Container Orchestration
Container Orchestration 이란 복잡한 컨테이너 환경을 효과적으로 관리하기 위한 도구로 K8s 가 주로 쓰인다.
- Cluster = Master Node 가 중앙제어, 다수의 Worker Node 가 클러스터를 이루어 서로 통신하며 작동
- State = Desired State 선언 시 관리자의 개입 없이 자동으로 상태를 유지
- Scheduling = Container 를 배치할 적합한 Worker Node 를 찾아 배포
- Rollout Rollback = 배포 버전관리
- Service Discovery = 서비스 등록 및 조회
- Volume = NFS, EBS 등 다양한 스토리지 마운팅
K8s Architecture
K8s 는 Master Node 와 Worker Node 의 집합으로 이루어진다.
Master Node 는 Worker Node 들을 Manage, Plan, Schedule, Monitor 하는 역할을 수행하기 위해 아래와 같은 Component 들을 가진다.
- kube-apiserver
- controller manager
- etcd cluster
- kube-scheduler
Worker Node 는 Containerized Application 이 실행되는 Node 로, 이를 위해 아래와 같은 Component 들을 가진다.
- Container Runtime
- kubelet
- kube-proxy
Docker vs containerd
- 2013년 Docker 출현으로 인한 컨테이너 기술 부상 이후 타 경쟁사 역시 각자 Container Runtime 을 개발하기 시작했고 이로 인해 표준화가 필요해졌다. 2016년 Docker 와 CoreOS 가 주축으로
imagespec과runtimespec등을 포함한 Open Container Initiative, OCI 를 출범하여 Container Runtime 의 표준화를 재정했다. 이후 OCI 스펙에 맞춰 각 기업들이 Container Runtime 을 발전시켰고, Docker 의 경우 OCI 표준에 맞춰 개발한 Container Runtime 이runc이다. - K8s 의 경우 초창기엔 Docker 만을 유일한 Container Runtime 으로 지원했었는데, OCI 등장 이후 다양한 Container Runtime 들이 등장하면서 각 Container Runtime 에 따라
kubelet이 관리해야 하는 방법을 따로 유지보수해야하는 어려움이 발생하기 시작했다. 이런kubelet유지보수 문제를 해결하면서 동시에 다양한 Container Runtime 들을 지원하기 위해kubelet에서 Container Runtime 을 관리할 수 있는 인터페이스인 Container Runtime Interface, CRI 가 등장하게된다. - 초창기 Docker 는 monolithic 한 구조로 Docker Daemon 하나에서 Docker Client, Docker API, Container Runtime, Image Build 등을 포함하고 있었고, 이는
kubelet이 Docker 의 Container Runtime 을 사용할 때 CRI 표준에 부합하는dockershim이라는 컴포넌트를 추가적으로 사용해야했다. - 이후 K8s 의
dockershim지원이 중지되고,containerd가 Docker 에서 분리되면서, CRI 스펙에 맞추기 위한cri plugin등을containerd내부적으로 추가하여containerd도kubelet에 의해 관리될 수 있게되었다. runc가 컨테이너를 실행하는 실질적인 주체라면,containerd는 한 단계 위에서 이미지 저장, 네트워킹, 스냅샷 및 기타 관리 작업 등의 기능들을 포함한 고수준의 Container Runtime 으로, 내부적으로runc를 사용하기에 OCI 와 CRI 표준을 모두 준수할 수 있는 Container Runtime 이 된 것이다.- We can use the 2 CLIs below instead of Docker to work with K8s
nerdctl= for general purpose from thecontainerdcommunitycrictl= for debugging from the K8s community (works with all CRI-compatible container runtimes)
ETCD
- ETCD is a distributed reliable key-value store that is Simple, Secure & Fast
- K8s 의 모든 상태와 데이터를 저장
- Key-Value 형태로 데이터를 저장
- 분산 시스템으로 구성하여 고가용성 확보
- TTL, watch 등 부가 기능 제공
Kube-API Server
- 상태를 바꾸거나 조회
- etcd 와 유일하게 통신하는 모듈
- REST API 형태로 제공
- 요청에 대한 권한 체크
- 수평적 확장 가능
- kubeadm 으로 설치할 경우 Pod 의 형태로 실행된다.
- Authenticate User
- Validate Request
- Retrieve data
- Update ETCD
- Scheduler
- Kubelet
Kube Controller Manager
- 다양한 Controller 가 존재
- A
controlleris aprocessthat continuously monitors the state of the components within the system and works towards bringing the whole system to the desired functioning state - Replication Controller, Node Controller, Endpoint Controller, …
- 끊임 없이 상태를 체크하고 원하는 상태를 유지
- 복잡성을 낮추기 위해 하나의 프로세스로 실행
- A
Installing Kube Controller Manager
wget https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-controller-manager
- kubeadm 으로 설치할 경우 Pod 의 형태로 실행된다.
Kube Scheduler
- kube-scheduler 는 생성 요청된 Pod 가 어느 Node 에 배포되어야 하는지 확인하는 역할을 수행한다. Node 의 현재 상태와 Pod 의 요구사항을 체크하여 적절한 Node 를 찾는 작업만 수행할 뿐 Pod 를 생성하는 역할은 kubelet 이 수행한다.
How does it work?
- Pod 에 필요한 리소스를 여분으로 가지고 있는 Node 를 확인하고 Pod 가 배치된 후 남은 리소스량을 기준으로 순위를 매겨 스케쥴링을 수행한다.
Installing Kube Scheduler
wget https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-scheduler
- kubeadm 으로 설치할 경우 Pod 의 형태로 실행된다.
Kubelet
kubelet 은 Master Node 의 kube-apiserver 로 부터 Container 생성 요청을 받아 Worker Node 에 설치된 Container Runtime 을 이용해 Container 를 생성하는 역할을 한다. kubelet 은 자신이 위치한 Node 와 생성한 Pod 들을 모니터링하여 주기적으로 kube-apiserver 와 소통한다.
Installing Kubelet
wget https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubelet
kubeadm 으로 K8s Cluster 를 구축할 때 kubelet 은 설치되지 않으니 수동으로 Worker Node 에 kubelet 을 설치해주어야 한다. 때문에 kubelet 은 다른 Component 들과 다르게 Pod 이 아닌 Node 의 프로세스로서 실행된다.
Kube Proxy
- 네트워크 프록시와 부하 분산 역할을 하며 K8s Cluster 에 배포된 모든 Pod 간의 통신을 담당한다.
- 각 Node 에서 Pod 형태로 실행되기 때문에 kubectl get pods 로 조회 가능하다.
- Service 와 EndpointSlice 의 변경을 감시한다.
- 성능상의 이유로 별도의 프록시 프로그램 대신 iptables / IPVS / eBPF 등을 사용하여 트래픽 라우팅 설정만 관리한다.