쿠버네티스 기본 개념
쿠버네티스란?
컨테이너는 가상 머신과 비교해 가볍고 빠르다는 장점이 있었지만, 운영 환경에서 사용하기 위해서는 다수의 컨테이너가 동시에 실행되고, 관리되어야 하는 등 그 자체로는 부족함이 많았습니다.
그래서 컨테이너 오케스트레이션이 등장했고 컨테이너가 서로 조화롭게 합주하는 오케스트라처럼 비즈니스 요구사항을 처리할 수 있게 되었습니다.
오늘에 이르기까지 여러 컨테이너 오케스트레이션이 등장했지만, 그 중에서도 구글 내부에서 사용하던 컨테이너 오케스트레이션인 보그가 OSS로 공개되며 선도하게 되었고, 이 보그는 쿠버네티스란 새로운 이름으로 우리에게 사용되고 있습니다.
쿠버네티스 특징
- 선언적 API
컨테이너가 어떤 상태이길 원하는지 쿠버네티스에 설정하면 지속해서 컨테이너의 상태를 확인한다. 그리고 설정한 상태가 아니라면 그것에 맞게 맞춘다는 개념입니다.
출처: https://www.leverege.com/iot-ebook/kubernetes-object-management-model
예를 들어, 어떤 앱으로 컨테이너를 항상 10개가 실행되길 원해서 설정하면, 쿠버네티스가 지켜보다가 장애나 기타 요인으로 인해 10개 미만으로 내려가면 자동으로 실행해 컨테이너의 수를 일정하게 유지시켜줍니다.
이러한 특성으로 인해 컴포넌트를 여러 개 실행해둘 수 있으므로 단일 장애점(Single Point of Failure, SPOF)가 없습니다.
그래서 컨테이너가 몇개가 실행되어야 한다거나 앱이 없어야 할 때는 설정하기 쉬운 반면에, 앱 재시작 같은 단순한 작업은 쿠버네티스에서 할 수 없습니다.
- 워크로드 분리
쿠버내티스를 사용하면 분산 시스템을 개발하고 어떻게 실행할지에 관한 고민을 많이 덜어줍니다. 예를 들어, 분산된 프로세스 각각이 잘 실행되는지, 이상이 생겼을 때는 어떻게 처리해야 하는지 등 시스템 안전성에 관한 고민을 많이 해야 합니다. 이떄 쿠버네티스는 운영체제처럼 분산된 프로세스의 관리를 추상화는 레이어가 되므로 시스템 운영에 관한 고민을 많이 덜어줍니다.
쿠버네티스 클러스터 관리
kubectl 이란
쿠버네티스 클러스터를 관리하는 동작 대부분은 kubectl 이라는 커맨드라인 인터페이스로 실행할 수 있습니다. kubectl에서 지원하는 명령어는 아래와 같습니다.
- 쿠버네티스 자원들의 생성, 업데이트, 삭제 (create, update, delete)
- 디버그, 모니터링, 트러블 슈팅 (log, exec, cp, top attach, ...)
- 클러스터 관리 (cordon, top, drain, taint)
이외에도 수 많은 기능이 있는데, 그외 세부 내용은 쿠버네티스 공식 문서인 Kubectl Cheat Sheet 를 참고하세요.
kubectl 기본 사용법
kubectl은 다음 형식으로 명령을 작성합니다.
kubectl [command] [TYPE] [NAME] flags
- command: 자원에 실행하려는 동작.
- TYPE: 자원 타입. pod, service, daemonset, statefulset, ...
- NAME: 자원이 이름.
- FLAG: 부가적으로 사용할 옵션.
kubeconfig 환경변수
kubectl은 기본적으로 $HOME/.kube/config 파일에서 클러스터, 인증, 컨텍스트 정보를 읽어드립니다. 이러한 클러스터 구성정보를 kubeconfig 라고 칭합니다. 클러스터에서 사용할 수 있는 자원들은 kubectl api-resources 에서 확인 할 수 있습니다.
노드
노드 란?
쿠버네티스 클러스터를 구성하는 서버를 뜻 합니다. 여기서 서버는 물리/가상 서버를 구분하지 않습니다.
노드의 종류
- 마스터: 클러스터를 관리하는 노드. 모자 쓰고 채찍든 사람.
- 워커 노드: 실제 컨테이너를 실행시키는 노드. 짐든 사람.
노드 컴포넌트의 종류
컨트롤 플레인 컴포넌트
먼저 컨트롤 플레인에 대해 알아보자면, 컨테이너의 라이프사이클을 정의, 배포, 관리하기 위한 API와 인터페이스들을 노출하는 컨테이너 오케스트레이션 레이어입니다.
컨트롤 플레인 컴포넌트는 클러스터에 관한 전반적인 결정(예를 들어, 스케줄링)을 수행하고 클러스터 이벤트(예를 들어, 디플로이먼트의 replicas 필드에 대한 요구 조건이 충족되지 않을 경우 새로운 파드를 구동시키는 것)를 감지하고 반응합니다.
컨트롤 플레인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작할 수 있습니다. 그러나 간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고, 사용자 컨테이너는 해당 머신 상에 동작시키지 않습니다. 다중-마스터-VM 설치 예제를 보려면 고가용성 클러스터 구성하기를 확인해보시기 바랍니다.
kube-apiserver
API 서버는 쿠버네티스 API를 노출하는 쿠버네티스 컨트롤 플레인 컴포넌트입니다. API 서버는 쿠버네티스 컨트롤 플레인의 프론트 엔드입니다.
CLI 외에도 REST API로도 쿠버네티스와 사용자 간에 통신이 가능합니다.
쿠버네티스 API 서버의 주요 구현은 kube-apiserver 입니다. kube-apiserver는 수평으로 확장되도록 디자인되었습니다. 즉, 더 많은 인스턴스를 배포해서 확장할 수 있습니다. 여러 kube-apiserver 인스턴스를 실행하고, 인스턴스간의 트래픽을 균형있게 조절할 수 있습니다.
kube-apiserver는 요청을 받으면 요청에 사용된 토큰이 해당 네임스페이스와 자원을 대상으로 요청을 실행할 권리가 있는지 검사하고 권한이 있다면 요청에 대한 결과를 반환해줍니다.
etcd
모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성·고가용성 키-값 저장소.
쿠버네티스 클러스터에서 etcd를 뒷단의 저장소로 사용한다면, 이 데이터를 백업하는 계획은 필수입니다.
etcd는 서버 하나당 프로세스 1개만 사용할 수 있습니다. 보통 etcd 자체를 클러스티링한 후 여러 개 마스터 서버에 분산해서 실행해 데이텅의 안전성을 보장하도록 구성합니다. 그 외에도 안정적인 운영을 위해 백업을 할 것을 권장합니다.
etcd에 대한 자세한 정보는, 공식 문서를 참고한다.
kube-scheduler
노드가 배정되지 않은 새로 생성된 파드 를 감지하고, 실행할 노드를 선택하는 컨트롤 플레인 컴포넌트입니다..
스케줄링 결정을 위해서 고려되는 요소는 리소스에 대한 개별 및 총체적 요구 사항, 하드웨어/소프트웨어/정책적 제약, 어피니티(affinity) 및 안티-어피니티(anti-affinity) 명세, 데이터 지역성, 워크로드-간 간섭, 데드라인을 포함합니다.
kube-controller-manager
컨트롤러를 구동하는 마스터 상의 컴포넌트.
논리적으로, 각 컨트롤러는 개별 프로세스이지만, 복잡성을 낮추기 위해 모두 단일 바이너리로 컴파일되고 단일 프로세스 내에서 실행됩니다.
kube-controller-manager는 컨트롤러 각각을 실행하는 컴포넌트 입니다. 쿠버네티스는 Go 언어로 개발되었는데, 클러스터 안에서 새로운 컨트롤러를 사용할 때는 컨트롤러에 해당하는 구조체를 만듭니다.이 구조체는 kube-controller-manager가 관리하는 큐에 넣어서 실행하는 방식으로 동작합니다.
이들 컨트롤러는 다음을 포함합니다.
- 노드 컨트롤러: 노드가 다운되었을 때 통지와 대응에 관한 책임을 가집니다.
- 레플리케이션 컨트롤러: 시스템의 모든 레플리케이션 컨트롤러 오브젝트에 대해 알맞은 수의 파드들을 유지시켜 주는 책임을 가집니다.
- 엔드포인트 컨트롤러: 엔드포인트 오브젝트를 채웁니다(즉, 서비스와 파드를 연결시킵니다.)
- 서비스 어카운트 & 토큰 컨트롤러: 새로운 네임스페이스에 대한 기본 계정과 API 접근 토큰을 생성합니다.
cloud-controller-manager
cloud-controller-manager는 클라우드 제공자 전용 컨트롤러만 실행합니다. 자신의 사내 또는 PC 내부의 학습 환경에서 쿠버네티스를 실행 중인 경우 클러스터에는 클라우드 컨트롤러 매니저가 없습니다.
kube-controller-manager와 마찬가지로 cloud-controller-manager는 논리적으로 독립적인 여러 컨트롤 루프를 단일 프로세스로 실행하는 단일 바이너리로 결합합니다. 수평으로 확장(두 개 이상의 복제 실행)해서 성능을 향상시키거나 장애를 견딜 수 있습니다.
다음 컨트롤러들은 클라우드 제공 사업자의 의존성을 가질 수 있습니다.
- 노드 컨트롤러: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공 사업자에게 확인하는 것
- 라우트 컨트롤러: 기본 클라우드 인프라에 경로를 구성하는 것
- 서비스 컨트롤러: 클라우드 제공 사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
노드 컴포넌트
노드 컴포넌트는 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작합니다.
kubelet
클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리합니다.
Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 합니다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않습니다.
kube-proxy
kube-proxy는 클러스터의 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스의 서비스 개념의 구현부입니다.
kube-proxy는 노드의 네트워크 규칙을 유지 관리합니다. 이 네트워크 규칙이 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 해줍니다.
kube-proxy는 운영 체제에 가용한 패킷 필터링 계층이 있는 경우, 이를 사용합니다. 그렇지 않으면, kube-proxy는 트래픽 자체를 포워드(forward)합니다.
컨테이너 런타임
컨테이너 런타임은 컨테이너 실행을 담당하는 소프트웨어입니다.
쿠버네티스는 여러 컨테이너 런타임을 지원합니다. 도커(Docker), containerd, CRI-O 그리고 Kubernetes CRI (컨테이너 런타임 인터페이스)를 구현한 모든 소프트웨어.
애드온
애드온은 쿠버네티스 리소스(데몬셋, 디플로이먼트 등)를 이용하여 클러스터 기능을 구현합니다. 이들은 클러스터 단위의 기능을 제공하기 때문에 애드온에 대한 네임스페이스 리소스는 kube-system 네임스페이스에 합니다.
선택된 일부 애드온은 아래에 설명하였고, 사용 가능한 전체 확장 애드온 리스트는 애드온을 참조합니다.
DNS
여타 애드온들이 절대적으로 요구되지 않지만, 많은 예시에서 필요로 하기 때문에 모든 쿠버네티스 클러스터는 클러스터 DNS를 갖추어야만 합니다.
클러스터 DNS는 구성환경 내 다른 DNS 서버와 더불어, 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주는 DNS 서버입니다.
쿠버네티스에 의해 구동되는 컨테이너는 DNS 검색에서 이 DNS 서버를 자동으로 포함합니다.
웹 UI (대시보드)
대시보드는 쿠버네티스 클러스터를 위한 범용의 웹 기반 UI다. 사용자가 클러스터 자체뿐만 아니라, 클러스터에서 동작하는 애플리케이션에 대한 관리와 문제 해결을 할 수 있도록 해줍니다.
컨테이너 리소스 모니터링
컨테이너 리소스 모니터링은 중앙 데이터베이스 내의 컨테이너들에 대한 포괄적인 시계열 매트릭스를 기록하고 그 데이터를 열람하기 위한 UI를 제공해 줍니다.
kublet에 안에 포함된 cAdvisor라는 컨테이너 모니터링 도구를 사용합니다. cAdvisor에서는 자원 사용량 데이터를 수집하는 메트릭 서버를 손쉽게 모니터링에 사용합니다.
https://www.8bitmen.com/what-is-cadvisor-how-does-it-work-explained/
클러스터-레벨 로깅
클러스터-레벨 로깅 메커니즘은 검색/열람 인터페이스와 함께 중앙 로그 저장소에 컨테이너 로그를 저장하는 책임을 집니다.
파드
쿠버네티스는 파드라는 단위로 컨테이너를 묶어서 관리하므로 컨테이너 하나가 아닌 여러 개 컨테이너로 구성됩니다.
파드로 컨테이너 여러 개를 한꺼번에 관리할 때는 컨테이너마다 역할을 부여할 수 있습니다. 파드 하나에 속한 컨테이너들은 모두 노드 하나안에서 실행 됩니다. 여러 노드에 흩여져서 실행되는 일은 없습니다. 파드의 역할 중 하나가 컨테이너 들이 같은 목적으로 자원을 공유하는 것이므로 가능한 일입니다.
아래 사진을 보면 jordy-web-svr라는 파드가 웹서버/로그수집기/볼륨컨테이너랑 각각의 역할을 가진 컨테이너로 구성되있는 것을 알 수 있습니다.
4개의 컨테이너는 192.158.120.30란 아이피를 함께 사용하고 컨테이너간 통신을 할 때는 로컬호스트를 사용해서 통신을 합니다.
ex ) 웹서버 → 로그 수집기: localhost:30210 사용
ex 2) 로그 수집기 → 볼륨 컨테이너: localhost:40000 사용
추가적으로 pause는 파드 인프라 컨테이너라고 합니다. pause는 파드 안 기본 네트워크로 실행되며, 프로세스 식별자가 1(PID 1)로 설정되므로 다른 컨테이너의 부모 컨테이너 역할을 합니다. 파드 안 다른 컨테이너는 pause 컨테이너가 제공하는 네트워크를 공유해서 사용합니다. 그래서 파드 안 다른 컨테이너가 재시작됐을 때는 파드의 IP를 유지하지만, pause 컨테이너가 재시작되면 파드 안 모든 컨테이너도 재시작 합니다.
'Infra & DevOps > Kubernetes' 카테고리의 다른 글
ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables 오류 (0) | 2020.06.16 |
---|---|
[퍼온 글] 쿠버네티스 노드 조인(Join)시 Token 값 확인 (0) | 2020.06.15 |
쿠버네티스 설치 방법 (0) | 2020.06.14 |
[오리뎅이] 쿠버네티스 네트워킹 (0) | 2020.04.20 |