ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入解析 OpenKruise:Kubernetes 增强工作负载与原地升级实战指南

深入解析 OpenKruise:Kubernetes 增强工作负载与原地升级实战指南 深入解析 OpenKruiseKubernetes 增强工作负载与原地升级实战指南【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbookOpenKruise 是阿里云开源的大规模应用自动化管理引擎在 Kubernetes 原生 Deployment、StatefulSet、DaemonSet 等控制器之外提供了一套扩展 workload 控制器与增强运维能力。本文以 Kubernetes Handbook 仓库中 practice/openkruise.md 为主线结合仓库内 manifests/kruise 下的真实示例系统讲解 CloneSet、AdvancedStatefulSet、SidecarSet、UnitedDeployment、BroadcastJob 等核心控制器的配置方式与适用场景并深入剖析其最具价值的原地升级In-place Update机制帮助你掌握一套更高效、更灵活的应用部署发布方案。OpenKruise 是什么OpenKruise 是阿里云开源的大规模应用自动化管理引擎于 2021 年 12 月发布 1.0 版本。它并不替代 Kubernetes 本身而是在 Kubernetes 原生控制器Deployment、StatefulSet 等基础上提供增强能力核心能力可归纳为五大类应用工作负载面向无状态、有状态、daemon 等多种类型应用提供高级部署发布策略例如优雅原地升级、灰度流式发布等。Sidecar 容器管理支持独立定义 sidecar 容器完成动态注入、独立原地升级、热升级等功能。增强运维能力包括容器原地重启、镜像预拉取、容器启动顺序保障等。应用分区管理管理应用在多个分区可用区、不同机型等上的部署比例、顺序、优先级等。应用安全防护帮助应用在 Kubernetes 之上获得更高的安全性保障与可用性防护。这些控制器帮助开发者应对更加多样化的部署环境和需求为集群维护者和应用开发者带来更加灵活的部署发布组合策略。扩展控制器全景与命名规范Kruise 是 OpenKruise 中的核心项目之一它提供一套在 Kubernetes 核心控制器之外的扩展 workload 管理和实现。目前Kruise 提供以下多个 Kubernetes 扩展控制器通用工作负载CloneSet提供更加高效、确定可控的应用管理和部署能力支持优雅原地升级、指定删除、发布顺序可配置、并行/灰度发布等丰富策略可以满足更多样化的应用场景。AdvancedStatefulSet基于原生 StatefulSet 的增强版本默认行为与原生完全一致在此之外提供原地升级、并行发布最大不可用、发布暂停等功能。AdvancedDaemonSet基于原生 DaemonSet 增强发布能力比如灰度分批、按 Node label 选择、暂停、热升级等。任务工作负载BroadcastJob配置一个 Job在集群中所有满足条件的 Node 上都运行一个 Pod 任务。AdvancedCronJob基于原生 CronJob 的扩展版本根据用户设置的 schedule 规则周期性创建 Job 执行任务且 template 支持多种不同的 Job 资源。Sidecar 容器管理SidecarSet对 sidecar 容器做统一管理在满足 selector 条件的 Pod 中注入指定的 sidecar 容器。多区域管理WorkloadSpread将 workloadPod按一定规则分布到不同类型的节点上赋予单一 workload 多区域部署和弹性部署的能力。UnitedDeployment通过多个 workload 管理多个区域下的 Pod。关于命名规范Kruise 中的扩展控制器采用与 Kubernetes 社区一致的命名规范Set后缀这类 controller 直接操作和管理 Pod比如CloneSet、ReplicaSet、SidecarSet等。它们提供 Pod 维度的多种部署、发布策略。Deployment后缀这类 controller 不直接操作 Pod而是通过操作一个或多个Set类型的 workload 间接管理 Pod比如Deployment管理ReplicaSet来提供额外的滚动策略以及UnitedDeployment支持管理多个StatefulSet/AdvancedStatefulSet将应用部署到不同可用区。Job后缀这类 controller 主要管理短期执行的任务比如BroadcastJob支持将任务类型的 Pod 分发到集群中所有 Node 上。理解这个命名规范有助于快速判断一个控制器的定位是直接管 PodSet还是管 workloadDeployment还是管一次性任务Job。CloneSet无状态应用的增强版 DeploymentCloneSet 是对 Deployment 的增强版主要用于管理对实例顺序没有要求的无状态应用。下面是一个完整的 CloneSet 配置示例apiVersion: apps.kruise.io/v1alpha1 kind: CloneSet metadata: labels: app: sample name: sample-data spec: replicas: 3 scaleStrategy: podsToDelete: - sample-9m4hp # 选择性的删除单个 pod updateStrategy: priorityStrategy: # 优先级策略 weightPriority: # - weight: 50 matchSelector: matchLabels: test-key: foo - weight: 30 matchSelector: matchLabels: test-key: bar orderPriority: - orderedKey: some-label-key scatterStrategy: - key: foo value: bar updateStrategy: # 升级策略 type: InPlaceIfPossible # 升级策略里增加了原地升级 maxUnavailable: 2 # 升级时最多有多少个实例不可用 selector: matchLabels: app: sample template: metadata: labels: app: sample spec: containers: - name: nginx image: nginx volumeMounts: - name:>apiVersion: apps.kruise.io/v1alpha1 kind: CloneSet metadata: name: guestbook-clone labels: app.kubernetes.io/name: guestbook-clone spec: replicas: 3 selector: matchLabels: app.kubernetes.io/name: guestbook-clone template: metadata: labels: app.kubernetes.io/name: guestbook-clone spec: containers: - name: guestbook image: openkruise/guestbook:v2 imagePullPolicy: Always ports: - name: http-server containerPort: 3000 updateStrategy: type: InPlaceIfPossible maxUnavailable: 3该示例展示了实际生产中最常见的最小配置组合replicasselectortemplateupdateStrategy。其中updateStrategy.type: InPlaceIfPossible配合maxUnavailable: 3意味着当 guestbook 镜像从 v1 升级到 v2 时3 个副本会尽量原地更新而不是销毁重建。仓库中另一个示例 manifests/kruise/cloneset-redis.yaml 演示了用 CloneSet 管理 Redis 主从的场景redis-master用 1 个副本的 CloneSet 管理redis-slave用 2 个副本的 CloneSet 管理各自配合一个 Service 暴露端口。这说明 CloneSet 同样可以承接传统上用 Deployment 承载的有主从关系的应用同时借助原地升级特性减少发布时对 Redis 连接的影响。AdvancedStatefulSet有状态应用的增强版AdvancedStatefulSet 是对 Kubernetes 原生 StatefulSet 的增强。下面是一个 AdvancedStatefulSet 的配置示例apiVersion: apps.kruise.io/v1alpha1 kind: StatefulSet metadata: name: sample spec: replicas: 3 serviceName: my-service selector: matchLabels: app: sample template: metadata: labels: app: sample spec: readinessGates: # 一个新的条件确保 pod 在原地更新时保持在 NotReady 状态。 - conditionType: InPlaceUpdateReady containers: - name: nginx image: nginx:alpine podManagementPolicy: Parallel # 允许并行更新与 maxUnavailable 一起使用。 updateStrategy: type: RollingUpdate rollingUpdate: # 如果可以的话做原地更新目前原地更新只支持镜像更新。 podUpdatePolicy: InPlaceIfPossible # 允许并行更新最大不可用实例数等于 2。 maxUnavailable: 2 # 可以按照特定的顺序更新 pod而不是按照 pod 名称的顺序。 unorderedUpdate: priorityStrategy: weightPriority: - weight: 50 matchSelector: matchLabels: test-key: foo - weight: 30 matchSelector: matchLabels: test-key: bar示例中值得注意的关键点readinessGates中新增了InPlaceUpdateReady条件确保 Pod 在原地更新期间保持在 NotReady 状态避免更新过程中流量被错误地打到正在变更的实例上。podManagementPolicy: Parallel允许并行更新配合maxUnavailable使用打破原生 StatefulSet 串行更新的限制。rollingUpdate.podUpdatePolicy: InPlaceIfPossible表示如果可以的话做原地更新目前原地更新只支持镜像更新。unorderedUpdate.priorityStrategy支持按照权重指定的顺序更新 Pod而不是按照 Pod 名称的顺序。AdvancedStatefulSet 是对 StatefulSet 的增强AdvancedStatefulSet 基本保留了 Kubernetes 原生 StatefulSet 的使用用法。在声明 AdvancedStatefulSet 时保留了 CRD 的名字StatefulSet不过将原来的apiVersion的值从apps/v1修改为了apps.kruise.io/v1alpha1并做出如下增强支持原地升级同 CloneSet 一样需要在updateStrategy中配置默认的升级策略为ReCreate支持更高级的更新策略例如根据权重按照特定的顺序更新 Pod而不是按照 Pod 的名称顺序。原生 StatefulSet 的核心价值在于为 Pod 提供稳定的唯一标识、稳定的持久化存储基于 PVC 实现以及有序的部署、扩展、删除和滚动升级。AdvancedStatefulSet 在完整保留这些能力的基础上解决了原生 StatefulSet 升级效率低必须逐 Pod 串行重建、重建后 Pod IP 变化的痛点让有状态应用也能享受到原地升级的收益。SidecarSet统一管理 Sidecar 容器SidecarSet 利用 Kubernetes 的 mutating webhook 准入控制器在 Pod 创建时向其中自动注入 sidecar 容器这与 Istio 的做法一致。下面是一个 SidecarSet 的配置示例apiVersion: apps.kruise.io/v1alpha1 kind: SidecarSet metadata: name: test-sidecarset spec: selector: matchLabels: app: nginx strategy: rollingUpdate: maxUnavailable: 2 containers: - name: sidecar1 image: centos:6.7 command: [sleep, 999d] # do nothing at all volumeMounts: - name: log-volume mountPath: /var/log volumes: # this field will be merged into pod.spec.volumes - name: log-volume emptyDir: {}配置要点说明selector.matchLabels决定哪些 Pod 会被注入 sidecar只有 label 匹配的 Pod 才会在创建时被注入。strategy.rollingUpdate.maxUnavailablesidecar 升级滚动时最多不可用的 Pod 数量。containers要注入的 sidecar 容器定义示例中sleep 999d是一个占位容器。volumes会被合并进pod.spec.volumessidecar 与业务容器可以共享该卷。SidecarSet 的主要功能Sidecar 容器的生命周期独立于整个 Pod实现如下功能SidecarSet 可以向指定的 Pod 中注入 Sidecar 容器Sidecar 容器可以原地升级仅当更新镜像时。对于使用 Istio、日志采集、监控探针等 sidecar 模式的场景传统做法是每次升级 sidecar 都要重建整个 Pod成本极高。SidecarSet 把 sidecar 从业务 Pod 中解耦出来单独管理使 sidecar 升级不再牵连业务容器是 Kubernetes 上实现基础设施能力独立演进的重要方式。UnitedDeployment多区域分组发布UnitedDeployment 主要用于分组发布通过定义 subset 将工作负载发布到不同的可用区中。Kubernetes 集群中的不同域由多组由标签识别的节点表示。UnitedDeployment 控制器为每组提供一种类型的工作负载并提供相应匹配的 NodeSelector这样各个工作负载创建的 Pod 就会被调度到目标域。UnitedDeployment 管理的每个工作负载称为子集subset。每个域至少要提供运行 n 个副本数量的 Pod 的能力。目前仅支持 StatefulSet 工作负载。下面的示例 YAML 展示了一个 UnitedDeployment它在三个域中管理三个 StatefulSet 实例管理的 Pod 总数为 6apiVersion: apps.kruise.io/v1alpha1 kind: UnitedDeployment metadata: name: sample spec: replicas: 6 revisionHistoryLimit: 10 selector: matchLabels: app: sample template: statefulSetTemplate: metadata: labels: app: sample spec: template: metadata: labels: app: sample spec: containers: - image: nginx:alpine name: nginx topology: subsets: - name: subset-a nodeSelector: nodeSelectorTerms: - matchExpressions: - key: node operator: In values: - zone-a replicas: 1 - name: subset-b nodeSelector: nodeSelectorTerms: - matchExpressions: - key: node operator: In values: - zone-b replicas: 50% - name: subset-c nodeSelector: nodeSelectorTerms: - matchExpressions: - key: node operator: In values: - zone-c updateStrategy: manualUpdate: partitions: subset-a: 0 subset-b: 0 subset-c: 0 type: Manual ...示例中的关键概念template.statefulSetTemplate定义子集的 workload 模板目前支持 StatefulSet 类型。topology.subsets定义多个子集每个子集通过nodeSelector匹配特定标签的节点如nodezone-a、zone-b、zone-c并可通过replicas指定该区域的副本数量支持绝对值如1也支持百分比如50%。updateStrategy.type: Manual配合manualUpdate.partitions支持对每个 subset 单独控制发布进度partition 为保留的旧版本副本数实现跨可用区的手动分批发布。UnitedDeployment 的主要功能UnitedDeployment 主要功能即分组发布控制不同可用区中的 StatefulSet 工作负载发布。它让一个应用、多区域部署从需要维护多套 workload 的繁琐工作中解放出来只需一份声明即可按区域比例、优先级进行调度与发布。BroadcastJob全节点一次性任务BroadcastJob 控制器在集群中的每个节点上分发一个 Pod。像 DaemonSet 一样BroadcastJob 确保 Pod 被创建并在集群中的所有选定节点上运行一次。BroadcastJob 在每个节点上的 Pod 运行完成后不会消耗任何资源。当升级一个软件例如 Kubelet或者在每个节点上进行验证检查时BroadcastJob 特别有用通常在很长一段时间内只需要一次或者运行一个临时性的完整集群检查脚本。BroadcastJob Pod 也可以选择在所需节点上运行完成后保持存活这样在每一个新节点被添加到集群后就会自动启动一个 Pod。下面是一个 BroadcastJob 的示例apiVersion: apps.kruise.io/v1alpha1 kind: BroadcastJob metadata: name: broadcastjob-ttl spec: template: spec: containers: - name: pi image: perl command: [perl, -Mbignumbpi, -wle, print bpi(2000)] restartPolicy: Never completionPolicy: type: Always ttlSecondsAfterFinished: 30示例中的completionPolicy.type: Always表示所有节点上的 Pod 都完成后任务即结束ttlSecondsAfterFinished: 30表示任务结束后 30 秒自动清理。BroadcastJob 支持多种CompletionPolicy和FailurePolicy设置可用于集群级软件升级、节点巡检、批量数据预热等一次性全集群任务。安装与卸载安装使用 Helm v3 安装并保证 Kubernetes 版本不低于 1.12helm install kruise https://github.com/openkruise/kruise/releases/download/v0.5.0/kruise-chart.tgz默认启用所有支持的扩展控制器若想只启动指定的控制器可以在执行上面的命令时设置环境变量。例如只想启用CloneSet和StatefulSet可以加上这样的参数--set manager.custom_resource_enableCloneSet,StatefulSet安装完成后即可使用apps.kruise.io/v1alpha1下的各类 CRD例如仓库 manifests/kruise 中的 guestbook 与 redis 示例可直接通过kubectl apply -f部署验证。卸载要想卸载 Kruise只需要执行下面的命令helm delete kruise --namespace default注意卸载会导致所有 Kruise 下的资源都被删除包括 webhook configurations、services、namespace、CRD、CR 实例和所有 Kruise workload 下的 Pod。请务必谨慎操作核心亮点原地升级In-place UpdateKruise 对 Kubernetes 扩展的控制器中有一个重要功能就是支持原地升级详见仓库文档 practice/in-place-update.md。简单来说原地升级可以在更新 Pod 中某一个或多个容器的镜像版本时不影响 Pod 中其余容器的运行同时保持 Pod 的网络和存储状态不变。Kubernetes 原生工作负载Deployment、StatefulSet 乃至 Pod 本身在升级镜像时都会销毁旧 Pod 并重新调度、创建新 Pod。对于 StatefulSet虽然能保持 Pod 名称不变但实际UID与Pod IP都会改变若使用 Istio更新 sidecar 时所有植入 sidecar 的 Pod 都要销毁、重建带来极大的开销并影响业务稳定性。原地升级模式的优势节省调度的耗时Pod 的位置、资源都不发生变化节省分配网络的耗时Pod 仍使用原有的 IP节省分配、挂载远程盘的耗时Pod 仍使用原有的 PV且都已在 Node 上挂载好节省大部分拉取镜像的耗时Node 上已存在旧镜像拉取新版本时只需下载很少的几层 layer。OpenKruise 的AdvancedStatefulSet、CloneSet、SidecarSet均支持原地升级。开启方式是将updateStrategy的type配置为以下两种之一InPlaceIfPossible如果可能的话控制器将尝试就地更新 Pod 而不是重新创建。目前只有spec.template.spec.container[x].image字段可以原地更新InPlaceOnly控制器将强制原地更新 Pod 而不是重新创建。使用InPlaceOnly策略用户不能修改spec.template中除spec.template.spec.containers[x].image以外的任何字段。注意updateStrategy默认值为ReCreate必须显式配置为以上两种类型之一才能开启原地升级。前文 CloneSet、AdvancedStatefulSet 示例中反复出现的type: InPlaceIfPossible正是这一特性的实际落地。总结Kruise 在 Kubernetes 原生控制器基础上进行了扩展主要增加了原地升级、更灵活的发布策略以及一些特殊场景的适配如 SidecarSet、UnitedDeployment。总体而言CloneSet可以完全替代Deployment额外获得原地升级、按 Pod 分配 PVC、指定删除、优先级/打散发布等能力AdvancedStatefulSet可以完全替代StatefulSet默认行为一致使用方式类似同时获得原地升级与并行、无序发布能力SidecarSet解决 sidecar 容器注入与独立升级问题UnitedDeployment解决多可用区/多分区的分组发布问题BroadcastJob解决全节点一次性任务问题。由于 API 使用方式与原生控制器高度一致用户可以无负担地轻松接入将 Kubernetes 应用的发布体验从重建式更新提升到原地热更新的新维度。仓库内 manifests/kruise 提供了 guestbook 与 redis 两套可直接运行的参考清单建议结合 practice/openkruise.md 与 practice/in-place-update.md 对照阅读、动手验证。【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表