天行健,君子以自强不息;地势坤,君子以厚德载物;

Kubernetes--OpenKruise原地升级组件

OpenKruise是基于Kubernetes的一个标准扩展组件,可以配合原生Kubernetes使用,高效管理应用容器、Sidecar及镜像分发等功能。本文介绍如何使用OpenKruise部署云原生应用。

OpenKruise 是什么

欢迎来到 OpenKruise 的世界!

OpenKruise 是一个基于 Kubernetes 的扩展套件,主要聚焦于云原生应用的自动化,比如部署、发布、运维以及可用性防护

OpenKruise 提供的绝大部分能力都是基于 CRD 扩展来定义,它们不存在于任何外部依赖,可以运行在任意纯净的 Kubernetes 集群中。

核心能力

  • 增强版本的 Workloads

    OpenKruise 包含了一系列增强版本的 Workloads(工作负载),比如 CloneSet、Advanced StatefulSet、Advanced DaemonSet、BroadcastJob 等。

    它们不仅支持类似于 Kubernetes 原生 Workloads 的基础功能,还提供了如原地升级、可配置的扩缩容/发布策略、并发操作等。

    其中,原地升级是一种升级应用容器镜像甚至环境变量的全新方式。它只会用新的镜像重建 Pod 中的特定容器,整个 Pod 以及其中的其他容器都不会被影响。因此它带来了更快的发布速度,以及避免了对其他 Scheduler、CNI、CSI 等组件的负面影响。

  • 应用的旁路管理

    OpenKruise 提供了多种通过旁路管理应用 sidecar 容器、多区域部署的方式,“旁路” 意味着你可以不需要修改应用的 Workloads 来实现它们。

    比如,SidecarSet 能帮助你在所有匹配的 Pod 创建的时候都注入特定的 sidecar 容器,甚至可以原地升级已经注入的 sidecar 容器镜像、并且对 Pod 中其他容器不造成影响。

    而 WorkloadSpread 可以约束无状态 Workload 扩容出来 Pod 的区域分布,赋予单一 workload 的多区域和弹性部署的能力。

  • 高可用性防护

    OpenKruise 在为应用的高可用性防护方面也做出了很多努力。

    目前它可以保护你的 Kubernetes 资源不受级联删除机制的干扰,包括 CRD、Namespace、以及几乎全部的 Workloads 类型资源。

    相比于 Kubernetes 原生的 PDB 只提供针对 Pod Eviction 的防护,PodUnavailableBudget 能够防护 Pod Deletion、Eviction、Update 等许多种 voluntary disruption 场景。

  • 高级的应用运维能力

    OpenKruise 也提供了很多高级的运维能力来帮助你更好地管理应用。

    你可以通过 ImagePullJob 来在任意范围的节点上预先拉取某些镜像,或者指定某个 Pod 中的一个或多个容器被原地重启。

关系对比

OpenKruise vs. Kubernetes

简单来说,OpenKruise 对于 Kubernetes 是一个辅助扩展角色。

Kubernetes 自身已经提供了一些应用部署管理的功能,比如一些基础工作负载。 但对于大规模应用与集群的场景,这些基础功能是远远不够的。

OpenKruise 可以被很容易地安装到任意 Kubernetes 集群中,它弥补了 Kubernetes 在应用部署、升级、防护、运维 等领域的不足。

OpenKruise vs. Platform-as-a-Service (PaaS)

OpenKruise 不是一个 PaaS 平台,并且也不会提供任何 PaaS 层的能力。

它是一个 Kubernetes 的标准扩展套件,目前包括 kruise-manager  kruise-daemon 两个组件。 PaaS 平台可以通过使用 OpenKruise 提供的这些扩展功能,来使得应用部署、管理流程更加强大与高效。

前提条件

已安装Kubernetes集群,且集群版本不低于1.16。

组件架构

《Kubernetes--OpenKruise原地升级组件》

 

《Kubernetes--OpenKruise原地升级组件》

OpenKruise是Kubernetes的一个标准扩展,所以也可以原生的部署到K8s集群当中,主要包含以下两个组件:

组件 说明
Kruise-manager Kruise-manager是一个运行Controller和Webhook的中心组件,通过Deployment部署在kruise-system命名空间中。通过Controller以及Webhook实现原地升级及Sidecar管理等核心能力。
Kruise-daemon 通过DaemonSet部署到每个节点上,提供镜像预热及容器重启等功能。

使用说明

OpenKruise包含CloneSet、Advanced StatefulSet、Advanced DaemonSet等控制器。以下介绍常用控制器的功能。

表 1. 常用控制器介绍
控制器 功能 推荐指数
CloneSet

管理无状态应用,对标Kubernetes原生Deployment。关于CloneSet的详细介绍,请参见Cloneset

资源(YAML)的字段与Deployment不完全兼容,但功能上全覆盖,并提供比Deployment更丰富的策略。

推荐指数:✩✩✩✩✩
Advanced StatefulSet

管理有状态应用,对标Kubernetes原生StatefulSet。关于Advanced StatefulSet的详细介绍,请参见Advanced StatefulSet

资源(YAML)字段与原生StatefulSet完全兼容,只需要把apiVersion改为apps.kruise.io/v1alpha1,另外提供了optional字段来扩展发布策略(原地升级、并行发布等)。

推荐指数:✩✩✩✩
Advanced DaemonSet

管理Daemon应用,对标Kubernetes原生DaemonSet。关于Advanced DaemonSet的详细介绍,请参见Advanced DaemonSet

资源(YAML)字段与原生DaemonSet完全兼容,只需要把apiVersion改为apps.kruise.io/v1alpha1,另外提供了optional字段来扩展发布策略(热升级、灰度、按Node标签灰度等)。

推荐指数:✩✩✩✩
SidecarSet

独立管理Sidecar容器和注入。关于SidecarSet的详细介绍,请参见SidecarSet

在独立CR中定义Sidecar容器和Label Selector,OpenKruise会在所有符合Selector条件的Pod创建时注入定义好的Sidecar容器,并支持对已注入Sidecar容器做原地升级。

推荐指数:✩✩✩✩
UnitedDeployment

管理不同区域下的多个Sub Workload,关于UnitedDeployment的详细介绍,请参见UnitedDeployment

目前支持将CloneSet、StatefulSet、Advanced StatefulSet作为Sub Workload,您可以用一个UnitedDeployment来定义不同区域中的Sub Workload部署Replicas。

推荐指数:✩✩✩

以下介绍CloneSet、Advanced StatefulSet、Advanced DaemonSet与社区对标控制器的功能对比。

表 2.与社区控制器功能对比
功能 CloneSet VS Deployment Advanced StatefulSet VS StatefulSet Advanced DaemonSet VS DaemonSet
CloneSet Deployment Advanced StatefulSet StatefulSet Advanced DaemonSet DaemonSet
流式扩容 不支持(开源中,未来会支持) 不支持 不支持 不支持 支持 不支持
指定缩容 支持 不支持 支持 不支持 不支持 不支持
Pod重建升级 支持 支持 支持 支持 支持 支持
Pod原地升级 支持 不支持 支持 不支持 不支持(开源中,未来会支持) 不支持
分批灰度发布 支持 不支持 支持 支持 支持 不支持
最大可用数量 支持 支持 支持 不支持 支持 支持
最大弹性数量 支持 支持 不支持 不支持 支持 不支持
通过使用优先级策略和打散策略来自定义发布顺序 支持 不支持 支持 不支持 支持 不支持
通过lifecycle hook管理Pod生命周期 支持 不支持 不支持 不支持 不支持 不支持

安装OpenKruise

从 v1.0.0 (alpha/beta) 开始,OpenKruise 要求在 Kubernetes >= 1.16 以上版本的集群中安装和使用。

通过 helm 安装

建议采用 helm v3.5+ 来安装 Kruise,helm 是一个简单的命令行工具可以从这里获取。

# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/

# [Optional]
$ helm repo update

# Install the latest version.
$ helm install kruise openkruise/kruise --version 1.2.0

通过 helm 升级

# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/

# [Optional]
$ helm repo update

# Upgrade to the latest version.
$ helm upgrade kruise openkruise/kruise --version 1.2.0 [--force]

注意:

  1. 在升级之前,必须 先阅读 Change Log ,确保你已经了解新版本的不兼容变化。
  2. 如果你要重置之前旧版本上用的参数或者配置一些新参数,建议在 helm upgrade 命令里加上 --reset-values
  3. 如果你在将 Kruise 从 0.x 升级到 1.x 版本,你需要为 upgrade 命令添加 --force 参数,其他情况下这个参数是可选的。

可选的:手工下载 charts 包

如果你在生产环境无法连接到 https://openkruise.github.io/charts/,可以先在这里手工下载 chart 包,再用它安装或更新到集群中。

$ helm install/upgrade kruise /PATH/TO/CHART

卸载

注意:卸载会导致所有 Kruise 下的资源都会删除掉,包括 webhook configurations, services, namespace, CRDs, CR instances 以及所有 Kruise workload 下的 Pod。 请务必谨慎操作!

卸载使用 helm chart 安装的 Kruise:

$ helm uninstall kruise
release "kruise" uninstalled

使用CloneSet部署无状态应用

  1. 创建CloneSet。
    1. 创建cloneset.yaml
      apiVersion: apps.kruise.io/v1alpha1
      kind: CloneSet
      metadata:
        name: demo-clone
      spec:
        replicas: 5
        selector:
          matchLabels:
            app: guestbook
        template: #Pod template和Deployment的结构完全一致。
          metadata:
            labels:
              app: guestbook
          spec:
            containers:
            - name: guestbook
              image: registry.cn-hangzhou.aliyuncs.com/kruise-test/guestbook:v1
              env:
              - name: test
                value: foo
        updateStrategy:
          type: InPlaceIfPossible     #尽量使用原地升级,否则重建升级。
          maxUnavailable: 20%        #发布过程最多20%不可用。
          inPlaceUpdateStrategy:
            gracePeriodSeconds: 3    #每个Pod原地升级前Not Ready优雅等待时间。
      • type:设置升级策略,支持以下3种升级方式。
        • ReCreate:控制器会删除旧Pod和PVC,然后用新版本重新创建Pod和PVC。
        • InPlaceIfPossible:控制器会优先尝试原地升级Pod,如果不行再采用重建升级。
        • InPlaceOnly:控制器只允许采用原地升级。
      • maxUnavailable:发布过程中,限制最多不可用的Pod数量,可以设置为一个绝对值或者百分比。
      • gracePeriodSeconds:每个Pod原地升级前Not Ready优雅等待时间。
    2. 使cloneset.yaml在ACK集群中生效。
      kubectl create -f ./cloneset.yaml

      预期输出:

      cloneset.apps.kruise.io/demo-clone created
  2. 查看Pod运行状态。
    kubectl get pod

    预期输出:

    NAME               READY   STATUS    RESTARTS   AGE
    demo-clone-5b9kl   1/1     Running   0          3s
    demo-clone-6xjdg   1/1     Running   0          3s
    demo-clone-bvmdj   1/1     Running   0          3s
    demo-clone-dm22s   1/1     Running   0          3s
    demo-clone-rbpg9   1/1     Running   0          3s
  3. 查看CloneSet。
    kubectl get clone

    预期输出:

    NAME         DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
    demo-clone   5         5         5               5       5       46s
    • DESIRED:期望Pod数量(spec.replicas)。
    • UPDATED:最新版本的Pod数量(status.updatedReplicas)。
    • UPDATED_READY:最新版本的可用Pod数量(status.updatedReadyReplicas)。
    • READY:可用Pod总量(status.readyReplicas)。
    • TOTAL:实际Pod总量(status.replicas)。

使用Advanced StatefulSet部署有状态应用

  1. 创建Advanced StatefulSet。
    1. 创建statefulset.yaml
      apiVersion: apps.kruise.io/v1alpha1
      kind: StatefulSet
      metadata:
        name: demo-asts
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: guestbook-sts
        podManagementPolicy: Parallel
        template: #Pod template和官方StatefulSet的结构完全一致。
          metadata:
            labels:
              app: guestbook-sts
          spec:
            containers:
            - name: guestbook
              image: registry.cn-hangzhou.aliyuncs.com/kruise-test/guestbook:v1
              env:
              - name: test
                value: foo
              volumeMounts:
              - name: log-volume
                mountPath: /var/log
            readinessGates:
            - conditionType: InPlaceUpdateReady
            volumes:
            - name: log-volume
              emptyDir: {}
        updateStrategy:
          type: RollingUpdate
          rollingUpdate:
            podUpdatePolicy: InPlaceIfPossible #尽量使用原地升级,否则重建升级。
            maxUnavailable: 20% #发布过程最多20%不可用。
            inPlaceUpdateStrategy:
              gracePeriodSeconds: 3 #每个Pod原地升级前Not ready优雅等待时间。
      • type:设置Pod升级策略,支持以下3种方式升级。
        • ReCreate:控制器会删除旧Pod和PVC,然后用新版本重新创建Pod和PVC。
        • InPlaceIfPossible:控制器会优先尝试原地升级Pod,如果不行再采用重建升级。
        • InPlaceOnly:控制器只允许采用原地升级。
      • maxUnavailable:发布过程中,限制最多不可用的Pod数量,可以设置为一个绝对值或者百分比。
      • gracePeriodSeconds:每个Pod原地升级前Not ready优雅等待时间。
    2. 使statefulset.yaml在ACK集群中生效。
       kubectl create -f ./statefulset.yaml

      预期输出:

      statefulset.apps.kruise.io/demo-asts created
  2. 查看Pod运行状态。
    kubectl get pod

    预期输出:

    NAME          READY   STATUS    RESTARTS   AGE
    demo-asts-0   1/1     Running   0          3h29m
    demo-asts-1   1/1     Running   0          3h29m
    demo-asts-2   1/1     Running   0          3h29m
  3. 查看Advanced StatefulSet。
    kubectl get asts

    预期输出:

    NAME        DESIRED   CURRENT   UPDATED   READY   AGE
    demo-asts   3         3         3         3       3h30m
    • DESIRED:期望Pod数量(spec.replicas)。
    • UPDATED:最新版本的Pod数量(status.updatedReplicas)。
    • READY:可用Pod总量(status.readyReplicas)。
    • TOTAL:实际Pod总量(status.replicas)。

 

 

点赞

发表回复