본문으로 건너뛰기
버전: 1.0.3

3.2. 컨트롤러

어떨 때 보는가

  • 애플리케이션이 몇 개 떠 있는지 확인할 때
  • 새 버전이 제대로 배포되었는지 볼 때
  • 파드 수를 늘리거나 줄일 때
  • 배포한 뒤 문제가 생겨 되돌려야 할 때

컨트롤러란 무엇인가

파드는 그 자체로는 다시 만들어지지 않습니다. 파드를 직접 만들어 두면, 그 파드가 종료되는 순간 애플리케이션도 함께 사라집니다. 노드가 내려가도 마찬가지입니다.

컨트롤러는 이 문제를 해결합니다. 사용자가 "원하는 상태" 를 정해 두면, 컨트롤러가 클러스터를 계속 지켜보며 실제 상태를 그 상태에 맞춥니다.

예를 들어 "복제본 3개" 라고 정해 두면 이렇게 동작합니다.

실제로 일어난 일컨트롤러가 하는 일
파드 하나가 종료됐다 (2개 남음)새 파드를 하나 만들어 3개로 맞춥니다
노드가 내려가 파드 2개가 사라졌다남은 노드에 2개를 새로 띄웁니다
누군가 파드를 손으로 지웠다다시 만듭니다
복제본을 5로 바꿨다2개를 더 만듭니다

사람이 지켜보지 않아도 됩니다. 이것이 Kubernetes 를 쓰는 가장 큰 이유 중 하나입니다.

선언형이라는 말의 뜻

Kubernetes 를 설명할 때 "선언형" 이라는 말이 나옵니다. 명령형과 비교하면 이해하기 쉽습니다.

방식지시 내용문제가 생기면
명령형"이 프로그램을 실행해라"종료돼도 아무 일도 일어나지 않습니다
선언형"이 프로그램이 3개 떠 있어야 한다"종료되면 시스템이 다시 맞춥니다

컨트롤러는 선언형을 실현하는 장치입니다. 사용자는 결과만 적고, 그 결과에 도달하는 과정은 컨트롤러가 맡습니다.

Console 에서 복제본 수를 바꾸거나 이미지를 고치는 것은 "원하는 상태" 를 고치는 것 입니다. 실제 파드를 직접 건드리는 것이 아닙니다.

Deployment 란

상태를 저장하지 않는 애플리케이션 을 관리하는 컨트롤러입니다. 웹 서버, API 서버처럼 어느 파드가 요청을 받아도 결과가 같은 경우에 씁니다.

Deployment 가 하는 일은 세 가지입니다.

하는 일설명
개수 유지정해진 복제본 수를 지킵니다
무중단 교체새 버전을 배포할 때 하나씩 바꿔 서비스를 끊지 않습니다
되돌리기이전 버전 기록을 남겨 문제가 생기면 돌아갑니다

"상태를 저장하지 않는다" 는 것은 파드 안에 남겨야 할 데이터가 없다는 뜻입니다. 데이터는 데이터베이스나 별도 저장 공간에 두고, 파드는 언제 종료되고 다시 만들어져도 상관없어야 합니다.

파드마다 고유한 데이터가 필요하면 Deployment 가 아니라 StatefulSet 을 씁니다(아래 참고).

Deployment 가 파드를 관리하는 구조

Deployment 는 파드를 직접 만들지 않습니다. 중간에 ReplicaSet 이 있습니다.

Deployment 가 파드를 관리하는 구조

새 버전을 배포하면 새 ReplicaSet 이 하나 더 생깁니다. 옛 ReplicaSet 은 복제본 0 으로 남아 이력이 됩니다. 되돌리기는 옛 ReplicaSet 의 복제본을 다시 올리는 것입니다.

목록에 같은 이름 앞부분을 가진 ReplicaSet 이 여럿 보이는 것은 그동안의 배포 이력입니다.

Deployment 목록

워크로드 > 배포 로 들어갑니다.

Deployment 목록
설명이렇게 읽습니다
이름Deployment 이름
네임스페이스속한 네임스페이스
파드준비된 파드 / 원하는 파드두 수가 다르면 배포가 진행 중이거나 문제가 있습니다
복제본설정한 복제본 수
경과 시간만든 뒤 지난 시간

2/3 가 몇 분 넘게 유지되면 파드 목록에서 준비되지 않은 파드를 찾아 이벤트를 확인하십시오 (3.1 장).

Deployment 상세

이름을 누르면 상세 화면이 열립니다.

Deployment 상세
구역무엇을 알 수 있는가
메타데이터이름, 네임스페이스, 레이블, 주석
전략새 버전으로 바꾸는 방식
선택 조건(Selector)어떤 레이블의 파드를 자기 것으로 보는지
컨테이너이미지, 태그, 환경 변수, 요청·제한 자원
조건배포 진행 상태
관련 자원만들어진 ReplicaSet 과 파드

컨테이너 이미지의 태그를 확인하십시오. 배포한 버전이 실제로 반영되었는지 여기서 봅니다.

선택 조건은 만든 뒤 바꿀 수 없습니다. 이 값으로 자기 파드를 찾기 때문에, 바꾸면 기존 파드와의 연결이 끊어집니다.

조건 에서 배포 상태를 읽습니다.

화면에는 조건마다 뱃지가 하나씩 나옵니다. 조건이 만족되면 초록, 아니면 빨강입니다.

조건정상일 때 뱃지아닐 때 뱃지아닐 때의 뜻
Available사용 가능사용할 수 없음준비된 파드가 모자랍니다
Progressing진행 중진행 중 아님배포가 멈췄습니다. 사유를 확인합니다

진행 중 뱃지에 마우스를 올리면 사유가 나옵니다. 배포가 정상으로 끝났으면 NewReplicaSetAvailable 입니다.

배포가 일정 시간(기본 10분) 안에 끝나지 않으면 ProgressDeadlineExceeded 로 바뀝니다. 새 파드가 뜨지 못하고 있다는 뜻이므로 파드 이벤트를 보십시오.

새 파드가 Running 인데 배포가 안 끝나면 준비 상태 검사를 확인하십시오. 롤링 업데이트는 새 파드가 준비 상태가 되어야 다음 파드를 교체합니다. 검사가 계속 실패하면 첫 파드에서 멈춘 채 진행되지 않습니다(3.1 장).

배포 방식 — Deployment 설정

전략동작언제 씁니다
RollingUpdate새 파드를 하나씩 띄우고 옛 파드를 하나씩 내립니다기본값. 서비스가 끊기지 않습니다
Recreate옛 파드를 모두 내린 뒤 새 파드를 띄웁니다두 버전이 동시에 뜨면 안 될 때

Recreate서비스가 잠시 멈춥니다. 데이터베이스 스키마가 바뀌어 옛 버전과 새 버전이 공존할 수 없는 경우에만 씁니다.

RollingUpdate 에는 조절 값이 두 개 있습니다.

기본값
maxSurge원하는 수보다 몇 개까지 더 띄워도 되는지25%
maxUnavailable동시에 몇 개까지 없어도 되는지25%

maxUnavailable: 0 으로 두면 배포 중에도 정상 파드 수가 유지됩니다. 대신 자원이 잠시 더 필요합니다.

설정은 이렇게 적습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-app
spec:
replicas: 4
revisionHistoryLimit: 10 # 되돌릴 수 있는 이력 개수
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 개수 또는 비율("25%")
maxUnavailable: 0 # 배포 중에도 4개를 유지합니다
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app # selector 와 같아야 합니다
annotations:
kubernetes.io/change-cause: "1.2.0 - 로그인 오류 수정"
spec:
containers:
- name: app
image: registry.example.com/my-app:1.2.0
항목설명
maxSurge원하는 수보다 더 띄울 수 있는 개수. 0 이면 자원을 더 쓰지 않지만 배포가 느립니다
maxUnavailable동시에 없어도 되는 개수. 0 이면 서비스 대수가 줄지 않습니다
revisionHistoryLimit남길 이력 개수. 이 수를 넘으면 오래된 것부터 지워지고 그 리비전으로는 되돌릴 수 없습니다
change-cause 주석배포 이력의 변경 사유 열에 표시됩니다

maxSurgemaxUnavailable 을 둘 다 0 으로 둘 수는 없습니다. 새로 띄울 수도, 내릴 수도 없어 배포가 진행되지 않습니다. 적용할 때 거부됩니다.

change-cause 를 넣어 두십시오. 넣지 않으면 배포 이력의 변경 사유가 <none> 으로 남아, 되돌릴 리비전을 고를 때 이미지 태그와 시각만으로 판단해야 합니다.

Recreate 는 조절 값이 없습니다.

strategy:
type: Recreate

블루그린·카나리처럼 Service 를 함께 다루는 배포 방식은 4.8 장에서 다룹니다. 이 절의 strategy 는 Deployment 하나 안에서 끝나는 설정입니다.

StatefulSet 이란

파드마다 고유한 정체성과 저장 공간이 필요한 애플리케이션 을 관리하는 컨트롤러입니다.

Deployment 의 파드는 서로 구별되지 않습니다. 이름 뒤에 무작위 문자열이 붙고, 다시 만들어지면 이름이 달라집니다. 저장 공간도 공유하거나 없습니다.

StatefulSet 은 다릅니다.

특징DeploymentStatefulSet
파드 이름무작위 (web-7d4f-x8k2)순번 (db-0, db-1, db-2)
만드는 순서동시에0번부터 차례로
지우는 순서동시에마지막 번호부터 거꾸로
저장 공간공유하거나 없음파드마다 하나씩 고정
네트워크 이름없음파드마다 고정된 이름

핵심은 "다시 만들어도 같은 것" 이라는 점입니다. db-0 이 종료됐다가 다시 떠도 이름이 db-0 이고, 이전에 쓰던 저장 공간에 그대로 다시 연결됩니다. 데이터가 유지됩니다.

StatefulSet 을 쓰는 경우

상황이유
데이터베이스 (MySQL, PostgreSQL)각 인스턴스가 자기 데이터 파일을 가집니다
메시지 큐 (Kafka)파티션이 특정 인스턴스에 할당되어 있습니다
분산 저장소 (Elasticsearch)노드마다 담당 데이터가 다릅니다
클러스터 구성원이 서로를 이름으로 찾아야 할 때고정된 네트워크 이름이 필요합니다

순서대로 만드는 것이 왜 중요한가. 데이터베이스 클러스터는 보통 첫 번째 인스턴스가 먼저 떠서 초기화한 뒤, 나머지가 거기에 합류합니다. 동시에 뜨면 서로 상대를 못 찾아 실패합니다.

순서대로 지우는 것도 중요합니다. 마지막 번호부터 빼야 남은 구성원끼리 정족수를 유지할 수 있습니다.

워크로드 > 상태저장 세트 에서 봅니다. 화면 구성은 Deployment 와 같습니다.

DaemonSet 이란

모든 노드에 파드를 하나씩 띄우는 컨트롤러입니다. 복제본 수를 정하지 않고, 노드 수만큼 자동으로 맞춥니다.

상황동작
새 노드를 클러스터에 추가그 노드에도 파드가 자동으로 생깁니다
노드를 클러스터에서 제거그 노드의 파드가 사라집니다

노드마다 하나씩 있어야 하는 것에 씁니다.

쓰임
로그 수집각 노드의 컨테이너 로그를 모아 보냅니다
지표 수집노드의 CPU·메모리를 재서 보냅니다
네트워크노드 사이 통신을 담당합니다
저장소노드의 디스크를 파드에 제공합니다

워크로드 > 데몬 세트 에서 봅니다. 원하는 수 는 보통 노드 수와 같습니다.

수가 노드 수보다 적으면 일부 노드에 배치되지 못한 것입니다. 테인트가 걸린 노드는 허용오차가 없으면 제외되므로(2.1 장), 관리 노드가 빠져 있는 것은 정상일 수 있습니다.

ReplicaSet 이란

정해진 개수의 파드를 유지 하는 컨트롤러입니다. 개수 유지만 하고 버전 관리나 무중단 교체 기능은 없습니다.

직접 만들지 않습니다. Deployment 가 내부적으로 만들어 씁니다. 목록에 나오는 것은 배포 이력이므로 지우지 마십시오.

워크로드 > 복제 세트 에서 봅니다.

상태
복제본이 0 이 아님지금 쓰이는 버전
복제본이 0이전 버전. 되돌리기에 쓰입니다

어떤 컨트롤러를 고를 것인가

질문아니오
파드마다 다른 데이터를 저장해야 하나?StatefulSet다음 질문으로
모든 노드에 하나씩 있어야 하나?DaemonSet다음 질문으로
한 번 실행하고 끝나는 작업인가?Job·CronJob (3.3 장)Deployment

대부분의 애플리케이션은 Deployment 로 충분합니다.

복제본 수 조절

상세 화면 오른쪽 위의 조절 버튼을 누릅니다.

  1. 조절 버튼을 누릅니다.
  2. 원하는 복제본 수를 넣습니다.
  3. 저장하면 곧바로 반영됩니다.

부하에 따라 자동으로 조절하려면 오토스케일링을 씁니다(3.5 장).

자동 조절을 설정한 자원의 복제본 수를 손으로 바꾸면 곧 자동 설정값으로 되돌아갑니다.

다시 시작

상세 화면 오른쪽 위의 다시 시작 버튼을 누르면 설정을 바꾸지 않고 파드만 새로 띄웁니다.

ConfigMap 이나 Secret 을 고친 뒤 값을 반영할 때 씁니다. 환경 변수로 주입한 값은 파드를 새로 띄워야 바뀌기 때문입니다(3.4 장).

다시 시작은 롤링 업데이트로 진행되므로 서비스가 끊기지 않습니다. 파드를 하나씩 지우는 것과 결과는 같지만 순서가 통제됩니다.

동작 원리는 이렇습니다. Console 이 파드 템플릿에 "다시 시작한 시각" 주석을 넣습니다. 템플릿이 바뀌었으므로 Kubernetes 가 새 버전 배포로 보고 롤링 업데이트를 시작합니다. 이미지나 설정은 그대로입니다.

배포 이력 보기

상세 화면 오른쪽 위의 시계 모양 아이콘(배포 히스토리)을 누르면 그동안의 배포 기록이 나옵니다.

지원 대상은 세 가지입니다.

자원이력 보기롤백
Deployment가능가능
DaemonSet가능가능
StatefulSet가능불가 (이력만 봅니다)

이력 표에는 이렇게 나옵니다.

설명
리비전배포 순번. 숫자가 클수록 최근입니다
이름그 리비전을 담고 있는 ReplicaSet 이름
이미지그때 배포된 컨테이너 이미지와 태그
변경 사유배포할 때 남긴 설명. 없으면 <none>
생성 시각그 리비전이 만들어진 때
상태지금 쓰이는 리비전이면 현재 로 표시됩니다

이미지 태그를 보면 어느 버전인지 바로 압니다. 태그를 latest 로 고정해 쓰면 리비전마다 같은 값이 나와 구분할 수 없으니, 빌드할 때 태그를 다르게 두십시오(4.2 장).

변경 사유 는 배포할 때 kubernetes.io/change-cause 주석을 넣어야 채워집니다. 넣지 않으면 <none> 으로 남습니다. 무엇 때문에 배포했는지 남겨 두면 나중에 되돌릴 리비전을 고르기 쉽습니다.

롤백하는 방법

새 버전을 배포했는데 문제가 생겼을 때 이전 상태로 되돌립니다.

  1. 되돌릴 자원(Deployment 또는 DaemonSet)의 상세 화면을 엽니다.
  2. 오른쪽 위의 시계 모양 아이콘 을 눌러 배포 히스토리를 엽니다.
배포 히스토리
  1. 돌아갈 리비전을 찾습니다. 이미지 태그와 생성 시각으로 확인합니다.
  2. 그 줄 오른쪽 작업 칸의 되돌리기 아이콘을 누릅니다.
  3. 롤링 업데이트가 시작됩니다. 잠시 뒤 이력이 갱신됩니다.

지금 쓰이는 리비전에는 되돌리기 아이콘이 없습니다. 위 그림에서 리비전 183 은 현재 표시와 활성 상태가 붙어 있고 작업 칸이 비어 있습니다. 이미 그 상태이므로 되돌릴 것이 없기 때문입니다. 나머지 줄은 비활성 이고 각각 되돌리기 아이콘을 갖습니다.

돌아갈 리비전은 이미지 태그와 생성 시각으로 고릅니다. 위 그림처럼 이미지 태그가 모두 같으면 리비전만으로는 무엇이 달라졌는지 알 수 없습니다. 이때는 생성 시각으로 "문제가 생기기 전 마지막 배포" 를 찾습니다. 변경 사유를 남겨 두었다면 그 값이 가장 확실한 단서입니다.

롤백하면 무엇이 되돌아가는가

파드 템플릿 전체 가 그 리비전 상태로 돌아갑니다.

항목되돌아가는가
컨테이너 이미지와 태그
환경 변수
자원 요청·상한
연결된 볼륨·ConfigMap·Secret 이름
복제본 수아니오. 현재 값을 유지합니다
ConfigMap·Secret 의 내용아니오. 참조만 되돌아갑니다
데이터베이스 데이터아니오

복제본 수가 그대로인 것은 의도된 동작입니다. 롤백은 "어떤 버전을 띄울지" 를 되돌리는 것이지 "몇 개를 띄울지" 를 되돌리는 것이 아닙니다.

ConfigMap 내용은 되돌아가지 않습니다. 설정값을 고친 것이 문제였다면 롤백만으로는 해결되지 않습니다. ConfigMap 도 함께 되돌려야 합니다(3.4 장).

롤백 뒤에 확인할 것

확인어디에서
파드가 새로 떠서 준비 상태가 되었는가워크로드 > Pod (3.1 장)
이미지 태그가 의도한 것인가Deployment 상세의 컨테이너
이력에서 리비전이 늘었는가배포 히스토리

롤백해도 리비전 번호는 앞으로 나아갑니다. 리비전 5에서 3으로 되돌리면 내용은 3과 같은 리비전 6이 만들어집니다. 되돌린 것도 하나의 배포로 기록되기 때문입니다.

롤백이 안 될 때

증상원인조치
되돌릴 리비전이 목록에 없음보관 개수를 넘어 지워졌습니다아래 "이력 보관 개수" 참고
롤백했는데 파드가 안 뜸그때 쓰던 이미지가 레지스트리에서 지워졌습니다이미지를 다시 올리거나 재빌드
롤백했는데 증상이 그대로원인이 애플리케이션이 아니라 설정·데이터에 있습니다ConfigMap·Secret·외부 연동 확인
StatefulSet 에 롤백 버튼이 없음지원하지 않습니다아래 참고

StatefulSet 은 이력만 보고 롤백할 수 없습니다. 파드마다 저장 공간이 연결되어 있어 버전을 되돌려도 데이터는 그대로이고, 옛 버전이 새 형식의 데이터를 읽지 못할 수 있기 때문입니다. 되돌려야 하면 편집에서 이미지 태그를 직접 이전 값으로 고치고, 데이터 호환성을 먼저 확인하십시오.

이력 보관 개수

Deployment 상세의 리비전 히스토리 제한 값만큼 이력이 남습니다. 기본은 10입니다.

이 수를 넘으면 오래된 리비전부터 지워지고, 지워진 리비전으로는 롤백할 수 없습니다. 배포가 잦은 애플리케이션이라면 값을 늘려 두십시오.

목록에서 복제본 0 인 ReplicaSet 을 지우지 마십시오. 그것이 이력입니다.