쿠버네티스 시작하기(4) - 쿠버네티스 아키텍쳐
이전 장에서 쿠버네티스(kubernetes) 클러스터의 구성요소에 대해 정리해 보았다. 이제 실제로 쿠버네티스가 어떤 아키텍쳐로 구현이 되어 있는지 알아보도록 하자. 아키텍쳐를 이해하면 쿠버네티스 사용법을 이해하는데 도움이 된다.
아래는 쿠버네티스의 구조를 간단한 그림으로 나타낸 것이다.
쿠버네티스는 크게 전체 클러스터를 관리하는 마스터(Master)와 컨테이너가 배포되는 노드(Node)로 구성되어 있다. 모든 명령은 마스터의 API서버를 호출하고 노드는 마스터와 통신하면서 필요한 작업을 수행한다. 특정 노드의 컨테이너에 명령하거나 로그를 조회할 때도 노드에 직접 명령하는 것이 아니라 마스터에 명령을 내리고 노드에 접속하여 대신 결과를 응답한다.
1. 마스터(Kubernetes Master)
쿠버네티스 마스터(Kubernetes Master)는 쿠버네티스 클러스터 전체를 컨트롤 하는 시스템이다. 관리자만 접속할 수 있도록 보안 설정을 해야 하고 마스터 서버가 죽으면 클러스터를 관리할 수 없기 때문에 보통 3대를 구성하여 안전성을 높인다. AWS EKS같은 경우 마스터를 AWS 자체 관리하여 안정성을 높였고(마스터에 접속 불가), 개발 환경이나 소규모 환경에선 마스터와 노드를 분리하지 않고 같은 서버에 구성하기도 한다. 마스터 서버는 다양한 모듈이 확장성을 고려하여 기능별로 쪼개져 있으며, 크게 API서버, 스케쥴러, 컨트롤러 매니저, etcd로 구성되어 있다.
1-1. API서버(kube-apiserver)
쿠버네티스는 모든 명령과 통신을 API를 통해서 하는데, 그 중심이 되는 서버가 API서버이다. 쿠버네티스의 모든 기능들을 REST API로 제공하고 그에 대한 명령을 처리한다. kubectl의 요청 뿐 아니라 내부 모듈의 요청도 처리하며 권한을 체크하여 요청을 거부할 수 있다. 노드에서 실행중인 컨테이너의 로그를 보여주고 명령을 보내는 등 디버거 역할도 수행한다.
1-2. etcd
API서버가 명령을 주고 받는 서버라면, etcd는 쿠버네티스 클러스터의 데이터베이스 역할을 하는 서버로 RAFT 알고리즘을 이용한 key-value 저장소이다. 여러개로 분산하여 복제할 수 있기 때문에 안전성이 높고 속도가 빠르다. 단순히 값을 저장하고 읽는 기능 뿐 아니라 watch 기능이 있어 어떤 상태가 변경되면 바로 체크하여 로직을 실행할 수 있다.
클러스터의 모든 설정, 상태 데이터는 여기 저장되고 나머지 모듈은 stateless하게 동작하기 때문에 etcd만 잘 백업해두면 언제든지 클러스터를 복구할 수 있다. etcd는 오직 API서버와 통신하고 다른 모듈은 API서버를 거쳐 etcd데이터에 접근한다.
1-3. 스케쥴러(kube-scheduler)
스케쥴러는 Pod, 서비스 등 각 리소스들을 적절한 노드에 할당하는 역할을 한다.
1-4. 컨트롤러 매니저(kube-controller-manager)
컨트롤러 매니저는 컨트롤러(Replica Controller, Service Controller, Volume Controller, Node Controller 등)를 생성하고 이를 각 노드에 배포하며 이를 관리하는 역할을 한다.
1-5. DNS(coreDNS)
쿠버네티스는 리소스의 엔드포인트(EndPoint)를 DNS로 맵핑하고 관리한다. Pod나 서비스 등은 IP를 배정받지만 동적으로 생성되는 리소스이므로 컨테이너 기동/삭제에 따라 IP주소가 변경되기 때문에, 그 리소스에 대한 위치정보가 필요하다. 때문에 쿠버네티스에서는 내부 위치정보를 DNS 서버를 두고 관리한다. 새로운 리소스가 생기면 그 리소스에 대한 IP와 DNS 이름을 등록하여, DNS 이름 기반으로 리소스에 접근할 수 있도록 한다.
2. 노드(Kubernetes Node)
쿠버네티스 노드(Kubernetes Node)는 마스터에 의해 명령을 받고 실제 워크로드를 생성하여 서비스 하는 컴포넌트이다. 실제 컨테이너들이 생성되는 곳으로 수백, 수천대로 확장할 수 있다. 각각의 서버에 라벨을 붙여 사용 목적(GPU 특화, SSD 서버)을 정의할 수 있다. 노드에는 Kubelet, Kube-proxy, cAdvisor 그리고 컨테이너 런타임이 배포된다.
2-1. Kubelet
노드에 배포되는 에이전트로, 마스터의 API서버와 통신을 하면서, 노드가 수행해야 할 명령을 받아서 수행하고, 반대로 노드의 상태 등을 마스터로 전달하는 역할을 한다.
2-2. Kube-proxy
노드로 들어오는 네트워크 트래픽을 적절한 컨테이너로 라우팅하고, 로드밸런싱 등 노드로 들어오고 나가는 네트워크 트래픽을 프록시하고, 노드와 마스터간의 네트워크 통신을 관리한다.
2-3. Container runtime(컨테이너 런타임)
Pod를 통해서 배포된 컨테이너를 실행하는 컨테이너 런타임이다. 컨테이너 런타임은 보통 도커 컨테이너를 생각하기 쉬운데, 도커 이외에도 rkt(보안이 강화된 컨테이너), Hyper container 등 다양한 런타임이 존재한다.
2-4. cAdvisor
cAdvisor는 각 노드에서 기동되는 모니터링 에이전트로, 노드에서 기동되는 컨테이너들의 상태와 성능 등의 정보를 수집하여, 마스터 서버의 API 서버로 전달한다. 이 데이터는 주로 모니터링을 위해 사용된다.
3. 애드온(Addons)
애드온은 클러스터 내부에서 필요한 기능들을 위해 실행되는 포드들이다. 애드온에 사용되는 포드들은 디플로이먼트, 리플리케이션컨트롤러등에 의해 관리된다. 애드온에 사용되는 네임스페이스는 kube-system이다. 애드온에는 몇가지 종류가 있다.
3-1. 네트워킹 에드온
쿠버네티스는 클러스터 내부에서 가상 네트워크를 구성해서 사용하는데, 이때 kube-proxy 이외에 네트워킹 관련한 애드온을 사용한다. AWS, Azure, GCP 같은 클라우드 서비스에서 제공하는 쿠버네티스를 사용한다면 별도의 네트워킹 애드온을 사용하지 않더라도 각 클라우드 벤더에서 구현하고 있으니 신경쓰지 않아도 된다. 하지만 쿠버네티스를 직접 보유중인 서버들에 설치해서 구성을 하려면 네트워킹 관련 애드온을 설치해서 사용해야한다. 네트워킹 애드온의 종류는 ACI, Calico, Cilium, CNI-Genie, Contiv, Flannel, Weave Net 등이 있고, OCI의 CNI(Container Network Interface)를 구현하고 있다면 다른 애드온들도 사용할 수 있다.
3-2. DNS 애드온
DNS 애드온으이 경우 실제로 클러스터 내에서 작동하는 DNS서버이다. 쿠버네티스 서버들에 DNS 레코드를 제공하는 역할을 한다. 쿠버네티스 내부에서 실행된 컨테이너들은 자동으로 DNS서버에 등록된다. DNS 서비스로는 kube-dns와 core-dns가 있다.
3-3. 대시보드 애드온
쿠버네티스를 사용할 때 대부분 kubectl이라는 CLI(command Line Interface)를 많이 사용한다. 하지만 웹 UI가 필요한 경우 사용할 수 있는 대시보드가 있다.
3-4. 컨테이너 자원 모니터링
클러스터 내부에서 실행중인 컨테이너의 상태를 모니터링 하기 위해서는 cpu, 메모리 같은 필요한 메트릭 데이터를 시계열형식으로 저장하고 볼수 있는 방법을 제공하는데 필요한 애드온이다. kubelet안에 cAdvisor라는 컨테이너 모니터링 도구가 포함되어 있으며, 이 데이터들을 수집해서 사용할 수 있는 힙스터(heapster)를 이용하면 손쉽게 필요한 데이터들을 수집해서 모니터링에 이용할 수 있다.
3-5. 클러스터 로깅
클러스터 내의 각 개별 컨테이너에서 나오는 로그와 쿠버네티스 구성요소들에서 나오는 로그들을 중앙화된 로그 수집 시스템에서 모아서 볼 수 있다. 이것 역시 클라우드 서비스를 이용중이라면 각 클라우드 벤더에서 제공해주는 로깅 서비스들과 잘 연동이 되어 있겠지만, 직접 쿠버네티스를 설치해서 사용할 때는 고려해야 할 요소다. 클러스터 내 각 노드에 로그를 수집하는 포드를 실행해서 한곳으로 로그를 수집해야 하며, 로그를 수집해서 제공해주는 역할로는 ELK(ElasticSearch, Logstash, Kibana)를 많이 사용한다.
참고
https://en.wikipedia.org/wiki/Kubernetes
https://bcho.tistory.com/1258?category=731548
https://subicura.com/2019/05/19/kubernetes-basic-1.html
https://arisu1000.tistory.com/27828