본문 바로가기
Infra & Cloud/DevOps

[Kubernetes] StaticPod: Master Node(Control Plane)의 Pod를 삭제하면 어떻게 될까? (Container Runtime, Containerd)

by newstellar 2022. 12. 2.
반응형

시작하며

일반 개발자가 아닌, 관리자의 입장에서는 Kubernetes 클러스터의 노드에서 Pod가 실행될 때 발생하는 에러들에 대해서 알아야 합니다. (만약 CKAD 수준의 쿠버네티스 이해 및 사용 능력이 아니라 CKA 및 그 이후 단계인 CKS까지 꿈꾼다면!)

대표적으로 발생하는 에러에는 Image가 dockerhub / Nexus Repository / ECR(Elastic Container Registry) 등의 컨테이너 이미지 저장소에서 제대로 불러와지지 않는 상황이 있습니다. 참고로 declarative하게 또는 imperative하게 Kubernetes 오브젝트를 생성할 때, container image가 쓰이는 상황에서는 항상 tag까지 명시해야 버전 관리가 가능하니 습관을 들이기로 합시다. 


본론

docker vs containerd


두 번째로 흔한 상황은, worker node의 Container Runtime(컨테이너 런타임)에 대해 이해하지 못했을 때 발생합니다. 우선 컨테이너 런타임이 무엇인지 확인하려면 아래 명령어의 CONTAINER-RUNTIME 칼럼을 참고하면 됩니다.

kubectl get node -o wide


Kubernetes 1.24 버전부터 dockershim 대신 containerd를 컨테이너 런타임 엔진으로 사용해야 합니다. 일반적인 VM에는 docker binary 파일이 존재하는데, daemon으로 동작하면서 디스크 공간을 차지하는 상황은 벌어지지 않는 것을 알 수 있습니다.

# docker 관련 파일은 존재함.
ls -al usr/bin | grep docker

# 하지만 docker daemon에 의해 차지되는 디스크 공간은 없음.
df -h


(참고 : https://kubernetes.io/ko/docs/setup/production-environment/container-runtimes/ )

 

컨테이너 런타임

참고: Dockershim은 쿠버네티스 릴리스 1.24부터 쿠버네티스 프로젝트에서 제거되었다. 더 자세한 내용은 Dockershim 제거 FAQ를 참고한다. 파드가 노드에서 실행될 수 있도록 클러스터의 각 노드에 컨

kubernetes.io


컨테이너 런타임은 Kubelet으로 하여금 Pod 내에서 container를 실행시킬 때 사용하는데, docker 18버전 이상부터는 우리에게 익숙한 docker 그 자체 대신 containerd가 container를 실행해왔습니다. Image Repository(DockerHub, ECR 등)에서 image를 호출하는 주체도 컨테이너 런타임인 containerd가 담당합니다.)

반응형


Kubernetes의 관점으로 바라보면, Master node의 Api-server가 Kubelet으로 하여금 Pod를 만들고 그 안에서 container를 실행하라는 명령을 내립니다. (개발자 -> kubectl -> kube-apiserver -> kubelet -> containerd 또는 docker(이제는 deprecated)

그러나 정작 container 실행 주체가 없으니 종료-재시작-종료-재시작-... 을 무한 반복하는 것입니다. 이 상태를 표현하는 단어가 바로 crashloopbackoff 입니다. 아래 명령어로 node 상태를 조사하고, ssh 명령어로 node에 접속했을 때 kubelet이 실행되지 않는 경우에도 crashloopbackoff 에러가 나타납니다.

master$ kubectl get node -o wide
master$ ssh [node]

root@[node]:/# service kubelet status


이때 컨테이너 런타임이 docker라고 무작정 생각하고 이미지를 불러오지 못한다고 가정해버리면 docker 명령어로 이미지를 가져와 실행하는 문제가 발생합니다. 이미 worker node에서는 kubelet의 명령을 받아 Pod라는 껍데기 안에서 컨테이너를 실행하는 주체인 containerd가 존재하기 때문입니다.


Static Pods


위와 같은 착각으로 컨테이너 런타임을 중복 실행해버리면 발생하는 문제가 Static Pods가 각각 생성되는 상황입니다. 그렇다면 Static Pods는 무엇일까요?

Static Pod를 이해하기 위한 질문을 던져보겠습니다. 가령 master node 없이 홀로 worker node만이 쿠버네티스 클러스터에 있다고 가정해봅시다. 이 worker node에서는 master node의 scheduler나 api-server 없이도 pod를 생성할 수 있을까요?

kubectl run [podName] --image=nginx:1.14


주지하다시피 kube-apiserver, kube-scheduler가 위치한 master node와의 통신이 불가능하므로 위와 같은 명령어로는 Pod 생성이 불가능합니다. 하지만 worker node 안에는 컨테이너의 실행 주체인 컨테이너 런타임(docker, containerd)이 존재하기 때문에 <사전에 약속한 위치>에 올바른 형식의 .yaml 파일을 넣어둔다면 언제든지 Pod가 실행됨을 보장합니다.

위 개념은 master node에서 유용하게 쓰입니다. 통상적으로 새로운 application을 배포할 때는 master node에 Pod를 새로 만들지 않습니다. (worker node에서 진행합니다.) 다만 controller-manager, apiserver, etcd 등 master node를 구성하는 컴포넌트들 역시 Pod기 때문에 항상 실행시켜줘야되고, 혹시나 삭제되더라도 바로 생성해줘야 합니다. 이런 상황에 Static Pod 개념이 딱 들어맞습니다. Static Pods는 DaemonSets과 마찬가지로 kube-scheduler의 영향을 받지 않습니다.

DaemonSet은 노드에 구애받지 않고 클러스터 전체에 Pod를 설치하는 API 오브젝트로서, 대표적으로 로깅/모니터링 툴들이 DaemonSet 개념을 이용합니다. DaemonSet을 Taint와 Toleration 옵션을 사용하여 특정 노드들에서만 실행할 수도 있습니다. 노드에 Taint를 설정하면 새로운 Pod가 만들어지지 않고, Pod를 띄우기 위해서는 Toleration 옵션을 걸어주면 됩니다.

 

  앞서 <사전에 약속한 위치>에 올바른 형식의 .yaml 파일을 넣어둔다 했습니다. master node에는 /etc/kubernetes/manifests가 약속한 위치이며, 그 안에는 controller-manager.yaml, apiserver.yaml, etcd.yaml 등의 파일이 존재합니다. <사전에 약속한 위치>도 변경할 수 있습니다. 각 node의 kubelet 설정 파일인 /var/lib/kubelet/config.yaml 내 staticPodPath에 정의된 값을 바꿔주면 됩니다. default 값은 staticPodPath: /etc/kubernetes/manifests 겠지요.

 

이렇게 생성된 Static Pod는 master node의 kubelet에 의해 생성과 실행이 보장됩니다. 그래서 우리는 Kubernetes를 안전하게 사용할 수 있습니다.

kubectl get pods -n kube-system


kube-system 네임스페이스에서 실행 중인 Pod를 살펴보면, pod 이름 마지막에 네임스페이스가 붙은 이들이 모두 Static Pods입니다.
(etcd-master, kube-apiserver-master, kube-controller-manager-master, kube-scheduler-master 등)

다시 돌아가서 혹시나 docker를 daemon으로 실행한 경우에는 docker 데몬을 bg에서 해제해주면 됩니다. 그렇지 않으면 Static Pod가 의도하지 않게 여러 개 생성되니까요.

systemctl stop docker
systemctl disable docker



  * 참고 : containerd는 crictl 또는 nerdctl을 통해 동작시킬 수 있음.
    - https://github.com/containerd/containerd/blob/main/docs/cri/crictl.md

    - https://github.com/containerd/nerdctl

 


 

 

[Kubernetes] 쿠버네티스 스케쥴러(Scheduler)를 직접 만들어보자. (kube-scheduler 개념/작동방식)

들어가며 쿠버네티스 스케줄링(Kubernetes Scheduling)이란 적절한 node의 kubelet이 Pod를 실행하도록 할당하는 것을 뜻합니다. Kubernetes에서는 master node(control plane)의 kube-scheduler가 위 역할을 담당합니다.

newstellar.tistory.com

 

[Kubernetes] Authentication/Authentication(인증/인가) 프로세스 및 User/Role 생성(User, CSR, RBAC, RoleBinding)

1. 쿠버네티스에서의 User 개념 쿠버네티스에서는 User(human)와 ServiceAccount(machine) 두 종류의 사용자가 존재합니다. User에는 클러스터 관리자 및 사용자(일반 개발자)가 있으며, ServiceAccount는 Prometheus

newstellar.tistory.com

 

[Kubernetes] NetworkPolicy를 통해 Pod끼리의 트래픽을 통제해보자. (Ingress/Egress, from/to, namespaceSelector, pod

[ NetworkPolicy ] 1. Ingress vs Egress 네트워크 트래픽은 외부로부터 유입되는 Ingress(inbound)와 내부로부터 외부로 나가는 Egress(outbound)로 구분됩니다. 우리가 공부하고 있는 쿠버네티스는 기본적으로 non-

newstellar.tistory.com

 

[Kubernetes] CKA(Certified Kubernetes Administration) 자격증 접수 방법/예약/출제 범위/할인바우처 (+CKAD, CKS

CNCF(Cloud Native Computing Foundation) 재단에서 주관하는 CKA(관리), CKAD(개발), CKS(보안) 세 자격증 가운데, 가장 대표적인 CKA 자격증에 대해 알아봅니다. 접수 및 시험 예약 방법, 추천하는 강좌 그리고

newstellar.tistory.com

 

반응형

댓글