YurtStaticSet

背景介绍

静态 pod 是 K8s 中一种特殊的 pod,它由 Kubelet 直接进行管理。静态 pod 也常用于云边协同的场景中,比如一些 AI 相关的业务。 在 OpenYurt 中,核心组件 YurtHub 就是通过静态 pod 进行部署的。静态 pod 一般通过 /etc/kubernetes/manifests 目录下的配置文件进行创建,通过人工手动替换/修改配置文件完成升级,这个过程中 Kubelet 直接负责了静态 pod 的创建、删除任务。由于边缘侧设备数量多、位置分布分散等特点,若通过人工完成云边协同场景下静态 pod 的部署、升级等工作,势必会带来沉重的操作负担与失误风险。 因此,OpenYurt 新增 CRD YurtStaticSet 来增强对于静态 pod 的管理,通过的控制器提供了滚动更新、OTA 升级等能力。

配置

  1. apiVersion: apps.openyurt.io/v1alpha1
  2. kind: YurtStaticSet
  3. metadata:
  4. # ···
  5. spec:
  6. # static pod 配置文件名称
  7. staticPodManifest: xxx
  8. # 升级策略,支持 AdvancedRollingUpdate 与 OTA 升级方式
  9. upgradeStrategy:
  10. type: AdvancedRollingUpdate
  11. # AdvancedRollingUpdate 升级方式可以设置滚动更新最大不可用数量,默认值为 10%
  12. # maxUnavailable: 3
  13. # static pod 模板配置
  14. template:
  15. # ···

用户使用

1)部署 OpenYurt

static-pod 控制器集成于 Yurt-Manager 组件,使用前需要安装部署Yurt-Manager,相关操作可以参照部署OpenYurt组件

2) 创建 static pod

YurtStaticSet Operator 不负责静态 pod 初始的部署,部署静态节点需手动完成或者通过 yurtadm 工具实现。作为示例,本文通过 Kind 创建一个具有三个工作节点的集群,并且每个节点上手动部署静态 pod。

  1. cat > nginx.yaml << EOF
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx
  6. spec:
  7. containers:
  8. - name: web
  9. image: nginx:1.19.1
  10. EOF

3)部署 YurtStaticSet CR

YurtStaticSet 资源通过 namespace/name 与静态 pod 对应。 因此,我们创建一个 namespace:default, name:nginx 的CR实例接管该静态 pod。

  1. cat <<EOF | kubectl apply -f -
  2. apiVersion: apps.openyurt.io/v1alpha1
  3. kind: YurtStaticSet
  4. metadata:
  5. name: nginx
  6. spec:
  7. staticPodManifest: nginx
  8. upgradeStrategy:
  9. type: AdvancedRollingUpdate
  10. maxUnavailable: 3
  11. template:
  12. metadata:
  13. name: nginx
  14. spec:
  15. containers:
  16. - name: web
  17. image: nginx:1.19.1
  18. EOF

4) 静态 pod 升级

通过 YurtStaticSet 资源可以轻松实现对静态 pod 的管理,其中就包括升级静态 pod。 YurtStaticSet 支持两种升级方式,分别为 AdvancedRollingUpdate 模式与 OTA 模式。 简单来说,AdvancedRollingUpdate 模式实现了跃过 not-ready 节点的滚动更新升级能力; OTA 模式则支持用户自主控制升级流程。 两种模式的详细介绍参见 DaemonSet 升级模型

AdvancedRollingUpdate 升级

  • 升级之前查看集群中的静态 pod
  1. $ kubectl get pods | grep nginx
  2. default nginx-openyurt-e2e-test-worker 1/1 Running 0 3h4m 10.244.2.3 openyurt-e2e-test-worker
  3. default nginx-openyurt-e2e-test-worker2 1/1 Running 0 3h4m 10.244.1.2 openyurt-e2e-test-worker2
  4. default nginx-openyurt-e2e-test-worker3 1/1 Running 0 3h5m 10.244.3.3 openyurt-e2e-test-worker3
  5. $ kubectl describe pods nginx-openyurt-e2e-test-worker
  6. ···
  7. Containers:
  8. web:
  9. ···
  10. # 此时 nginx pod 的版本是1.19.1
  11. Image: nginx:1.19.1
  12. ···
  13. ···
  • 修改 YurtStaticSet spec,将容器镜像从 nginx:1.19.1 升级版本至 nginx:1.19.2
  1. apiVersion: apps.openyurt.io/v1alpha1
  2. kind: YurtStaticSet
  3. metadata:
  4. name: nginx
  5. spec:
  6. ···
  7. spec:
  8. containers:
  9. - name: web
  10. image: nginx:1.19.2
  • 查看资源状态, 可以看到三个静态 pods 均升级完成。 TOTAL 代表 YurtStaticSet nginx 在该集群中匹配多少对应的静态 pods, READY 代表就绪 pods 的数量,UPGRADED 表示多少 pods 已经升级至最新版本。
  1. $ kubectl get yurtstaticsets nginx
  2. NAME AGE TOTAL READY UPGRADED
  3. nginx 4m20s 3 3 3
  • 查看集群中相应的静态 pods
  1. $ kubectl describe pods nginx-openyurt-e2e-test-worker
  2. ···
  3. Containers:
  4. web:
  5. ···
  6. # 此时 nginx pod 的版本已经升级至1.19.2
  7. Image: nginx:1.19.2
  8. ···
  9. ···

OTA 升级

  1. OTA 升级接口

    YurtHub 提供了两个 OTA 升级相关的 REST APIs。

    • GET /pods 通过该接口可以获取节点上 pods 信息。
    • POST /openyurt.io/v1/namespaces/{ns}/pods/{podname}/upgrade 通过该接口用户可以指定更新某个静态 Pod。路径参数 nspodname 分别代表 Pod 的命名空间以及名称。
  2. OTA 升级流程

    • OTA 升级中通过 pod status 中 PodNeedUpgrade condition 字段表示升级状态,当值为 true 时表示存在可升级版本,反正不可升级。
    • 通过主动调用上述 upgrade API 接口即可实现静态 pod 升级任务