노드 자원 보호하기
최근에 문제가 생긴 노드에 파드를 할당하면 문제가 생길 가능성이 높습니다. 하지만 모든 개발/프로덕션 환경이 그렇듯 사용할 수 있는 자원을 활용하지 않는것또한 자원의 낭비입니다. 때문에 해당 노드를 어쩔수 없이 사용해야하는 경우가 생기는데 어떻게 조치해야할까요? 어떻게 문제가 생길 가능성이 있는 노드임을 쿠버네티스에 알려줄까요? 쿠버네티스에서는 이런경우에 문제가 cordon기능을 사용합니다.
현재 배포된 파드가 없기때문에 파드를 생성해보도록 하겠습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-hname
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: echo-hname
image: sysnet4admin/echo-hname
ubuntu@master001:~$ k apply -f echo-hname.yaml
deployment.apps/echo-hname created
ubuntu@master001:~$ k get po
NAME READY STATUS RESTARTS AGE
echo-hname-5746bc5cb9-46vvs 1/1 Running 0 4s
echo-hname-5746bc5cb9-72bbt 1/1 Running 0 4s
echo-hname-5746bc5cb9-jtxf5 1/1 Running 0 4s
nginx-pod 1/1 Running 1 (50m ago) 5h11m
ubuntu@master001:~$
scale 명령으로 파드를 9개로 늘려보겠습니다.
ubuntu@master001:~$ k scale deploy echo-hname --replicas=9
deployment.apps/echo-hname scaled
ubuntu@master001:~$ k get po
NAME READY STATUS RESTARTS AGE
echo-hname-5746bc5cb9-46vvs 1/1 Running 0 48s
echo-hname-5746bc5cb9-72bbt 1/1 Running 0 48s
echo-hname-5746bc5cb9-7g7rb 0/1 ContainerCreating 0 3s
echo-hname-5746bc5cb9-85lm4 1/1 Running 0 3s
echo-hname-5746bc5cb9-85vln 1/1 Running 0 3s
echo-hname-5746bc5cb9-9wdlj 0/1 ContainerCreating 0 3s
echo-hname-5746bc5cb9-dqcm5 1/1 Running 0 3s
echo-hname-5746bc5cb9-jtxf5 1/1 Running 0 48s
echo-hname-5746bc5cb9-qj4z8 0/1 ContainerCreating 0 3s
nginx-pod 1/1 Running 1 (51m ago) 5h11m
ubuntu@master001:~$ k get po
NAME READY STATUS RESTARTS AGE
echo-hname-5746bc5cb9-46vvs 1/1 Running 0 56s
echo-hname-5746bc5cb9-72bbt 1/1 Running 0 56s
echo-hname-5746bc5cb9-7g7rb 1/1 Running 0 11s
echo-hname-5746bc5cb9-85lm4 1/1 Running 0 11s
echo-hname-5746bc5cb9-85vln 1/1 Running 0 11s
echo-hname-5746bc5cb9-9wdlj 1/1 Running 0 11s
echo-hname-5746bc5cb9-dqcm5 1/1 Running 0 11s
echo-hname-5746bc5cb9-jtxf5 1/1 Running 0 56s
echo-hname-5746bc5cb9-qj4z8 1/1 Running 0 11s
nginx-pod 1/1 Running 1 (51m ago) 5h12m
배포된 9개의 파드의 세부사항을 columns를 사용하여 출력해보겠습니다.
ubuntu@master001:~$ k get po \\
> -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:status.phase,NODE:.spec.nodeName
NAME IP STATUS NODE
echo-hname-5746bc5cb9-46vvs 10.36.0.2 Running slave002
echo-hname-5746bc5cb9-72bbt 10.36.0.1 Running slave002
echo-hname-5746bc5cb9-7g7rb 10.36.0.4 Running slave002
echo-hname-5746bc5cb9-85lm4 10.44.0.3 Running slave001
echo-hname-5746bc5cb9-85vln 10.36.0.3 Running slave002
echo-hname-5746bc5cb9-9wdlj 10.44.0.4 Running slave001
echo-hname-5746bc5cb9-dqcm5 10.36.0.5 Running slave002
echo-hname-5746bc5cb9-jtxf5 10.44.0.2 Running slave001
echo-hname-5746bc5cb9-qj4z8 10.44.0.5 Running slave001
nginx-pod 10.44.0.1 Running slave001
ubuntu@master001:~$
scale로 파드의 수를 2개로 줄입니다. 각 노드에 파드가 1개씩 남았는지 확인합니다.
ubuntu@master001:~$ k delete pod nginx-pod
pod "nginx-pod" deleted
ubuntu@master001:~$ k scale deploy echo-hname --replicas=2
deployment.apps/echo-hname scaled
ubuntu@master001:~$ k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
echo-hname-5746bc5cb9-4rshr 1/1 Running 0 11s 10.36.0.2 slave002 <none> <none>
echo-hname-5746bc5cb9-zrdfc 1/1 Running 0 11s 10.44.0.1 slave001 <none> <none>
ubuntu@master001:~$
워커노드2에 문제가 발생해 현재 상태를 보존해야 한다고 가정하겠습니다. cordon을 적용합니다.
ubuntu@master001:~$ k cordon slave002
node/slave002 cordoned
ubuntu@master001:~$ k get nodes
NAME STATUS ROLES AGE VERSION
master001 Ready control-plane 13d v1.27.4
slave001 Ready <none> 13d v1.27.4
slave002 Ready,SchedulingDisabled <none> 13d v1.27.4
ubuntu@master001:~$
node2는 이제 파드가 할당되지 않는 상태를 가집니다. 이 상태에서 파드 수를 늘려보겠습니다.
ubuntu@master001:~$ k scale deployment echo-hname --replicas=9
deployment.apps/echo-hname scaled
ubuntu@master001:~$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
echo-hname-5746bc5cb9-4fbvt 1/1 Running 0 12s 10.44.0.5 slave001 <none> <none>
echo-hname-5746bc5cb9-4r4zx 1/1 Running 0 12s 10.44.0.6 slave001 <none> <none>
echo-hname-5746bc5cb9-4rshr 1/1 Running 0 2m34s 10.36.0.2 slave002 <none> <none>
echo-hname-5746bc5cb9-9g54x 1/1 Running 0 12s 10.44.0.2 slave001 <none> <none>
echo-hname-5746bc5cb9-9zwt2 1/1 Running 0 12s 10.44.0.3 slave001 <none> <none>
echo-hname-5746bc5cb9-bdmgk 1/1 Running 0 12s 10.44.0.7 slave001 <none> <none>
echo-hname-5746bc5cb9-dkr4f 1/1 Running 0 12s 10.44.0.8 slave001 <none> <none>
echo-hname-5746bc5cb9-stm7p 1/1 Running 0 12s 10.44.0.4 slave001 <none> <none>
echo-hname-5746bc5cb9-zrdfc 1/1 Running 0 2m34s 10.44.0.1 slave001 <none> <none>
ubuntu@master001:~$
노드2에 파드가 더이상 할당되지 않는것을 확인 할 수 있습니다.
uncordon을 적용합니다.
ubuntu@master001:~$ k uncordon slave002
node/slave002 uncordoned
노드 유지보수하기
쿠버네티스 사용시에 정기 또는 비정기적인 유지보수를 위해 노드를 꺼야하는 상황이 발생하기도 합니다. 이때 쿠버네티스는 drain기능을 제공합니다. drain은 지정된 파드를 전부 다른 곳으로 이동시켜 해당 노드를 유지보수 할 수 있도록 합니다.
drain명령을 사용하여 유지보수할 노드를 파드가 없는 상태로 만들어보도록 하겠습니다.
ubuntu@master001:~$ k drain slave002
node/slave002 cordoned
error: unable to drain node "slave002" due to error:cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/kube-proxy-dhgrf, kube-system/weave-net-zqllr, continuing command...
There are pending nodes to be drained:
slave002
cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/kube-proxy-dhgrf, kube-system/weave-net-zqllr
ubuntu@master001:~$
데몬셋을 지울수 없기때문에 명령을 수행 할 수 없다고합니다.
drain은 실제 파드를 옮기는것이 아니라 파드를 삭제하고 다른곳에 생성합니다. 데몬셋은 각 노드에 1개씩만 존재하는 파드이기때문에 drain으로는 삭제할 수 없습니다.
이번에는 ignore-daemonsets옵션을 함께 사용하여 데몬셋을 무시하고 진행해보도록 하겠습니다.
ubuntu@master001:~$ k drain slave002 --ignore-daemonsets
node/slave002 already cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-dhgrf, kube-system/weave-net-zqllr
evicting pod default/echo-hname-5746bc5cb9-4rshr
pod/echo-hname-5746bc5cb9-4rshr evicted
node/slave002 drained
ubuntu@master001:~$ k get no
NAME STATUS ROLES AGE VERSION
master001 Ready control-plane 13d v1.27.4
slave001 Ready <none> 13d v1.27.4
slave002 Ready,SchedulingDisabled <none> 13d v1.27.4
ubuntu@master001:~$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
echo-hname-5746bc5cb9-4fbvt 1/1 Running 0 12m 10.44.0.5 slave001 <none> <none>
echo-hname-5746bc5cb9-4r4zx 1/1 Running 0 12m 10.44.0.6 slave001 <none> <none>
echo-hname-5746bc5cb9-9g54x 1/1 Running 0 12m 10.44.0.2 slave001 <none> <none>
echo-hname-5746bc5cb9-9zwt2 1/1 Running 0 12m 10.44.0.3 slave001 <none> <none>
echo-hname-5746bc5cb9-bdmgk 1/1 Running 0 12m 10.44.0.7 slave001 <none> <none>
echo-hname-5746bc5cb9-dkr4f 1/1 Running 0 12m 10.44.0.8 slave001 <none> <none>
echo-hname-5746bc5cb9-j22sd 1/1 Running 0 24s 10.44.0.9 slave001 <none> <none>
echo-hname-5746bc5cb9-stm7p 1/1 Running 0 12m 10.44.0.4 slave001 <none> <none>
echo-hname-5746bc5cb9-zrdfc 1/1 Running 0 14m 10.44.0.1 slave001 <none> <none>
ubuntu@master001:~$
모든 파드가 워커노드 1에서 실행됨을 확인할 수 있습니다.
파드를 업데이트하고 복구하기
파드운영시에 새로운 기능을 추가하거나 버그를 픽스해야할 때가 있습니다. 업데이트중 문제가 발생하여 기존버전으로 롤백해야하는 상황도 발생합니다. 이때 쿠버네티스에서 어떻게 처리해야하는지에 알아보도록 하겠습니다.
파드업데이트
간단한 파드를 배포하도록 하겠습니다. —record 옵션을 사용하여 배포 정보의 히스토리를 기록합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: rollout-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.12
ubuntu@master001:~$ k apply -f rollout-nginx.yaml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/rollout-nginx created
ubuntu@master001:~$
record옵션으로 기록된 히스토리는 rollout history 명령으로 확인해볼수 있습니다.
ubuntu@master001:~$ k rollout history deployment rollout-nginx
deployment.apps/rollout-nginx
REVISION CHANGE-CAUSE
1 kubectl apply --filename=rollout-nginx.yaml --record=true
ubuntu@master001:~$
배포한 파드의 정보를 확인하고 ip를 기억해둡니다. nginx 버전을 확인해보겠습니다.
ubuntu@master001:~$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rollout-nginx-6b6c46d58f-55pml 1/1 Running 0 44h 10.36.0.1 slave002 <none> <none>
rollout-nginx-6b6c46d58f-cz5l7 1/1 Running 0 44h 10.44.0.1 slave001 <none> <none>
rollout-nginx-6b6c46d58f-dgsk5 1/1 Running 0 44h 10.36.0.2 slave002 <none> <none>
ubuntu@master001:~$ curl -I --silent 10.36.0.1 | grep Server
Server: nginx/1.15.12
ubuntu@master001:~$
컨테이너의 nginx 버전을 업데이트 하도록 하겠습니다. —record 옵션으로 명령을 기록합니다.
ubuntu@master001:~$ k set image deployment rollout-nginx nginx=nginx:1.16.0 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/rollout-nginx image updated
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-6b6c46d58f-55pml 1/1 Running 0 45h
rollout-nginx-6b6c46d58f-cz5l7 1/1 Running 0 45h
rollout-nginx-6b6c46d58f-dgsk5 1/1 Running 0 45h
rollout-nginx-9bcd84889-w6hpj 0/1 ContainerCreating 0 4s
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-6b6c46d58f-cz5l7 1/1 Running 0 45h
rollout-nginx-6b6c46d58f-dgsk5 1/1 Running 0 45h
rollout-nginx-9bcd84889-sqm85 0/1 ContainerCreating 0 5s
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 13s
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-6b6c46d58f-dgsk5 0/1 Terminating 0 45h
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 1s
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 9s
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 17s
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 6s
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 14s
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 22s
ubuntu@master001:~$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 49s 10.44.0.3 slave001 <none> <none>
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 57s 10.44.0.2 slave001 <none> <none>
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 65s 10.36.0.3 slave002 <none> <none>
파드의 이름과 ip가 변경되었습니다. 컨테이너 업데이트 시에 replicas의 수를 줄이고 늘려서 파드를 새로생성합니다. replicas의 모든 파드를 한번에 지우는 것이 아닌 하나씩을 순차적으로 지우고 생성하게 됩니다. 업데이트 기본값은 전체의 1/4 이며 최솟값은 1개입니다.
업데이트 실패 시 파드 복구하기
set image 명령으로 nginx 컨테이너 버전을 잘못 입력해보도록 하겠습니다.
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-6f58d68f85-h5bw6 0/1 ErrImagePull 0 6s
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 19m
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 19m
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 19m
ubuntu@master001:~$ k get pods
NAME READY STATUS RESTARTS AGE
rollout-nginx-6f58d68f85-h5bw6 0/1 ImagePullBackOff 0 18s
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 19m
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 19m
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 19m
업데이트가 더이상 진행되지 않고, 파드가 동작하지 않음을 확인 할 수 있습니다.
rollout undo 명령을 통해 마지막 개정에서 전 개정으로 되돌리도록 하겠습니다.
ubuntu@master001:~$ k rollout undo deployment rollout-nginx
deployment.apps/rollout-nginx rolled back
ubuntu@master001:~$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rollout-nginx-9bcd84889-cbsx5 1/1 Running 0 21m 10.44.0.3 slave001 <none> <none>
rollout-nginx-9bcd84889-sqm85 1/1 Running 0 21m 10.44.0.2 slave001 <none> <none>
rollout-nginx-9bcd84889-w6hpj 1/1 Running 0 21m 10.36.0.3 slave002 <none> <none>
ubuntu@master001:~$
히스토리를 확인해보면 개정5가 추가되었고 1.16 버전으로 롤백함을 알 수 있습니다.
ubuntu@master001:~$ k rollout history deployment rollout-nginx
deployment.apps/rollout-nginx
REVISION CHANGE-CAUSE
1 kubectl apply --filename=rollout-nginx.yaml --record=true
2 kubectl set image deployment rollout-nginx nginx=1.16.0 --record=true
4 kubectl set image deployment rollout-nginx nginx=nginx:2.0.0 --record=true
5 kubectl set image deployment rollout-nginx nginx=nginx:1.16.0 --record=true
ubuntu@master001:~$
특정 시점으로 파드 복구하기
바로 전 시점이아니라 특정 개정 시점으로 복구하고싶다면 —to-revision옵션을 사용합니다.
처음상태인 revision 1로 돌아가보겠습니다.
ubuntu@master001:~$ k rollout undo deployment rollout-nginx --to-revision=1
deployment.apps/rollout-nginx rolled back
ubuntu@master001:~$
nginx 버전을 확인해보도록 하겠습니다.
ubuntu@master001:~$ k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rollout-nginx-6b6c46d58f-pwtts 1/1 Running 0 35s 10.44.0.1 slave001 <none> <none>
rollout-nginx-6b6c46d58f-zngxx 1/1 Running 0 36s 10.36.0.1 slave002 <none> <none>
rollout-nginx-6b6c46d58f-zw9dl 1/1 Running 0 34s 10.44.0.3 slave001 <none> <none>
ubuntu@master001:~$ curl -I --silent 10.44.0.1 | grep Server
Server: nginx/1.15.12
ubuntu@master001:~$
1.15.12버전이므로 처음 상태로 복구된 것을 확인 할 수 있습니다.
'Kubernetes' 카테고리의 다른 글
K8s from scratch - 6. 인그레스 (0) | 2023.10.25 |
---|---|
K8s from scratch - 5. 외부와의 연결담당 (서비스) (0) | 2023.10.25 |
K8s from scratch - 3. 파드 생성 및 삭제, Self-Healing (0) | 2023.10.25 |
K8s from scratch - 2. 쿠버네티스 구성 요소 (0) | 2023.10.25 |
K8s from scratch - 1. AWS 에서 쿠버네티스 환경 구축하기 (0) | 2023.10.25 |