这里写自定义目录标题
- Helm Kubernetes 包管理器
-
- 软件简介
- 什么是 DaemonSet
-
- 简介
- nodeAffinity
-
- 场景
- 案例
- 作用
- Toleration
-
- 场景
- 案例
- 作用
- ControllerRevision
-
- 概念
- 回滚原理
- 总结
Helm Kubernetes 包管理器
软件简介
Helm 帮助您管理 Kubernetes 应用程序 ——Helm Charts 帮助您定义、安装和升级最复杂的 Kubernetes 应用程序。
Helm 可以使用 Charts 启动 Kubernetes 集群, 提供可用的工作流:
- 一个 Redis 集群
- 一个 Postgres 数据库
- 一个 HAProxy 边界负载均衡
特性:
- 查找并使用流行的软件, 将其打包为 Helm Charts, 以便在 Kubernetes 中运行
- 以 Helm Charts 的形式共享您自己的应用程序
- 为您的 Kubernetes 应用程序创建可复制的构建
- 智能地管理您的 Kubernetes 清单文件
- 管理 Helm 包的发行版
- Chart 是 Kubernetes 的单元, Helm 的架构参考 Homebrew。
安装:
- Homebrew 用户使用 brew install kubernetes-helm.
- Chocolatey 用户使用 choco install kubernetes-helm.
- Scoop 用户使用 scoop install helm.
- GoFish 用户使用 gofish install helm.
- Snap 用户使用 sudo snap install helm --classic.
什么是 DaemonSet
简介
DaemonSet 的主要作用, 是在 Kubernetes 集群里, 运行一个
Daemon Pod
。 DaemonSet 只管理 Pod 对象, 然后通过 nodeAffinity 和 Toleration 这两个调度器的小功能, 保证了每个节点上有且只有一个 Pod。
所以, 这个 Pod 有如下三个特征:
- 这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上。
- 每个节点上只有一个这样的 Pod 实例。
- 当有新的节点加入 Kubernetes 集群后, 该 Pod 会自动地在新节点上被创建出来。
- 当旧节点被删除后, 它上面的 Pod 也相应地会被回收掉。
Daemon Pod
的意义确实是非常重要的。比如的作用:
- 网络插件的 Agent 组件, 都必须运行在每一个节点上, 用来处理这个节点上的容器网络。
- 存储插件的 Agent 组件, 也必须运行在每一个节点上, 用来在这个节点上挂载远程存储目录, 操作容器的 Volume 目录。
- 监控组件和日志组件, 也必须运行在每一个节点上, 负责这个节点上的监控信息和日志搜集。
nodeAffinity
我们的 DaemonSet Controller 会在创建 Pod 的时候, 自动在这个 Pod 的 API 对象里, 加上这样一个 nodeAffinity 定义。
场景
在这个 Pod 里, 声明了一个 spec.affinity 字段, 然后定义了一个 nodeAffinity。其中, spec.affinity 字段, 是 Pod 里跟调度相关的一个字段。
案例
比如我们创建如下的一个 YAML 文件:
apiVersion: v1
kind: Pod
metadata:
name: demo-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: metadata.name
operator: In
values:
- demo-node
关于上面参数的具体含义:
-
requiredDuringSchedulingIgnoredDuringExecution
这个代表 nodeAffinity 必须在每次调度的时候予以考虑, 同时, 这也意味着可以设置在某些情况下不考虑这个 nodeAffinity;
- 这个 Pod, 将来只允许运行在"metadata.name"是"demo-node"的节点上。
作用
在 nodeAffinity 的定义处, 可以支持更加丰富的语法, 比如 operator: In(即: 部分匹配)。
我们的 DaemonSet Controller 会在创建 Pod 的时候, 自动在这个 Pod 的 API 对象里, 加上这样一个 nodeAffinity 定义。
Toleration
场景
DaemonSet 还会给这个 Pod 自动加上另外一个与调度相关的字段, 叫作 tolerations。这个字段意味着这个 Pod, 会"容忍"(Toleration)某些 Node 的"污点"(Taint)。
案例
apiVersion: v1
kind: Pod
metadata:
name: with-toleration
spec:
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists
effect: NoSchedule
在正常情况下, 被标记了 unschedulable"污点"的 Node, 是不会有任何 Pod 被调度上去的(effect: NoSchedule)。可是, DaemonSet 自动地给被管理的 Pod 加上了这个特殊的 Toleration, 就使得这些 Pod 可以忽略这个限制, 继而保证每个节点上都会被调度一个 Pod。
当然, 如果这个节点有故障的话, 这个 Pod 可能会启动失败, 而 DaemonSet 则会始终尝试下去, 直到 Pod 启动成功。
作用
通过这样一个 Toleration, 调度器在调度这个 Pod 的时候, 就会忽略当前节点上的"污点", 从而成功地将网络插件的 Agent 组件调度到这台机器上启动起来。
这种机制, 正是我们在部署 Kubernetes 集群的时候, 能够先部署 Kubernetes 本身、再部署网络插件的根本原因: 因为当时我们所创建的 Weave 的 YAML, 实际上就是一个 DaemonSet。
ControllerRevision
DaemonSet 使用 ControllerRevision, 来保存和管理自己对应的"版本"。在 Kubernetes 项目里, ControllerRevision 其实是一个通用的版本管理对象。这样, Kubernetes 项目就巧妙地避免了每种控制器都要维护一套冗余的代码和逻辑的问题。
概念
Kubernetes v1.7 之后添加了一个 API 对象, 名叫 ControllerRevision, 专门用来记录某种 Controller 对象的版本。
ControllerRevision 对象, 实际上是在 Data 字段保存了该版本对应的完整的 DaemonSet 的 API 对象。并且, 在 Annotation 字段保存了创建这个对象所使用的 kubectl 命令。
回滚原理
现在 DaemonSet Controller 就可以使用这个历史 API 对象, 对现有的 DaemonSet 做一次 PATCH 操作(等价于执行一次 kubectl apply -f “旧的 DaemonSet 对象”), 从而把这个 DaemonSet"更新"到一个旧版本。
这也是为什么, 在执行完这次回滚完成后, 会发现, DaemonSet 的 Revision 并不会从 Revision=2 退回到 1, 而是会增加成 Revision=3。这是因为, 一个新的 ControllerRevision 被创建了出来。
总结
DaemonSet 其实就是依靠 nodeAffinity 和 Toleration 实现的。这是一种不需要增加设计结构, 而直接使用标签等方式完成的 Daemon 进程。这样的结构非常符合 Kubernetes 的控制器模式, 一切皆对象。