Skip to main content
版本:v1.4

DaemonSet 升级模型

背景介绍

在边缘化场景下,原生 DaemonSet 升级模型无法满足用户现有需求。在云边网络断连的情况下,DaemonSet 升级流程可能被阻塞。除此之外,原生升级模型并未提供相应的升级操作接口,节点上用户无法自主控制应用升级。

为了解决上述问题,我们对原生 DaemonSet 升级模型进行扩展,新增自定义控制器daemonPodUpdater-controller,提供 AdvancedRollingUpdate 与 OTA 两种升级模型。

  • AdvancedRollingUpdate 模型:解决云边断连时,节点Not-Ready导致的 DaemonSet 升级阻塞问题,在升级过程中会忽略Not-Ready节点,从而保证升级流程的顺利完成,并且在节点状态从Not-Ready转变为Ready后,自动完成 DaemonSet 应用的升级。
  • OTA 模型:新增 Pod status condition PodNeedUpgrade来表明更新可用信息。YurtHub OTA 升级组件可以通过该 condition 判断 DaemonSet 应用是否存在新版本。

配置

# AdvancedRollingUpdate 或 OTA 升级模型配置文件示例
apiVersion: apps/v1
kind: DaemonSet
metadata:
  # ···
  annotations:
    # 该注解是使用 AdvancedRollingUpdate 或者 OTA 升级模型的前提条件之一,目前支持的配置值为"AdvancedRollingUpdate" 或者 "OTA"。
    apps.openyurt.io/update-strategy: AdvancedRollingUpdate
    # 该注解用于滚动更新时设置最大不可用 pod 数量,仅在 AdvancedRollingUpdate 模式下起作用。
    # 该注解支持的配置值与原生 DaemonSet 配置中 maxUnavailable 相同,默认值为10%。
    apps.openyurt.io/max-unavailable: 30%
  # ···
spec:
  # ···
  # 使用 AdvancedRollingUpdate 或者 OTA 升级模型的另一个前提条件是将 updateStrategy 设置为 OnDelete。
  updateStrategy:
    type: OnDelete
  # ···

总的来说,如果你希望使用 AdvancedRollingUpdate 或者 OTA 升级模型,那么你需要将注解 apps.openyurt.io/update-strategy 设置为 "AdvancedRollingUpdate" 或者 "OTA", 并且将 .spec.updateStrategy.type 设置为 "OnDelete"。

用户使用:

1)安装Yurt-Manager组件

daemonpodupdater控制器集成于Yurt-Manager组件,使用 AdvancedRollingUpdate 或 OTA 升级模型前需要安装部署Yurt-Manager,相关操作可以参照部署OpenYurt组件

2)使用 AdvancedRollingUpdate 升级模型

  • 创建 daemonset 实例
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  annotations:
    apps.openyurt.io/update-strategy: AdvancedRollingUpdate
spec:
  selector:
    matchLabels:
      app: nginx
  updateStrategy:
    type: OnDelete
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.4

EOF
  • 查看 nginx-daemonset pods
$ kubectl get pods | grep nginx-daemonset

nginx-daemonset-bv5jg   1/1     Running   0          21m   10.244.2.2   openyurt-e2e-test-worker3   <none>           <none>
nginx-daemonset-fhsr6   1/1     Running   0          21m   10.244.1.2   openyurt-e2e-test-worker    <none>           <none>
nginx-daemonset-lmmtd   1/1     Running   0          21m   10.244.3.2   openyurt-e2e-test-worker2   <none>           <none>
  • 模拟云边网络断连, 假定断开边缘节点openyurt-e2e-test-worker2openyurt-e2e-test-worker3与云端节点的网络连接,该示例采用Kind创建集群,可以通过将容器从虚拟网桥中移除的方式模式网络断连
$ docker network disconnect kind openyurt-e2e-test-worker2
$ docker network disconnect kind openyurt-e2e-test-worker3

$ kubectl get nodes -o wide
AME                              STATUS     ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION     CONTAINER-RUNTIME
openyurt-e2e-test-control-plane   Ready      control-plane,master   36m   v1.22.7   172.18.0.4    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker          Ready      <none>                 35m   v1.22.7   172.18.0.2    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker2         NotReady   <none>                 35m   v1.22.7   172.18.0.3    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker3         NotReady   <none>                 35m   v1.22.7   172.18.0.5    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
  • 更新 daemonset,将容器镜像从 nginx:1.19.4 修改为 nginx:1.19.5
***
containers:
      - name: nginx
        image: nginx:1.19.5
***
  • 查看 pods:openyurt-e2e-test-worker节点上旧 pod default/nginx-daemonset-fhsr6已被删除,新 pod default/nginx-daemonset-slp5t被创建; 两个网络断连节点上的 pods 暂不进行更新升级
nginx-daemonset-bv5jg   1/1     Running   0          33m     10.244.2.2   openyurt-e2e-test-worker3   <none>           <none>
nginx-daemonset-lmmtd   1/1     Running   0          33m     10.244.3.2   openyurt-e2e-test-worker2   <none>           <none>
nginx-daemonset-slp5t   1/1     Running   0          5m54s   10.244.1.3   openyurt-e2e-test-worker    <none>           <none>
  • 恢复节点网络连接
$ docker network connect kind openyurt-e2e-test-worker2
$ docker network connect kind openyurt-e2e-test-worker3

$ kubectl get nodes -o wide
NAME                              STATUS   ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION     CONTAINER-RUNTIME
openyurt-e2e-test-control-plane   Ready    control-plane,master   49m   v1.22.7   172.18.0.4    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker          Ready    <none>                 48m   v1.22.7   172.18.0.2    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker2         Ready    <none>                 48m   v1.22.7   172.18.0.3    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
openyurt-e2e-test-worker3         Ready    <none>                 48m   v1.22.7   172.18.0.5    <none>        Ubuntu 21.10   5.10.76-linuxkit   containerd://1.5.10
  • 查看 pods, 所有节点上 daemonset pods 均已完成更新升级
nginx-daemonset-kbkf6   1/1     Running   0          88s   10.244.3.3   openyurt-e2e-test-worker2   <none>           <none>
nginx-daemonset-scgtv   1/1     Running   0          51s   10.244.2.3   openyurt-e2e-test-worker3   <none>           <none>
nginx-daemonset-slp5t   1/1     Running   0          11m   10.244.1.3   openyurt-e2e-test-worker    <none>           <none>
  • 查看 pods 镜像版本,均已升级至nginx:1.19.5
***
Containers:
  nginx:
    Container ID:   containerd://f7d4b3f1257a0d1d8da862671c11cb094f9fba1ba0041b7a5f783d9c9e4d8449
    Image:          nginx:1.19.5
    Image ID:       docker.io/library/nginx@sha256:31de7d2fd0e751685e57339d2b4a4aa175aea922e592d36a7078d72db0a45639
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 14 Oct 2022 14:21:25 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-wrhj8 (ro)
***

3)OTA 升级模型

OTA 升级接口

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

  1. GET /pods

    通过该接口可以获取节点上 pods 信息。

  2. POST /openyurt.io/v1/namespaces/{ns}/pods/{podname}/upgrade

    通过该接口用户可以指定更新某个 DaemonSet Pod。路径参数 nspodname 分别代表 Pod 的 命名空间以及名称。

OTA 升级示例

  • 创建 daemonset 实例
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  annotations:
    apps.openyurt.io/update-strategy: OTA
spec:
  selector:
    matchLabels:
      app: nginx
  updateStrategy:
    type: OnDelete
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.4

EOF

# get nginx-daemonset pods
$ kubectl get pods -o wide | grep nginx-daemonset
nginx-daemonset-bwzss   1/1     Running   0          92s   10.244.3.4   openyurt-e2e-test-worker2   <none>           <none>
nginx-daemonset-ppf9p   1/1     Running   0          92s   10.244.1.4   openyurt-e2e-test-worker    <none>           <none>
nginx-daemonset-rgp9h   1/1     Running   0          92s   10.244.2.4   openyurt-e2e-test-worker3   <none>           <none>
  • 查看 pod status condition PodNeedUpgrade, 以openyurt-e2e-test-worker2节点上 pod nginx-daemonset-bwzss 为例
$ kubectl describe pods nginx-daemonset-bwzss

***
Conditions:
  Type              Status
  PodNeedUpgrade    False
***
  • 更新 daemonset,将容器镜像从 nginx:1.19.4修改为 nginx:1.19.5
***
containers:
      - name: nginx
        image: nginx:1.19.5
***
  • 再次查看 pod status condition PodNeedUpgrade
$ kubectl describe pods nginx-daemonset-bwzss

***
Conditions:
  Type              Status
  PodNeedUpgrade    True
***
  • 进入节点openyurt-e2e-test-worker2,执行 OTA 升级
# Kind 集群中需要先进入边缘节点
$ docker exec -it openyurt-e2e-test-worker2 /bin/bash

# 调用 Upgrade API, 该升级接口仅在边缘节点上提供
$ curl -X POST 127.0.0.1:10267/openyurt.io/v1/namespaces/default/pods/nginx-daemonset-bwzss/upgrade
Start updating pod default/nginx-daemonset-bwzss
  • 检查 OTA 升级结果, 节点openyurt-e2e-test-worker2上pod nginx-daemonset-bwzss已经被删除,新创建 pod 为 nginx-daemonset-vrvhn
# 检查 OTA 升级结果
$ kubectl get pods -o wide | grep nginx-daemonset
nginx-daemonset-ppf9p   1/1     Running   0          15m   10.244.1.4   openyurt-e2e-test-worker    <none>           <none>
nginx-daemonset-rgp9h   1/1     Running   0          15m   10.244.2.4   openyurt-e2e-test-worker3   <none>           <none>
nginx-daemonset-vrvhn   1/1     Running   0          63s   10.244.3.5   openyurt-e2e-test-worker2   <none>           <none>

# 查看容器镜像版本
$ kubectl describe pods nginx-daemonset-vrvhn
***
Containers:
  nginx:
    Container ID:   containerd://18df6aa88076639353ea0b3d87f340cd4c86ab27a7f154bce06345e9764c997a
    Image:          nginx:1.19.5
    Image ID:       docker.io/library/nginx@sha256:31de7d2fd0e751685e57339d2b4a4aa175aea922e592d36a7078d72db0a45639
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 14 Oct 2022 16:25:20 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-p6kjh (ro)
***