Kubernetes: 非优雅节点关机的操作验证

首先

在本文中,我们将对在Kubernetes v1.28中被正式引入的Non Graceful Node Shutdown进行操作验证。
当关闭Kubernetes节点时,如果关闭过程没有正常完成,可能会导致卷等无法被卸载。
在这种情况下,如果在iSCSI等块存储中,已经被挂载的节点处于可读写状态,其他节点将无法通过读写进行卷的挂载。
将一个卷连接到多个节点被称为Multi Attach,上述错误情况被称为Multi Attach错误。
作为恢复这种情况的手段,Non Graceful Node Shutdown应运而生。

作为这个功能的注意事项,它并不会自动恢复。一旦用户判断节点没有正确关闭,可以添加taint (node.kubernetes.io/out-of-service),从而触发该功能的执行。

另外,本功能支持的版本如下。

    • Kubernetes v1.24: アルファ (デフォルト無効)

 

    • Kubernetes v1.26: ベータ (デフォルト有効)

 

    Kubernetes v1.28: GA

验证环境

    • Kubernetes v1.25.9, 1.26.4

 

    • ノードOS: Ubuntu 20.04

 

    ストレージ: NetApp ONTAP AFF9.9 (iSCSIを利用)

验证

在这个验证中,为了确认”Non Graceful Node Shutdown”的行为,我们将使用禁用了该功能的Kubernetes来验证在没有该功能的情况下的行为(验证1)。
然后,我们将使用启用了该功能的Kubernetes来验证该功能的行为(验证2)。

[验证1] 如果禁用了非优雅的节点关机(适用于Kubernetes v1.25之前的版本)

首先,让我们讨论非优雅节点关闭被禁用时的行为。
我们将使用默认情况下禁用非优雅节点关闭的Kubernetes v1.25版本进行验证,其中包括Non Graceful Node Shutdown功能门(NodeOutOfServiceVolumeDetach)。
首先,我们将使用StatefulSet(sts.yaml)创建Pod、PVC和PV。

    sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pv-test
spec:
  serviceName: pv-test
  replicas: 1
  selector:
    matchLabels:
      app: pv-test
  template:
    metadata:
      labels:
        app: pv-test
    spec:
      containers:
      - name: pv-test
        image: ubuntu:20.04
        volumeMounts:
        - name: block
          mountPath: /mnt/block
        command: 
        - sleep
        - infinity
  volumeClaimTemplates:
  - metadata:
      name: block
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: ontap-block
      resources:
        requests:
          storage: 10Gi

部署(sts.yaml)并验证Pod、PVC、PV。

$ kubectl apply -f sts.yaml 
statefulset.apps/pv-test created

$ kubectl get pod,pvc,pv -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP             NODE                                       NOMINATED NODE   READINESS GATES
pod/pv-test-0   1/1     Running   0          55s   10.26.107.43   demo-ysakashita-w-default-a7102877-mmh9d   <none>           <none>

NAME                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
persistentvolumeclaim/block-pv-test-0   Bound    pvc-adc68176-5517-4274-85fa-33d5dfcd81c2   10Gi       RWO            ontap-block    55s   Filesystem

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/pvc-adc68176-5517-4274-85fa-33d5dfcd81c2   10Gi       RWO            Delete           Bound    default/block-pv-test-0   ontap-block             52s   Filesystem

接下来,您可以通过ssh登录到部署了Pod的节点(demo-ysakashita-w-default-a7102877-mmh9d),并引发操作系统的严重错误(OS Panic)。

ubuntu@demo-ysakashita-w-default-a7102877-mmh9d:~$ sudo bash
root@demo-ysakashita-w-default-a7102877-mmh9d:/home/ubuntu# vi /etc/sysctl.conf
root@demo-ysakashita-w-default-a7102877-mmh9d:/home/ubuntu# sysctl -p
kernel.panic = 0
root@demo-ysakashita-w-default-a7102877-mmh9d:/home/ubuntu# echo c > /proc/sysrq-trigger

在发生 OS Panic 后,会检查节点的状态。

$ kubectl get node
NAME                                        STATUS     ROLES    AGE    VERSION
...
demo-ysakashita-w-default-a7102877-mmh9d    NotReady   <none>   176m   v1.25.9

該当のノードがNotReadyとなりました。 しばらく待ち、Podのステータスも確認します.

$ kubectl get pod -o wide
NAME        READY   STATUS        RESTARTS   AGE   IP             NODE                                       NOMINATED NODE   READINESS GATES
pv-test-0   1/1     Terminating   0          10m   10.26.107.43   demo-ysakashita-w-default-a7102877-mmh9d   <none>           <none>

10分以上経ってもTerminatingのままとなります。
この状態で、ノードにtaint (node.kubernetes.io/out-of-service=nodeshutdown:NoExecute)を付与します。

在Kubernetes v1.25版本中,我们确认由于非优雅节点关闭被禁用,这个操作是没有意义的。

$ kubectl taint node demo-ysakashita-w-default-a7102877-mmh9d "node.kubernetes.io/out-of-service=nodeshutdown:NoExecute"
node/demo-ysakashita-w-default-a7102877-mmh9d tainted

在给予了taint之后,我将Pod放置了20分钟,但Pod的状态仍然是Terminating,并没有恢复。这是预期的行为。

$ kubectl get pod -o wide
NAME        READY   STATUS        RESTARTS   AGE   IP             NODE                                       NOMINATED NODE   READINESS GATES
pv-test-0   1/1     Terminating   0          30m   10.26.107.43   demo-ysakashita-w-default-a7102877-mmh9d   <none>           <none>

[验证2] 在启用非优雅节点关闭的情况下 (针对Kubernetes v1.26以前)

Kubernetes v1.26にてNon Graceful Node ShutdownのFeature Gates(NodeOutOfServiceVolumeDetach)がベータとなり、デフォルト有効となりました。
そこで、Kubernetes v1.26を使い Non Graceful Node Shutdown の検証を行います。
上記の検証で用いたsts.yamlを使いPod,PVC,PVを作成します。

$ kubectl apply -f sts.yaml 
statefulset.apps/pv-test created

$ kubectl get pod,pvc,pv -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP            NODE                                      NOMINATED NODE   READINESS GATES
pod/pv-test-0   1/1     Running   0          47s   10.26.26.23   demo-ysaka-net-w-default-4282754a-px2wm   <none>           <none>

NAME                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
persistentvolumeclaim/block-pv-test-0   Bound    pvc-e5b39376-33bb-44af-8753-85a2bba44a6a   10Gi       RWO            ontap-block    47s   Filesystem

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/pvc-e5b39376-33bb-44af-8753-85a2bba44a6a   10Gi       RWO            Delete           Bound    default/block-pv-test-0   ontap-block             45s   Filesystem

次に、Podがデプロイされているノード(demo-ysaka-net-w-default-4282754a-px2wm)にsshで入り、OS Panicを起こします。

ubuntu@demo-ysaka-net-w-default-4282754a-px2wm:~$ sudo bash
root@demo-ysaka-net-w-default-4282754a-px2wm:/home/ubuntu# vi /etc/sysctl.conf 
root@demo-ysaka-net-w-default-4282754a-px2wm:/home/ubuntu# sysctl -p
kernel.panic = 0
root@demo-ysaka-net-w-default-4282754a-px2wm:/home/ubuntu# echo c > /proc/sysrq-trigger

查看节点的状态。

$ kubectl get node
NAME                                       STATUS     ROLES    AGE     VERSION
...
demo-ysaka-net-w-default-4282754a-px2wm    NotReady   <none>   3h52m   v1.26.4

該当のNodeがNotReadyとなっていることを確認しました。 しばらく待ち、Podの状態を確認します。

$ kubectl get pod -o wide
NAME        READY   STATUS        RESTARTS   AGE     IP            NODE                                      NOMINATED NODE   READINESS GATES
pv-test-0   1/1     Terminating   0          8m43s   10.26.26.23   demo-ysaka-net-w-default-4282754a-px2wm   <none>           <none>

在这种状态下,将与先前的验证相同地向节点添加taint(node.kubernetes.io/out-of-service = nodeshutdown:NoExecute)。

$ kubectl taint node demo-ysaka-net-w-default-4282754a-px2wm "node.kubernetes.io/out-of-service=nodeshutdown:NoExecute"
node/demo-ysaka-net-w-default-4282754a-px2wm tainted

在将污点添加后,Pod立即被调度到另一节点上,状态变为Running并成功恢复。

$ kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE                                      NOMINATED NODE   READINESS GATES
pv-test-0   1/1     Running   0          30s   10.26.99.39   demo-ysaka-net-w-default-4282754a-4s68h   <none>           <none>

$ kubectl describe pod pv-test-0 
...
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
  Normal  Scheduled               102s  default-scheduler        Successfully assigned default/pv-test-0 to demo-ysaka-net-w-default-4282754a-4s68h
  Normal  SuccessfulAttachVolume  102s  attachdetach-controller  AttachVolume.Attach succeeded for volume "pvc-e5b39376-33bb-44af-8753-85a2bba44a6a"
  Normal  Pulled                  97s   kubelet                  Container image "ubuntu:20.04" already present on machine
  Normal  Created                 97s   kubelet                  Created container pv-test
  Normal  Started                 97s   kubelet                  Started container pv-test

评论
印象

在本篇文章中,我們進行了對非優雅節點關機的驗證。

在这个功能问世之前,我们需要进入无法正确关闭的节点,并强制卸载卷、注销与存储之间的会话,如iSCSI等。
然而,由于无法正确关闭的节点通常处于某种异常状态,有时甚至无法通过SSH等方式进入节点,因此很多时候无法采取这种手段。
在这种情况下,我们必须等待iSCSI会话超时或在存储端强制断开会话。

如果节点无法正确关闭,恢复的步骤将变得复杂,并且只有具备节点 root 权限和存储管理权限的管理员才能执行,这限制了可执行此操作的管理员的数量。

如果具备设置Kubernetes节点taint的权限的管理员,在执行本次验证的非优雅节点关闭时,即使节点不能正确关闭,可以相对容易地进行恢复。但需要注意的是,需要手动设置taint。要准确判断关闭是否正确执行并不容易。因此,系统设计为管理员可以通过设置taint来恢复被判断为“未正确关闭”的节点。换句话说,管理员需要确保能够检测到“未正确关闭”的情况。一种简单的方法是,在节点状态变为非Ready后,检测其停止时间达到了相当长的时间(这在正确关闭的情况下是不可能的)。

建议您了解非优雅节点关机的用法,这是一种有效的手段,可以在故障发生时快速恢复。同时,推荐您在这个机会上确认运营方法,以确保从故障检测到恢复的过程能在短时间内完成。

参考信息

    • Kubernetes 1.26: Non-Graceful Node Shutdown Moves to Beta

 

    • KEP-2268: Non graceful node shutdown

 

    kubernetes/kubernetes Issue#65392
广告
将在 10 秒后关闭
bannerAds