2023. 4. 10. 17:00ㆍDevops/Kubernetes
컨테이너 인프라 환경
리눅스 OS 커널 하나에서 여러 개의 컨테이너가 격리된 상태로 실행되는 인프라 환경을 말한다. 여기서 컨테이너는 하나 이상의 목적을 위해 독립적으로 작동하는 프로세스이다. 컨테이너 인프라 환경을 구성하면 눈송이 서버를 방지하는 데 효과적이다.
💡 눈송이 서버란 여러 사람이 만져서 설정의 일관성이 떨어진 서버를 말한다.
가상화 환경에서는 각각의 가상 머신이 모두 독립적인 OS 커널을 가지고 있기 때문에 그만큼 자원을 더 소모해야 하고 성능이 낮아질 수밖에 없다. 하지만 컨테이너 환경은 OS 커널 하나에 컨테이너 여러 개가 격리된 형태로 실행되기 때문에 자원을 효율적으로 사용할 수 있고 거치는 단계가 적어 속도도 훨씬 빠르다. 컨테이너 인프라 환경에서 쿠버네티스가 사실상 표준으로 자리하고 있다.
구성 요소 - 파드 배포 중심
관리자나 개발자가 파드를 배포할 경우
마스터 노드
- kubectl
- 쿠버네티스 클러스터에 명령을 내리는 역할을 수행함
- 다른 구성 요소들과 달리 바이너리로 배포되기 때문에 마스터 노드에 있을 필요 x
- 통상적으로 API 서버와 주로 통신
- API 서버
- 쿠버네티스 클러스터의 중심 역할을 하는 통로
- 주로 상태 값을 저장하는 etcd와 통신하지만 그 밖의 요소들 또한 API 서버를 중심에 두고 통신하므로 매우 중요한 역할을 수행
- 관리자 역할
- etcd
- 구성 요소들의 상태 값이 모두 저장되는 곳
- 관리자가 모든 보고 내용을 기록하는 노트
- etcd 외의 다른 구성 요소는 상태 값을 관리하지 않음
- → etcd에 정보만 백업돼 있다면 장애 상황 시 복구 가능
- 분산 저장이 가능한 key-value 저장소
- → 복제하여 여러 곳에 저장해두면 하나의 etcd에서 장애가 나더라도 가용성 확보 가능
- 컨트롤러 매니저
- 쿠버네티스 클러스터의 오브젝트 상태를 관리함
- 워커 노드와 통신이 되지 않는 경우 상태 체크와 복구는 컨트롤러 매니저에 속한 노드 컨트롤러에서 이루어짐
- 레플리카셋 컨트롤러는 레플리카셋에 요청받은 파드 개수대로 파드 생성
- → 다양한 상태 값을 관리하는 주체들이 컨트롤러 매니저에 소속돼 각자의 역할 수행
- 쿠버네티스 클러스터의 오브젝트 상태를 관리함
- 스케줄러
- 노드의 상태와 자원, 레이블, 요구 조건 등을 고려해 파드를 어떤 워커 노드에 생성할 것인지 결정하고 할당함
워커 노드
- kubelet
- 파드의 구성 내용(PodSpec)을 받아서 컨테이너 런타임으로 전달하고, 파드 안의 컨테이너들이 정상적으로 작동하는지 모니터링함
- 컨테이너 런타임(CRI, Container Runtime Interface)
- 파드를 이루는 컨테이너의 실행을 담당함
- 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 만드는 표준 인터페이스
- 파드(Pod)
- 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해 모인 단위
- 하나의 파드는 웹 서버 역할, 로그 수집 및 데이터 분석을 수행할 수도 있음
- 언제라도 죽을 수 있는 존재
- 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해 모인 단위
선택 가능한 구성 요소
- 네트워크 플러그인
- 쿠버네티스 클러스터의 통신을 위해서 구성해야 하는 플러그인
- 일반적으로 CNI로 구성함
- 캘리코, 플래널, 실리움 등
- CoreDNS
- 클라우드 네이티브 컴퓨팅 재단에서 보증하는 프로젝트
- 빠르고 유연한 DNS 서버
- 실무에서 쿠버네티스 클러스터를 구성하여 사용할 때 IP보다 도메인 네임을 편리하게 관리하기 위해 사용
💡 CNI(Container Network Interface)는 클라우드 네이티브 컴퓨팅 재단의 프로젝트로, 컨테이너의 네트워크 안정성과 확장성을 보장하기 위해 개발됐다. CNI에 사용할 수 있는 네트워크 플러그인은 다양한데, 구성 방식과 지원하는 기능, 성능이 각기 다르므로 사용 목적에 맞게 선택할 수 있다. 예를 들어 캘리코는 L3로 컨테이너 네트워크를 구성하고, 플레널은 L2로 컨테이너 네트워크를 구성한다. 또한 네트워크 프로토콜, 보안 기능 제공 등을 살펴보고 선택할 수 있어 설계 유연성이 매우 높다.
사용자가 배포된 파드에 접속할 때
- kube-proxy
- 쿠버네티스 클러스터는 파드가 위치한 노드에 kube-proxy를 통해 파드가 통신할 수 있는 네트워크를 설정함
- 이때 실제 통신은 br_netfilter와 iptables로 관리함
- 파드
- 이미 배포된 파드에 접속하고 필요한 내용을 전달받음
- 대부분의 사용자는 파드가 어느 워커 노드에 위치하는지 신경쓰지 않아도 됨
구성 요소 - 파드 생명주기
쿠버네티스의 가장 큰 장점은 쿠버네티스의 구성 요소마다 하는 일이 명확하게 구분돼 각자의 역할만 충실하게 수행하면 클러스터 시스템이 안정적으로 운영된다는 점이다. 이는 MSA 구조와도 밀접하게 연관된다. 명확한 역할이 나뉘어 있어서 문제가 발생했을 때 어느 부분에서 문제가 발생했는지 디버깅하기 쉽다.
파드의 생명 주기
- kubectl을 통해 API 서버에 파드 생성을 요청한다.
- (업데이트가 있을 때마다) API 서버에 전달된 내용이 있으면 API 서버는 etcd에 전달된 내용을 모두 기록해 클러스터의 상태 값을 최신으로 유지한다. 따라서 각 요소가 상태를 업데이트할 때마다 모두 API 서버를 통해 etcd에 기록된다.
- API 서버에 파드 생성이 요청된 것을 컨트롤러 매니저가 인지하면 컨트롤러 매니저는 파드를 생성하고, 이 상태를 API 서버에 전달한다. 참고로 아직 어떤 워커 노드에 파드를 적용할지는 결정되지 않은 상태로 파드만 생성한다.
- API 서버에 파드가 생성됐다는 정보를 스케줄러가 인지한다. 스케줄러는 생성된 파드를 어떤 워커 노드에 적용할지 조건을 고려해 결정하고 해당 워커 노드에 파드를 띄우도록 요청한다.
- API 서버에 전달된 정보대로 지정한 워커 노드에 파드가 속해 있는지 스케줄러가 kubelet으로 확인한다.
- kubelet에서 컨테이너 런타임으로 파드 생성을 요청한다.
- 파드가 생성된다.
- 파드가 사용 가능한 상태가 된다.
쿠버네티스 구조
쿠버네티스는 작업을 순서대로 진행하는 워크플로 구조가 아니라 선언적인(declarative) 시스템 구조를 가지고 있다. 즉, 각 요소가 추구하는 상태(desire status)를 선언하면 현재 상태(current status)와 맞는지 점검하고 그것에 맞추려고 노력하는 구조로 돼 있다.
따라서 추구하는 상태를 API 서버에 선언하면 다른 요소들이 API 서버에 와서 현재 상태와 비교하고 그에 맞게 상태를 변경하려고 한다. 여기서 API는 현재 상태 값을 가지고 있는데, 이것을 보존해야 해서 etcd가 필요하다. API 서버와 etcd는 거의 한몸처럼 움직이도록 설계되었다.
다만 워커 노드는 워크플로 구조에 따라 설계됐다. 쿠버네티스가 kubelet과 컨테이너 런타임을 통해 파드를 새로 생성하고 제거해야 하는 구조라서 선언적인 방식으로 구조화하기에 어렵기 때문이다. 또한 명령이 절차적으로 전달되는 방식은 시스템 효율을 높이는 데 효율적이다. 하지만 마스터 노드는 이미 생성된 파드들을 유기적으로 연결하므로 쿠버네티스 클러스터를 안정적으로 유지하려면 선언적인 시스템이 유리하다.
쿠버네티스 기본 사용법 배우기
파드 생성 방법
- run
kubectl run nginx-pod --image=nginx
- create
kubectl create deployment nginx-pod --image=nginx
- 차이점
- run - 단일 파드로 생성된다.
- create - 디플로이먼트라는 그룹 내에서 파드가 생성된다.
오브젝트
쿠버네티스를 사용하는 관점에서 파드와 디플로이먼트는 스펙과 상태 등의 값을 가지고 있다. 이러한 값을 가지고 있는 파드와 디플로이먼트를 개별 속성을 포함해 부르는 단위를 오브젝트라고 한다. 쿠버네티스는 여러 유형의 오브젝트를 제공한다.
기본 오브젝트
- 파드
- 쿠버네티스에서 실행되는 최소 단위
- 독립적인 공간과 사용 가능한 IP를 가지고 있음
- 하나의 파드는 1개 이상의 컨테이너를 갖고 있기 때문에 여러 기능을 묶어 하나의 목적으로 사용할 수 있음
- 범용으로 사용할 땐 1개의 파드에 1개의 컨테이너를 적용함
- 네임스페이스
- 쿠버네티스 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹
- 기본적으로 할당되는 네임스페이스
- default - 기본으로 할당됨
- kube-system - 쿠버네티스 시스템에서 사용됨
- metallb-system - 온프레미스에서 쿠버네티스를 사용할 경우 외부에서 쿠버네티스 클러스터 내부로 접속하게 해주는 컨테이너들이 속해 있음
- 볼륨
- 파드 생성 시 파드에서 사용할 수 있는 디렉터리를 제공함
- 기본적으로 파드는 영속되는 개념이 아니라 제공되는 디렉터리도 임시로 사용함
- 파드가 사라지더라도 저장, 보존이 가능한 디렉터리를 볼륨 오프젝트를 통해 생성하고 사용할 수 있음
- 서비스
- 쿠버네티스 외부에서 쿠버네티스 내부로 접속할 때 어떤 구조로 돼있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연결하는 것
디플로이먼트
기본 오브젝트만으로도 쿠버네티스를 사용할 수 있지만 한계가 있어 이를 좀 더 효율적으로 작동하도록 기능들을 조합하고 추가해 구현한 것이 디플로이먼트이다. 이 외에도 데몬셋, 컨피그맵, 레플리카셋 등이 있으며 앞으로도 계속 추가될 것이다.