사전 Kubernetes
구현체

Kubernetes

gabury1

쿠버네티스는 여러 대의 컴퓨터를 묶어 컨테이너를 대신 띄워 주는 물건입니다. 무엇을 몇 개 띄울지 적어서 넘기면 그 상태에 맞춰 줍니다. 띄워 둔 것이 죽으면 다시 띄웁니다. 받아서 설치하는 오픈소스 프로젝트입니다.

상세

공식 개요 문서는 쿠버네티스를 컨테이너로 만든 워크로드와 서비스를 관리하는 이식 가능하고 확장 가능한 오픈소스 플랫폼이라고 적습니다. 선언적 구성과 자동화 둘 다를 쉽게 해 준다는 설명이 붙습니다. 구글이 2014년에 이 프로젝트를 오픈소스로 공개했습니다. 프로덕션 워크로드를 대규모로 돌린 15년 넘는 경험에 커뮤니티의 아이디어와 관행을 합친 것이라고 문서가 밝힙니다.

설치하고 나면 생기는 단위는 클러스터입니다. 클러스터 하나는 컨트롤 플레인과 노드라고 부르는 워커 머신들로 이루어집니다. 파드를 돌리려면 워커 노드가 적어도 하나는 필요합니다. 워커 노드는 애플리케이션 워크로드를 이루는 파드를 호스팅합니다. 컨트롤 플레인은 클러스터 안의 워커 노드와 파드를 관리합니다. 프로덕션 환경에서는 컨트롤 플레인이 보통 여러 컴퓨터에 걸쳐 돕니다. 클러스터도 보통 여러 노드를 돌립니다. 그렇게 해서 장애 내성과 고가용성을 얻는다고 아키텍처 문서가 적습니다.

컨트롤 플레인 컴포넌트

컨트롤 플레인의 컴포넌트들은 클러스터에 대한 전역 결정을 내립니다. 스케줄링이 그런 결정입니다. 클러스터 이벤트를 감지하고 거기에 반응하는 것도 이쪽 일입니다. 디플로이먼트의 replicas 필드가 충족되지 않을 때 새 파드를 띄우는 것이 문서가 든 예입니다. 컨트롤 플레인 컴포넌트는 클러스터의 아무 머신에서나 돌 수 있습니다. 다만 단순하게 하려고 셋업 스크립트들은 대개 컨트롤 플레인 컴포넌트를 전부 같은 머신에서 띄웁니다. 그 머신에서는 사용자 컨테이너를 돌리지 않습니다.

컴포넌트 아키텍처 문서가 적는 것
kube-apiserver 쿠버네티스 API(Application Programming Interface, 응용 프로그램 인터페이스)를 노출합니다. 컨트롤 플레인의 프론트 엔드입니다
etcd 모든 클러스터 데이터를 담는 뒷단 저장소입니다. 일관성 있고 고가용성인 키-값 저장소라고 문서가 적습니다
kube-scheduler 노드가 아직 안 정해진 새 파드를 지켜보다가 그 파드가 돌 노드를 고릅니다
kube-controller-manager 컨트롤러 프로세스를 돌립니다. 논리적으로는 컨트롤러마다 별개 프로세스입니다. 복잡도를 줄이려고 전부 하나의 바이너리로 컴파일해 한 프로세스에서 돌립니다
cloud-controller-manager 클라우드에 특화된 제어 로직을 품습니다. 클러스터를 클라우드 제공자의 API 에 연결합니다. 직접 운영하는 온프레미스나 개인 컴퓨터 안 학습 환경의 클러스터에는 이 컴포넌트가 없습니다

노드 컴포넌트

노드 컴포넌트는 모든 노드에서 돕니다. 돌고 있는 파드를 유지합니다. 쿠버네티스 런타임 환경을 제공하는 것도 이쪽 일입니다.

컴포넌트 아키텍처 문서가 적는 것
kubelet 클러스터의 각 노드에서 도는 에이전트입니다. 파드 안에서 컨테이너가 돌고 있는지 확인합니다. 쿠버네티스가 만들지 않은 컨테이너는 관리하지 않습니다
kube-proxy 각 노드에서 도는 네트워크 프록시입니다. 쿠버네티스 서비스 개념의 일부를 구현합니다. 선택 컴포넌트입니다
컨테이너 런타임 컨테이너의 실행과 생명주기를 관리하는 자리입니다. containerd, CRI-O, 그리고 쿠버네티스 CRI(Container Runtime Interface, 컨테이너 런타임 인터페이스)를 구현한 다른 구현체를 지원합니다

포기한 것

PaaS 가 아니다

쿠버네티스는 전통적인 올인원 PaaS(Platform as a Service, 서비스형 플랫폼) 시스템이 아니라고 개요 문서가 못 박습니다. 하드웨어 레벨이 아니라 컨테이너 레벨에서 돌기 때문입니다. 그래서 PaaS 제품들이 공통으로 갖는 기능 몇 가지를 일반적으로 쓸 수 있는 형태로 제공합니다. 배포, 스케일링, 로드 밸런싱이 그 기능입니다. 그리고 사용자가 자기 로깅·모니터링·알림 솔루션을 통합하도록 열어 둡니다. 쿠버네티스는 모놀리식이 아니라고 문서가 덧붙입니다. 여기서 말한 기본 솔루션들은 선택 사항이고 갈아 끼울 수 있습니다. 포기하고 얻은 것은 문서의 표현으로 사용자의 선택과 유연성입니다. 개발자 플랫폼을 짓는 빌딩 블록을 주되 중요한 자리에서는 선택권을 남겨 둡니다.

소스코드를 빌드하지도 배포하지도 않는다

쿠버네티스는 소스코드를 배포하지 않습니다. 애플리케이션을 빌드하지도 않습니다. CI/CD (Continuous Integration, Delivery, and Deployment, 지속적 통합·전달·배포) 워크플로는 기술적 요구사항뿐 아니라 조직의 문화와 선호가 정하는 것이라고 문서가 이유를 답니다. 안 하기로 하고 남긴 것은 그 워크플로를 고르는 자리 자체입니다.

애플리케이션 수준 서비스와 운영 도구를 정해 주지 않는다

미들웨어, 데이터 처리 프레임워크, 데이터베이스, 캐시, 클러스터 스토리지 시스템을 내장 서비스로 제공하지 않습니다. 문서가 각각에 붙인 예는 메시지 버스, Spark, MySQL, Ceph 입니다. 그런 컴포넌트는 쿠버네티스 위에서 돌 수 있습니다. 쿠버네티스 위에서 도는 애플리케이션이 Open Service Broker 같은 이식 가능한 메커니즘으로 그것들에 접근할 수도 있습니다.

로깅·모니터링·알림 솔루션도 지시하지 않습니다. 개념 증명 수준의 통합 몇 개와 메트릭을 수집·내보내는 메커니즘만 제공합니다. 설정 언어나 설정 시스템도 제공하거나 강제하지 않습니다. 문서가 든 예는 Jsonnet 입니다. 대신 선언적 API 를 제공합니다. 그 API 는 임의의 형태를 한 선언적 명세가 겨냥할 수 있는 대상이라고 적혀 있습니다. 포괄적인 머신 설정·유지보수·관리·자가치유 시스템도 제공하거나 채택하지 않습니다.

포기한 것을 값으로 보면 기본값입니다. 어떤 로그 수집기를 쓸지, 어떤 설정 언어로 매니페스트를 찍어낼지, 머신을 어떻게 관리할지가 전부 쓰는 쪽에 남습니다.

정해진 순서를 실행하는 오케스트레이션이 아니다

문서는 쿠버네티스가 단순한 오케스트레이션 시스템도 아니라고 덧붙입니다. 오히려 오케스트레이션의 필요를 없앤다고 적습니다. 오케스트레이션의 기술적 정의는 정의된 워크플로의 실행입니다. 먼저 A 를 하고 다음에 B, 그다음에 C 를 하는 식입니다. 쿠버네티스는 그와 달리 독립적이고 조합 가능한 제어 프로세스들의 집합입니다. 그 프로세스들이 현재 상태를 주어진 원하는 상태 쪽으로 계속 몰고 갑니다. A 에서 C 로 어떻게 가는지는 중요하지 않아야 한다고 문서가 적습니다. 중앙집중 제어도 필요하지 않습니다. 순서를 적을 자리를 포기한 대신 남은 것이 아래 「동작」의 조정 루프입니다.

예시

nginx 파드 셋을 띄우는 디플로이먼트

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

디플로이먼트 문서가 싣는 매니페스트입니다. 이 디플로이먼트가 레플리카셋을 만들고 그 레플리카셋이 nginx 파드 세 개를 띄웁니다. apiVersion 은 이 오브젝트를 만드는 데 쓰는 쿠버네티스 API 의 버전입니다. kind 는 만들 오브젝트의 종류입니다. metadata 는 오브젝트를 유일하게 가려내는 자료입니다. 여기 들어가는 name 이 오브젝트 이름 nginx-deployment 입니다. spec 은 그 오브젝트가 갖기를 바라는 상태입니다. spec.replicas 가 3 이라 원하는 파드 수가 셋입니다. spec.selector 는 만들어진 레플리카셋이 관리할 파드를 어떻게 찾을지 정하는 자리입니다. 여기서는 파드 템플릿에 적힌 app: nginx 라벨을 고른 것입니다. spec.template 아래에는 하위 필드들이 붙습니다. metadata.labels 로 파드에 app: nginx 라벨을 붙입니다. 파드 템플릿의 spec 은 그 파드가 컨테이너 하나를 돌린다고 적습니다. 컨테이너 이름은 nginx, 이미지는 nginx:1.14.2, 여는 포트는 80 입니다.

넣는 명령은 한 줄입니다.

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml

만들어졌는지는 kubectl get deployments 로 봅니다. 아직 만들어지는 중이면 출력이 이렇습니다.

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   0/3     0            0           1s

칸은 다섯입니다. NAME 은 네임스페이스 안 디플로이먼트들의 이름을 늘어놓습니다. READY 는 사용자가 쓸 수 있는 애플리케이션 레플리카가 몇 개인지 보여 줍니다. 준비된 수/원하는 수 꼴을 따릅니다. 여기 원하는 수가 3 인 것은 .spec.replicas 필드에 적은 대로입니다. UP-TO-DATE 는 원하는 상태에 이르려고 갱신된 레플리카 수입니다. AVAILABLE 은 사용자가 쓸 수 있는 레플리카 수입니다. AGE 는 애플리케이션이 돌아온 시간입니다. 몇 초 뒤에 같은 명령을 다시 돌리면 출력이 이렇게 바뀝니다.

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           18s

최소 파드 매니페스트

YAML
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

파드 문서가 싣는 매니페스트입니다. 앞의 디플로이먼트와 달리 원하는 개수도 셀렉터도 없습니다. 파드 하나를 그대로 적은 것입니다. 파드는 쿠버네티스에서 만들고 관리할 수 있는 가장 작은 배포 단위라고 문서가 적습니다. 컨테이너 하나 이상을 저장소와 네트워크 자원을 공유하는 형태로 묶은 것입니다. 컨테이너를 어떻게 돌릴지 적은 명세가 함께 들어갑니다. 컨테이너 하나짜리 파드가 가장 흔한 쓰임새입니다. 그때 파드는 컨테이너 하나를 감싼 껍데기로 볼 수 있습니다. 쿠버네티스가 다루는 것은 컨테이너가 아니라 파드입니다.

동작

쿠버네티스 오브젝트는 시스템 안에 남는 영속 엔티티입니다. 클러스터의 상태를 나타내는 데 쓰입니다. 문서는 오브젝트를 의도의 기록이라고 부릅니다. 오브젝트를 만들면 쿠버네티스 시스템이 그 오브젝트가 존재하도록 끊임없이 일합니다.

거의 모든 오브젝트는 중첩된 필드 두 개를 갖습니다. spec 과 status 입니다. spec 은 만들 때 사람이 채웁니다. 그 자원이 갖기를 바라는 특성, 곧 원하는 상태를 적는 자리입니다. status 는 오브젝트의 현재 상태를 적습니다. 쿠버네티스 시스템과 그 컴포넌트들이 채우고 갱신합니다. 컨트롤 플레인은 모든 오브젝트의 실제 상태를 사람이 준 원하는 상태에 맞추려고 계속 능동적으로 관리합니다.

맞추는 일을 하는 것이 컨트롤러입니다. 로보틱스와 자동화에서 조정 루프는 시스템의 상태를 조절하는 끝나지 않는 루프라고 컨트롤러 문서가 적습니다. 문서가 드는 예가 방 안의 온도조절기입니다. 온도를 맞춰 두는 것이 온도조절기에게 원하는 상태를 알려 주는 일입니다. 실제 방 온도가 현재 상태입니다. 온도조절기는 장비를 켜고 끄면서 현재 상태를 원하는 상태에 가깝게 만듭니다. 쿠버네티스의 컨트롤러가 바로 이 조정 루프입니다. 클러스터의 상태를 지켜보다가 필요한 곳에 변경을 만들거나 요청합니다. 컨트롤러는 자기가 직접 행동을 수행하기도 합니다. 다만 쿠버네티스에서 더 흔한 쪽은 API 서버에 메시지를 보내는 것입니다. 그 메시지가 쓸모 있는 부수 효과를 냅니다.

flowchart TD
    S["spec · 원하는 상태"] --> C["컨트롤러"]
    T["status · 현재 상태"] --> C
    C -->|어긋나면| A["API 서버에 변경을 요청"]
    A --> K["kube-scheduler 가 노드를 고르고 kubelet 이 컨테이너를 돌린다"]
    K --> T

한 바퀴를 디플로이먼트로 따라가면 이렇습니다. 디플로이먼트 스펙에 레플리카 세 개를 적어 두면 쿠버네티스가 그 스펙을 읽고 그만큼의 인스턴스를 띄웁니다. 그리고 status 를 spec 에 맞게 갱신합니다. 그중 하나가 죽으면 status 가 바뀝니다. 쿠버네티스는 spec 과 status 의 차이에 반응해 교정합니다. 이 경우 교정은 교체 인스턴스를 시작하는 것입니다. 노드가 아직 안 정해진 새 파드를 찾아 노드를 고르는 것은 kube-scheduler 의 일입니다. 노드에서 파드 안 컨테이너가 돌고 있는지 확인하는 것은 kubelet 의 일입니다.

루프가 끝나는 자리는 정해져 있지 않습니다. 쿠버네티스는 시스템을 클라우드 네이티브 관점으로 보고 끊임없는 변화를 다룰 수 있다고 문서가 적습니다. 일이 벌어지는 동안 클러스터는 언제든 바뀔 수 있습니다. 조정 루프가 실패를 자동으로 고치기도 합니다. 그래서 클러스터가 안정 상태에 영영 도달하지 않을 수도 있습니다. 컨트롤러가 돌고 쓸모 있는 변경을 만들 수 있는 한 전체 상태가 안정적인지 아닌지는 중요하지 않다고 문서가 적습니다.

관련 항목

쿠버네티스를 이루는 구성 요소

클러스터 · 컨트롤 플레인 · 워커 노드 · 노드 · 파드

컨트롤 플레인을 이루는 컴포넌트

kube-apiserver · etcd · kube-scheduler · kube-controller-manager · cloud-controller-manager · 스케줄링

워커 노드를 이루는 컴포넌트

kubelet · kube-proxy · 컨테이너 런타임 · containerd · CRI-O · CRI · 네트워크 · 프록시

쿠버네티스가 정의하는 컨트롤러

컨트롤러 · 조정 루프 · 노드 컨트롤러 · 잡 컨트롤러 · EndpointSlice 컨트롤러 · ServiceAccount 컨트롤러

컨트롤러가 원하는 상태로 맞춰 가는 오브젝트 종류

디플로이먼트 · 레플리카셋 · 서비스

예시 매니페스트에 등장하는 이름

nginx · 컨테이너 이미지

쿠버네티스를 다루는 도구와 형식

kubectl · API · 쿠버네티스 API · 매니페스트 · 오브젝트

쿠버네티스가 지키는 성질과 배치 조건

자동화 · 선언적 구성 · 고가용성 · 어피니티 · 안티어피니티

쿠버네티스가 걸치는 배치 환경

클라우드 · 온프레미스

쿠버네티스가 내장하지 않는 애플리케이션 서비스

미들웨어 · 프레임워크 · 데이터베이스 · 캐시 · 스토리지 · 메시지 · MySQL · Ceph · Spark · Open Service Broker

쿠버네티스가 강제하지 않는 운영·설정 도구

로그 · 메트릭 · 모니터링 · 알림 · Jsonnet

쿠버네티스가 맡지 않는 배포·개발 단계

배포 · CI/CD · 워크플로 · 개발

쿠버네티스와 맞세워지는 대립 개념

PaaS · 오케스트레이션

다른 이름: 쿠버네티스 · K8s