Kubernetes를 갓 배우기 시작한 동료 개발자들에게 Kubernetes 클러스터의 기본 구성에 대해 설명하다보면 많이들 헷갈려하는 것이 있다. 바로, kubelet과 kube-proxy이다.

두 컴포넌트는 모두 Kubernetes 클러스터를 구성하는 각 노드에 설치되어 동작하지만, 실제로 클러스터를 운영할 때 우리가 이들을 다룰 일이 많지 않아서 그렇다. (둘 다 kube로 시작해서 헷갈려하는 경우도 있을 것이다.)

하지만 kubelet와 kube-proxy가 어떤 일을 하는지 이해하고 있다면 Kubernetes 클러스터를 운영할 때의 트러블슈팅에도 큰 도움이 된다. 문제의 원인 의심 지점을 더 제대로 파악할 수 있기 때문이다.

그래서 이번 아티클에서는 클러스터의 각 노드에서 리소스 상태 관리를 담당하는 kubelet트래픽 전달을 담당하는 kube-proxy에 대해 컴팩트하게 알아보려 한다.

1. 리소스 상태 관리를 담당하는 kubelet

Kubernetes의 Pod가 한 개 이상의 컨테이너로 구성된다는 것은 익히 알려진 사실이다. 즉, Kubernetes에 배포되는 애플리케이션은 기본적으로 컨테이너 내에서 동작한다.

각 노드에서 동작하는 kubelet은 이 컨테이너가 매니페스트에 정의된 Pod의 사양(spec)대로 노드에 잘 배포되도록 관리하는 역할을 수행한다.

kubelet은 각 노드에 설치된 컨테이너 런타임(예: Docker, containerd)과 연동되어 있다. 그래서 전달받은 매니페스트 파일의 spec 내용에 맞춰 필요한 컨테이너 이미지와 각종 설정을 컨테이너 런타임에게 알려줘 올바른 컨테이너를 실행하도록 관리할 수 있다.

Pod에 Liveness Probe가 설정되어 있다면 kubelet이 해당 설정을 통해 컨테이너가 정상 동작 중인지 체크할 수 있다. 만약 컨테이너 동작에 이상이 있다고 판단되면 Restart Policy에 정의된 대로 컨테이너 재시작을 수행할 수도 있다.

이런 kubelet에 문제가 생길 경우 발생할 수 있는 이슈는 아래와 같다.

  • 해당 노드에 새로운 컨테이너 배포 불가

  • 해당 노드에 배포된 기존 컨테이너의 상태 관리 불가

즉, kubelet의 작동이 멈춘 노드는 Kubernetes 클러스터 관점에서 사용할 수 없는 것이다.

만약 위와 같이 클러스터 노드를 사용할 수 없다면 해당 노드에 설치된 kubelet의 상태와 로그를 확인해봐야 한다.

해당 노드에 SSH 접속 후 systemctl status kubelet 명령어로 kubelet의 상태를 먼저 체크하고, 만약 정상 동작 중이 아니라면 아래 방법 중 하나로 kubelet의 로그를 확인하여 문제 원인을 찾아보자.

  • journalctl -u kubelet

  • /var/log/kubelet.log 또는 /var/log/syslog 로그 파일의 내용 확인

2. 트래픽 전달을 담당하는 kube-proxy

클러스터에 배포한 애플리케이션의 컨테이너를 kubelet이 아무리 잘 관리한다고 해도 외부에서 해당 애플리케이션으로 접속할 수 없다면 무용지물이다.

외부에서 Kubernetes 클러스터 안으로 들어온 사용자의 트래픽을 올바른 컨테이너로 잘 인도해야 하는 것이다.

각 노드에서 동작하는 kube-proxy가 바로 이런 길잡이 역할을 수행한다.

특히 Kubernetes의 Service 리소스가 제 역할을 해낼 수 있도록 도와주는데, Service의 IP와 포트번호로 접근한 외부 트래픽을 Service와 연동된 실제 컨테이너의 IP로 전달해주기 때문이다.

모든 노드에서 동작하는 kube-proxy는 클러스터에 배포된 Service나 Pod의 IP 주소 등을 주기적으로 확인하고 업데이트한다. 그래서 어떤 노드에 배포되었든 상관없이 외부 트래픽이 사전에 정의된 대로 Service를 거쳐 올바른 컨테이너로 전해질 수 있는 것이다.

이런 kube-proxy에 문제가 생긴다면 어떻게 될까?

  • 외부 트래픽이 Service로 전달되지 못해 Timeout 발생

    • 특히 일부 노드에 배포된 kube-proxy에 문제가 생겼다면, 일부 사용자만 접속 오류를 경험하게 될 위험이 있다. (간헐적 장애)

kube-proxy는 각 노드에 Daemonset 리소스로 배포된다. 만약 위와 같은 간헐적 장애가 발생한다면 kube-proxy Daemonset의 로그와 이벤트를 확인해보자.

Kubernetes 클러스터의 기본 구성에 포함되어있는 kube-proxy이지만, 최근에는 kube-proxy를 쓰지 않고 다른 대체재를 사용하는 경우도 있다.

특히 수많은 리소스가 배포되고 사라지는 대규모 클러스터에서 그렇다. 무수히 많은 컨테이너의 IP 주소가 매번 변경되기 때문에 kube-proxy가 이를 기록하고 업데이트하는 데에 시간이 오래 걸리고 리소스도 많이 소모될 수 있기 때문이다.

kube-proxy의 대체재로 주목받는 Cilium은 eBPF 기술(리눅스 커널 내부에서 작업을 더욱 빠르게 처리하는 기술)을 활용한다. 그 덕분에 복잡한 단계를 거치지 않고 기존 kube-proxy의 역할을 더 빠르게 수행할 수 있다.

마무리

지금까지 kubelet과 kube-proxy가 정확히 어떤 역할을 수행하는지 알아봤다. 이제 여러분은 클러스터 운영 시 이 두 컴포넌트도 염두에 두고 트러블슈팅을 할 수 있을 것이다.

이번에 kube-proxy를 살펴봤기 때문에 Kubernetes 클러스터 내부에서의 트래픽 흐름을 OSI 계층과 연관지어 함께 알아보는 심화 주제도 추후 아티클로 다뤄볼 수 있을 것이다. 이와 관련하여 아이디어를 주신 구독자분께 감사 인사를 드린다.

또한 kubelet의 역할에 대해서 이해했으니, 터미널에서 kubectl apply 명령어를 실행한 시점에서부터 실제 Pod가 배포되기까지의 흐름도 다른 아티클에서 정리해보겠다.

함께 읽어보면 좋은 아티클

Keep Reading