kubernetes 비정상적 종료

beomjin·2024년 7월 30일

kubernetes 1.24v 를 사용하고 있는 환경에서 master node가 죽게되면 master node에 동작하는 stateful set pod와 daemon set pod가 running상태 혹은 terminating상태로 남아있는 경우가 있습니다.

$ kubectl get po -n openstack -o wide |grep control01
btx-0                                          1/1     Terminating        0                92m     10.233.120.122   control01   <none>           <none>
cinder-api-6c74c7f8f6-qtghd                    1/1     Terminating        0                98m     10.233.120.109   control01   <none>           <none>
cinder-backup-6889c9c65f-lzpxt                 1/1     Terminating        0                98m     10.233.120.112   control01   <none>           <none>
cinder-scheduler-58cfd855cb-8vjfr              1/1     Terminating        0                98m     10.233.120.108   control01   <none>           <none>
cinder-volume-6c699cd764-7r4ns                 1/1     Terminating        0                98m     10.233.120.111   control01   <none>           <none>
glance-api-848c6cb79d-95mkz                    2/2     Terminating        0                111m    10.233.120.90    control01   <none>           <none>
horizon-5499c4fc8b-hhtlm                       1/1     Terminating        0                95m     10.233.120.118   control01   <none>           <none>
ingress-0                                      1/1     Terminating        0                117m    192.168.20.31    control01   <none>           <none>
keystone-api-78c4c85fb5-5svdt                  1/1     Terminating        0                113m    10.233.120.78    control01   <none>           <none>
mariadb-ingress-678fff6745-zzxls               1/1     Terminating        0                117m    10.233.120.74    control01   <none>           <none>
mariadb-server-1                               1/1     Terminating        0                117m    10.233.120.76    control01   <none>           <none>
neutron-bgp-dragent-default-8894x              1/1     Running            0                106m    192.168.20.31    control01   <none>           <none>
neutron-dhcp-agent-default-4mwdg               1/1     Running            0                106m    192.168.20.31    control01   <none>           <none>
neutron-l3-agent-default-lrkdx                 1/1     Running            0                106m    192.168.20.31    control01   <none>           <none>
neutron-metadata-agent-default-56sdx           0/1     CrashLoopBackOff   21 (12m ago)     106m    192.168.20.31    control01   <none>           <none>
neutron-ovs-agent-default-qt7vz                1/1     Running            0                106m    192.168.20.31    control01   <none>           <none>
neutron-server-556fc9444c-q7ctw                2/2     Terminating        0                106m    10.233.120.92    control01   <none>           <none>
nova-api-metadata-55fdf9c5cf-hg859             1/1     Terminating        0                102m    10.233.120.97    control01   <none>           <none>
nova-api-osapi-c477c575b-cncj2                 1/1     Terminating        0                102m    10.233.120.101   control01   <none>           <none>
nova-conductor-7c67b6d696-tlkw7                1/1     Terminating        0                102m    10.233.120.99    control01   <none>           <none>
nova-novncproxy-6596c57dcd-q9cg2               1/1     Terminating        0                102m    192.168.20.31    control01   <none>           <none>
nova-scheduler-5566c99c74-7zpx8                1/1     Terminating        0                102m    10.233.120.98    control01   <none>           <none>
openvswitch-db-5rvzz                           1/1     Running            0                114m    192.168.20.31    control01   <none>           <none>
openvswitch-vswitchd-f7xgq                     1/1     Running            0                114m    192.168.20.31    control01   <none>           <none>
placement-api-78f559d7db-h8lb6                 1/1     Terminating        0                108m    10.233.120.87    control01   <none>           <none>
rabbitmq-rabbitmq-2                            1/1     Terminating        0                117m    10.233.120.75    control01   <none>           <none>

상기 내용을 조치하기 위하여 pod-eviction-timout 을 적용해보았습니다.

kube-controller-manager.yml

$ sudo vi kube-controller-manager.yaml
...
    - --node-cidr-mask-size=24
    - --node-monitor-grace-period=40s
    - --node-monitor-period=5s
+   - --pod-eviction-timeout=300s
    - --profiling=False
    - --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.crt
    - --root-ca-file=/etc/kubernetes/ssl/ca.crt

kube-controller-manager에 pod-evivtion-timeout=300s 를 추가

$ sudo kubectl get po -n openstack -o wide |grep control02
cinder-backup-584c65856-4826r                  1/1     Terminating        1 (35m ago)    60m     10.233.77.54     control02   <none>           <none>
cinder-scheduler-8c9f54477-rzlmr               1/1     Terminating        1 (35m ago)    60m     10.233.77.28     control02   <none>           <none>
cinder-volume-685b649d79-wmnbz                 1/1     Terminating        1 (35m ago)    60m     10.233.77.58     control02   <none>           <none>
horizon-5499c4fc8b-bntjg                       1/1     Terminating        1 (35m ago)    60m     10.233.77.45     control02   <none>           <none>
ingress-0                                      1/1     Terminating        0              68m     192.168.20.32    control02   <none>           <none>
keystone-api-78c4c85fb5-lm86r                  1/1     Terminating        1 (35m ago)    60m     10.233.77.49     control02   <none>           <none>
mariadb-ingress-678fff6745-6fc7c               1/1     Terminating        1 (34m ago)    60m     10.233.77.2      control02   <none>           <none>
mariadb-server-1                               1/1     Terminating        1 (33m ago)    60m     10.233.77.57     control02   <none>           <none>
neutron-bgp-dragent-default-h9jxc              1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
neutron-dhcp-agent-default-fm9dn               1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
neutron-l3-agent-default-t9jk6                 1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
neutron-metadata-agent-default-s6j4b           0/1     CrashLoopBackOff   14 (31m ago)   88m     192.168.20.32    control02   <none>           <none>
neutron-ovs-agent-default-g8g82                1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
neutron-server-5989c44c84-xpr4g                2/2     Terminating        2 (35m ago)    60m     10.233.77.31     control02   <none>           <none>
nova-api-metadata-7676cc7488-5q5gb             1/1     Terminating        1 (35m ago)    60m     10.233.77.32     control02   <none>           <none>
nova-api-osapi-7c856f8455-zsg5l                1/1     Terminating        1 (35m ago)    60m     10.233.77.44     control02   <none>           <none>
nova-novncproxy-c8d5f4b59-r927l                1/1     Terminating        0              89m     192.168.20.32    control02   <none>           <none>
openvswitch-db-5nkkg                           1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
openvswitch-vswitchd-85qf6                     1/1     Running            0              88m     192.168.20.32    control02   <none>           <none>
rabbitmq-rabbitmq-2                            1/1     Terminating        1 (33m ago)    60m     10.233.77.1      control02   <none>           <none>

추가이후에도 동일증상 유지

Taint Tolerations 적용

unning이나 terminating 중인 pod들은 모두 Tolerations이 정해져있어 kubernetes의 node의 status taint를 바라보고 움직이고있습니다.

다만, node의 taint상태와 Tolerations이 동일함에도 running이나 terminating을 유지하고있었습니다.

statefulset pod tolerations

Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

Rabbitmq의 pod의 tolerations은 kube node의 상태가 not ready이거나, unreachable상태일 때, 300s를 기다린 후에도 변동이 없다면,

pod에서 노드가 제거되도록 설정이 되어있습니다.

$ sudo kubectl describe node control02
Name:               control02
...
Taints:             node.kubernetes.io/unreachable:NoExecute
                    node.kubernetes.io/unreachable:NoSchedule

실제로 node의 상태를 not-ready로 변동을 하여도, 해당 Tolerations으로 인한 pod 제거는 없었으며, pod는 terminating상태로 머물러 있었습니다.

none graceful node shutdown

k8s 1.24 버전부터 적용 된 기능게이트웨이 중 논 그레이스 풀 노드 셧다운에 의하면, kubelet이 감지하지 못한 동작(비 정상적인 종료)에 대하여

pod 서비스를 모두 다른곳으로 옮기는 방법이있습니다. 이는 k8s 의 taint에 out-of-service를 이용한 방법입니다.

기능소개 :: (https://kubernetes.io/ko/docs/concepts/architecture/nodes/)

자세한 내용 :: ( https://kubernetes.io/blog/2022/05/20/kubernetes-1-24-non-graceful-node-shutdown-alpha/ )

적용을 위해선 다음과 같이 kube-controller-manager에 아래와 같이 기능게이트를 추가합니다.

$ sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml
...
    - --terminated-pod-gc-threshold=12500
    - --use-service-account-credentials=true
    - --pod-eviction-timeout=20s
+    - --feature-gates=NodeOutOfServiceVolumeDetach=true
...

Node의 taint에 out-of-service가 표기되면, Pod에 대한 볼륨 분리 작업을 수행하며 다른 node에서 pod가 뜰 수 있도록 기능을해주는 기능 게이트를 추가합니다.

(해당 yaml파일 수정하게되면, 자동으로 kube-system의 namespace에서 kube-controller-manager가 재기동됩니다.)

$ sudo kubectl get node
NAME        STATUS     ROLES           AGE   VERSION
compute01   Ready      <none>          20h   v1.24.8
compute02   Ready      <none>          20h   v1.24.8
control01   Ready      control-plane   20h   v1.24.8
control02   NotReady   control-plane   20h   v1.24.8
control03   Ready      control-plane   20h   v1.24.8
 
$ sudo kubectl get po -n openstack -o wide |grep control02
ingress-0                                      1/1     Terminating   0              43m    192.168.20.32    control02   <none>           <none>
mariadb-server-1                               1/1     Terminating   1 (30m ago)    43m    10.233.77.21     control02   <none>           <none>
neutron-bgp-dragent-default-h9jxc              1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
neutron-dhcp-agent-default-fm9dn               1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
neutron-l3-agent-default-t9jk6                 1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
neutron-metadata-agent-default-s6j4b           1/1     Running       15 (12h ago)   13h    192.168.20.32    control02   <none>           <none>
neutron-ovs-agent-default-g8g82                1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
nova-novncproxy-c8d5f4b59-frk4f                1/1     Terminating   0              12h    192.168.20.32    control02   <none>           <none>
openvswitch-db-5nkkg                           1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
openvswitch-vswitchd-85qf6                     1/1     Running       1 (12h ago)    13h    192.168.20.32    control02   <none>           <none>
rabbitmq-rabbitmq-2                            1/1     Terminating   1 (30m ago)    43m    10.233.77.15     control02   <none>           <none>

taint적용 전 pod의 상태는 현재 이렇습니다.

running중인 pod는 모두 daemon-set이며, terminating상태의 pod는 statefulset pod입니다.

$ sudo kubectl taint node control02 node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
node/control02 tainted
 
$ sudo kubectl describe node control02
...
Taints:             node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
                    node.kubernetes.io/unreachable:NoExecute
                    node.kubernetes.io/unreachable:NoSchedule
 
 
$ sudo kubectl get po -n openstack -o wide |grep control02

control02에 논 그레이스 풀 노드 셧다운을 위한 taint추가(out-of-service) 후 control02위에 pod를 확인해보았지만, control02는 out-of-service가 되며 pod가 모두 삭제되었습니다.

(control02에 구동중이던 pod 중 daemon-set의 경우, 삭제, statefulset pod의 경우 다른 node로 이주)

$ kubectl get po -n openstack -o wide |grep rabbitmq
rabbitmq-rabbitmq-0                            1/1     Running     1 (4m36s ago)   18h     10.233.83.47     control03   <none>           <none>
rabbitmq-rabbitmq-1                            1/1     Running     2 (2m38s ago)   18h     10.233.120.106   control01   <none>           <none>
rabbitmq-rabbitmq-2                            0/1     Init:0/4    0               5m41s   <none>           control03   <none>           <none>
 
 
$ kubectl get po -n openstack -o wide |grep mariadb-server
mariadb-server-0                               1/1     Running     0               18h     10.233.83.48     control03   <none>           <none>
mariadb-server-1                               0/1     Init:0/2    0               5m49s   <none>           control03   <none>           <none>
mariadb-server-2                               1/1     Running     0               18h     10.233.120.107   control01   <none>           <none>

statefulset의 대표적인 pod (rabbitmq, mariadb)는 각각 controller 03으로 이주하였으나 init상태였습니다.

그렇다면, 다시 control02를 정상적으로 ready상태로 돌린 후 적용하였던 taint를 제거해보겠습니다.

$ sudo kubectl taint node control02 node.kubernetes.io/out-of-service=nodeshutdown:NoExecute-
node/control02 untainted
 
$ sudo kubectl describe node control02
...
Taints:             <none>
 
[clex@control01 ~]$ sudo kubectl get po -n openstack -o wide |grep control02
ingress-0                                      1/1     Running     0             3m22s   192.168.20.32    control02   <none>           <none>
neutron-bgp-dragent-default-7gmnk              0/1     Init:0/2    0             59s     192.168.20.32    control02   <none>           <none>
neutron-dhcp-agent-default-6ndhz               0/1     Init:0/2    0             59s     192.168.20.32    control02   <none>           <none>
neutron-l3-agent-default-5kd7q                 0/1     Init:0/2    0             59s     192.168.20.32    control02   <none>           <none>
neutron-metadata-agent-default-7f65p           0/1     Init:0/2    0             59s     192.168.20.32    control02   <none>           <none>
neutron-ovs-agent-default-p4hcq                0/1     Init:0/3    0             59s     192.168.20.32    control02   <none>           <none>
nova-novncproxy-c8d5f4b59-hvzqn                0/1     Running     0             6m17s   192.168.20.32    control02   <none>           <none>
openvswitch-db-q4jr5                           0/1     Running     0             59s     192.168.20.32    control02   <none>           <none>
openvswitch-vswitchd-k9mws                     0/1     Init:0/2    0             59s     192.168.20.32    control02   <none>           <none>

taint(out-of-service)를 제거하자, daemon-set pod들이 구동되며, 다른 node로 이주했던 deployment pod나 statefulset pod는 수동으로 이동해야합니다.

0개의 댓글