이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.
공부 › 아키텍처와 운영 › 배포와 운영
쿠버네티스 자가 치유
컨테이너가 죽으면 누가 다시 띄우나
쿠버네티스에는 "이 애플리케이션을 3개 띄워 둬라"처럼 원하는 상태를 적어 둡니다. 쿠버네티스는 실제 상태를 계속 지켜보다가 원하는 상태와 달라지면 스스로 맞춥니다. 죽은 Pod를 사람이 손대지 않아도 새것으로 바꿔 놓는 이런 동작을 자가 치유라고 합니다.
문서·표준 대조 · 쿠버네티스 공식 문서
이 실습에 나오는 개념
- Kubernetes
- 여러 서버에 걸쳐 컨테이너를 배치하고 관리하는 일을 자동화하는 플랫폼이다. 원하는 상태(예: 이 애플리케이션을 3개 실행)를 선언하면 실제 상태가 그와 같아지도록 계속 조정한다. 컨테이너가 죽으면 다시 띄우고, 부하에 따라 개수를 조절하며, 새 버전으로의 교체를 단계적으로 수행한다.
- Pod, Deployment, Service
- 쿠버네티스의 기본 구성 요소다. Pod는 함께 실행되는 하나 이상의 컨테이너 묶음으로 배포의 최소 단위다. Deployment는 Pod를 몇 개 유지할지와 새 버전으로 교체하는 방법을 관리한다. Service는 수시로 바뀌는 Pod들에 대해 변하지 않는 접근 주소를 제공하고 요청을 분산한다.
- 헬스 체크(Liveness, Readiness)
- 서버가 정상인지 주기적으로 확인하는 것이다. Liveness는 프로세스가 살아 있는지를 확인해 문제가 있으면 재시작하게 한다. Readiness는 요청을 받을 준비가 되었는지를 확인해 준비되지 않은 서버로는 트래픽을 보내지 않게 한다. 서버가 시작 중이거나 종료 중일 때 요청이 들어가는 것을 막는다.
- 오토스케일링
- CPU 사용률이나 요청 수 같은 지표에 따라 서버의 수를 자동으로 늘리거나 줄이는 기능이다. 부하가 많을 때는 서버를 추가하고 적을 때는 줄여 비용을 아낀다. 서버가 추가되어 요청을 받을 수 있게 되기까지 시간이 걸리므로, 예고된 급증에는 미리 늘려 두는 것이 안전하다.
- 컨테이너와 이미지
- 컨테이너는 애플리케이션과 그 실행에 필요한 것들을 묶어, 호스트 운영체제의 커널을 공유하면서 다른 프로세스와 격리된 환경에서 실행하는 기술이다. 이미지는 컨테이너를 만드는 데 쓰는 읽기 전용 템플릿으로 애플리케이션과 라이브러리, 설정이 들어 있다. 같은 이미지로 실행하면 실행 환경의 차이로 생기는 문제를 크게 줄인다.
이렇게 바꿔 보세요
- 처음 설정으로 — Pod 하나가 죽습니다. 새 Pod가 자동으로 만들어집니다.
- 노드가 죽으면 — 그 노드에 있던 Pod가 다른 노드에 다시 만들어집니다.
- 복제본 수를 늘리면 — 숫자만 바꾸면 쿠버네티스가 모자란 만큼 만듭니다.
- 프로세스는 살아 있는데 멈췄다면 — liveness 검사가 실패해 컨테이너를 재시작합니다.
- 잠시 요청을 못 받는 상태라면 — readiness 검사가 실패해 요청만 끊습니다. 재시작하지 않습니다.
처음 설정으로 실행하면
- 평소 상태입니다. Deployment에 "복제본 3개"라고 적혀 있고, 실제로 Pod 3개가 노드 세 대 가운데 두 대(노드 1, 노드 2)에 나뉘어 실행 중입니다. Service가 요청을 세 Pod에 나눠 보냅니다.
- shop-b Pod가 사라졌습니다(예: 노드의 자원이 모자라 쫓겨남). Service는 이 Pod로 요청을 보내지 않게 됩니다. 실제 Pod 수는 2개가 됐습니다.
- 컨트롤러가 상태를 비교합니다. 원하는 수 3, 실제 2. 하나가 모자랍니다. 누가 알려 주지 않아도 이 비교는 계속 반복되고 있습니다.
- 새 Pod shop-d를 만듭니다. 스케줄러가 여유 있는 노드를 골라 배치하고, 그 노드의 kubelet이 컨테이너를 띄웁니다. 사라진 Pod를 살리는 것이 아니라 새것으로 교체합니다.
- shop-d가 준비 상태 검사(readiness)를 통과했습니다. Service가 요청을 보내기 시작합니다. 다시 3개입니다.
실행 결과
- 사람이 손대지 않았는데 Pod가 다시 3개가 됐습니다. 이것이 자가 치유입니다. Pod는 언제든 죽고 교체될 수 있는 일회용으로 다룹니다. 그래서 Pod가 교체되면 컨테이너 안의 파일과 세션은 사라지므로 상태는 외부 저장소(볼륨, DB, Redis)에 두고, Pod의 IP 대신 Service의 고정된 이름으로 접근합니다.
- 컨트롤러는 원하는 상태와 실제 상태를 끊임없이 비교해 차이를 메웁니다. 이 반복이 쿠버네티스의 기본 동작 원리입니다.
코드
apiVersion: apps/v1
kind: Deployment
metadata: { name: shop }
spec:
replicas: 3 # 원하는 상태: 항상 3개
template:
spec:
containers:
- name: app
image: shop:1.0
livenessProbe: # 실패하면 컨테이너 재시작
httpGet: { path: /actuator/health/liveness, port: 8080 }
readinessProbe: # 실패하면 요청 대상에서만 제외
httpGet: { path: /actuator/health/readiness, port: 8080 }
이 모형의 전제
복제본 3개, 노드 세 대의 단순한 구성입니다. 감지와 복구에 걸리는 시간은 표시하지 않았습니다(노드 장애는 감지 후 Pod를 옮기기까지 기본 설정으로 수 분이 걸립니다). Deployment, 컨트롤러, 두 가지 검사의 동작은 쿠버네티스 공식 문서의 설명을 따랐습니다. 실제 클러스터에서 실행한 결과는 아닙니다.
앞 실습: 컨테이너와 가상 머신 · 다음 실습: 평균과 백분위