리눅스 컨테이너 커널
docker-0-9-introducing-execution-drivers-and-libcontainer
도커
컨테이너 기반의 오픈소스 가상화 플랫폼
컨테이너(Container)
컨테이너는 격리된 공간에서 프로세스가 동작하는 기술
등장 배경
가상화 기술의 하나지만 기존방식과는 차이가 존재
기존
호스트 가상화 : VMware나 VirtualBox같은 가상머신은 호스트 OS위에 게스트 OS 전체를 가상화하여 사용하는 방식 => 무거움
CPU의 가상화 기술(HVM)을 이용한 KVMKernel-based Virtual Machine과 반가상화 Paravirtualization방식의 Xen이 등장 => 무거움/ 추가적인 OS를 설치해 가상화하는 것에 한계가 있음.
프로세스를 격리 하는 방식이 등장
이미지
컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것
Immutable
이미지 관리는 url형식으로 관리가 가능함.
레이어 저장방식
유니온 파일 시스템을 이용하여 여러개의 레이어를 하나의 파일시스템으로 사용할 수 있게 해줌.
ex) A, B, C, D, E 레이어 존재시 => 중복 저장없음
X컨테이너 ( A + B + C )
Y컨테이너 ( A + B + D )
Z컨테이너 ( B + C + E )
쿠버네티스
컨테이너를 쉽고 빠르게 배포/확장하고 관리를 자동화해주는 오픈소스 플랫폼
다양한 배포 지원
Deployment는 새로운 버전의 애플리케이션을 다양한 전략으로 무중단 배포
StatefulSets은 실행 순서를 보장하고 호스트 이름과 볼륨을 일정하게 사용할 수 있어 순서나 데이터가 중요한 경우에 사용
DaemonSet 로그나 모니터링 등 모든 노드에 설치가 필요한 경우
Job이나 CronJob은 배치성 작업인 경우
Ingress 지원
웹 앱 배포시 필요한 프록시서버(ALB, Ngnix, Apache - 도메인과 Path조건에 따라 등록된 서버로 요청 전달) 설정 자동화 및 기존 그대로 사용 가능
여러개 Ingress 설정가능
ex) 관리자용 + 일반용 동시 설정 가능
Pod 라벨링 지원
RBAC (role-based access control) + IAM
CRD ( Custom Resource Definitaion )
ex ) cert-manager ( ssl 관리 )
Auto Scaling
Federation, Multi Cluster
워크로드
쿠버네티스에서 구동되는 애플리케이션
workload라는 오브젝트/컴포넌트/어떤 종류의 구성요소도 존재하지 않음.
클러스터에서 실행하려는 작업이나 서비스 등을 가리키는 말로 종종 사용
마이크로 서비스, 어플리케이션, 컨테이너, 프로세스와 동의어일 가능성이 있음.
workload는 수명이 긴 프로세스이지만 요청시만 수행되거나 배치 잡과 같은 수명이 짧은 프로세스일수도있음.
워크로드가 단일 컴포넌트든 함께 작동하는 컴포넌트 집합이든 관계없이, 쿠버네티스에서는 워크로드를 일련의 파드 집합 실행
사용자를 대신하여 파드 집합을 관리하는 워크로드 리소스를 사용할 수 있는데, 이러한 리소스는 지정한 상태와 일치하도록 올바른 수의 올바른 파드 유형이 실행되고 있는지 확인하는 컨트롤러를 구성
기본 개념
Desired State
관리자가 원하는 환경, 상태 생성, 선언
k8s는 현재상태를 모니터링하면서 관리자가 원하는 상태를 유지하려고 내부적인 작업을 지속적으로 실행
$ docker run # 명령 [ 명령imperative - ex) nginx 컨테이너를 실행해줘. 그리고 80 포트로 오픈 ]
$ kubectl create # 상태 생성 [선언 declarative - ex) 80 포트를 오픈한 nginx 컨테이너를 1개 유지 ]
Kubernetes Object
Pod (돌고래떼 귀여움..)
배포할 수 있는 가장 작은 단위
컨테이너 + 스토리지 + 네트워크 속성
Pod에 속한 컨테이너끼리 스토리지와 네트워크를 공유 => 서로 localhost로 접근
종류
단일 컨테이너를 실행하는 파드
함께 작용해야 하는 '여러 컨테이너를 실행하는 파드
함께 배치된 컨테이너는 하나의 결합된 서비스 단위를 형성함
ReplicaSet
Pod을 여러 개(한 개 이상) 복제하여 관리하는 오브젝트
Pod을 생성하고 개수를 유지하려면 반드시 ReplicaSet을 사용
ReplicaSet은 복제할 개수, 개수를 체크할 라벨 선택자, 생성할 Pod의 설정값(템플릿)등
직접적으로 ReplicaSet을 사용하기보다는 Deployment등 다른 오브젝트에 의해서 사용되는 경우가 많음.
Service
Pod을 외부 네트워크와 연결해주고 여러 개의 Pod을 바라보는 내부 로드 밸런서를 생성할 때 사용
서비스 디스커버리 : 내부 DNS에 서비스 이름을 도메인으로 등록
Volume
스토리지, EBS 사용가능
Object Spec - YAML
오브젝트의 종류와 원하는 상태를 입력
REST API로 쉽게 노출 가능 ( 생성, 조회, 삭제로 관리 가능 )
접근 권한 설정 가능
쿠버네티스 배포방식
애플리케이션을 배포하기 위해 원하는 상태(desired state)를 다양한 오브젝트(object)에 라벨Label을 붙여 정의(yaml)하고 API 서버에 전달하는 방식을 사용
쿠버네티스 아키텍처
server- agent 구성
마스터 - 노드 구조
전체 클러스터를 관리하는 마스터 + 컨테이너가 배포되는 노드
모든 명령은 마스터의 API 서버를 호출하고 노드는 마스터와 통신하면서 필요한 작업을 수행합니다. 특정 노드의 컨테이너에 명령하거나 로그를 조회할 때도 노드에 직접 명령하는 게 아니라 마스터에 명령을 내리고 마스터가 노드에 접속하여 대신 결과를 응답
Master
다양한 모듈이 확장성을 고려하여 기능별로 쪼개져 있는 것이 특징
가용성을 위해서 일반적으로 3대 이상
EKS 특징 : AWS의 경우 마스터는 AWS에서 관리해줌
Node
마스터 서버와 통신하면서 필요한 Pod을 생성하고 네트워크와 볼륨을 설정
Kubectl
json 또는 protobuf 형식을 이용한 http 통신을 지원합니다. 이 방식을 그대로 쓰면 불편하므로 보통 kubectl이라는 명령행 도구를 사용
Master 구성요소
API 서버 kube-apiserver
모든 요청을 처리하는 마스터의 핵심 모듈
kubectl의 요청뿐 아니라 내부 모듈의 요청도 처리하며 권한을 체크하여 요청을 거부 가능
실제로 하는 일은 원하는 상태를 key-value 저장소에 저장하고 저장된 상태를 조회함.
Pod을 노드에 할당하고 상태를 체크하는 일은 다른 모듈로 분리되어 있음.
노드에서 실행 중인 컨테이너의 로그를 보여주고 명령을 보내는 등 디버거 역할도 수행
분산 데이터 저장소 etcd
RAFT 알고리즘을 이용한 key-value 저장소
여러 개로 분산하여 복제할 수 있기 때문에 안정성과 속도가 높음
단순히 값을 저장하고 읽는 기능뿐 아니라 watch 기능이 있어 어떤 상태가 변경되면 바로 체크하여 로직 실행 가능
클러스터의 모든 설정, 상태 데이터는 여기 저장되고 나머지 모듈은 stateless하게 동작하기 때문에 etcd만 잘 백업해두면 언제든지 클러스터를 복구가능
etcd는 오직 API 서버와 통신하고 다른 모듈은 API 서버를 거쳐 etcd 데이터에 접근
스케줄러, 컨트롤러
API 서버는 요청을 받으면 etcd 저장소와 통신할 뿐 실제로 상태를 바꾸는 건 스케줄러와 컨트롤러
현재 상태를 모니터링하다가 원하는 상태와 다르면 각자 맡은 작업을 수행하고 상태를 갱신
Deployment는 ReplicaSet을 생성하고 ReplicaSet은 Pod를 생성, Pod은 스케줄러가 관리
철저하게 분업화가 되어있음
스케줄러 ( kube-scheduler )
할당되지 않은 Pod을 여러 가지 조건(필요한 자원, 라벨)에 따라 적절한 노드 서버에 할당
큐브 컨트롤러 ( kube-controller-manager )
쿠버네티스에 있는 거의 모든 오브젝트의 상태를 관리
클라우드 컨트롤러 ( cloud-controller-manager )
클라우드 컨트롤러는 AWS, GCE, Azure 등 클라우드에 특화된 모듈
노드를 추가/삭제하고 로드 밸런서를 연결하거나 볼륨을 붙음
각 클라우드 업체에서 인터페이스에 맞춰 구현
Node 구성요소
큐블릿 kubelet
노드에 할당된 Pod의 생명주기를 관리
Pod을 생성하고 Pod 안의 컨테이너에 이상이 없는지 확인하면서 주기적으로 마스터에 상태를 전달
API 서버의 요청을 받아 컨테이너의 로그를 전달하거나 특정 명령을 대신 수행
프록시 kube-proxy
Pod으로 연결되는 네트워크를 관리
TCP, UDP, SCTP 스트림을 포워딩하고 여러 개의 Pod을 라운드로빈 형태로 묶어 서비스를 제공
초기 : 프록시서버로 동작, 실제 요청을 프록시 서버가 받고 각 pod에 전달
현재 : iptables를 설정하는 방식으로 변경. => 규칙이 많으면 느려짐
최근 : IPVS를 지원
추상화
CRI(Container runtime interface)를 구현한 다양한 컨테이너 런타임을 지원
생명주기