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 을 적용해보았습니다.
$ 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>
추가이후에도 동일증상 유지
unning이나 terminating 중인 pod들은 모두 Tolerations이 정해져있어 kubernetes의 node의 status taint를 바라보고 움직이고있습니다.
다만, node의 taint상태와 Tolerations이 동일함에도 running이나 terminating을 유지하고있었습니다.
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상태로 머물러 있었습니다.
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는 수동으로 이동해야합니다.