Pod
Pod
컨테이너 접속과 명령어 실행
- 생성된 컨테이너에 접속할 때는
kubectl exec 명령어를 사용하는데 가상 터니멀을 생성(-t)하고 표준 입력을 패스 스루(-i) 하면서 /bin/sh 를 실행하면 컨테이너에 SSH로 로그인 한 상태가 됨
- 정상 수행 중 인지 명령어 실행
kubectl exec -it sample-pod -- /bin/bash
apt update && apt -y install iproute2 procps
ip a | grep "inet"
ss -napt | grep LISTEN
kubectl exec -it sample-pod -- /bin/ls
kubectl exec -it sample-2pod -c nginx-container -- /bin/ls
kubectl exec -it sample-pod -- /bin/ls --all --classify
kubectl exec -it sample-pod -- /bin/bash -c "ls --all --classify | grep lib"
ENTRYPOINT 명령 /CMD 명령과 command/args
- 도커 파일로 이미지를 생성할 때는
ENTRYPOINT 명령과 CMD 명령을 사용하여 컨테이너 실행 시 명령어를 정의하는데 쿠버네티스에서는 도커용 용어와 조금 다르게 ENTRYPOINT를 command로 CMD 를 args 라고 부름
파드명 제한
- 이용 가능한 문자는 영문 소문자와 숫자
- 이용 가능한 기호는
- 와 .
- 시작과 끝은 영문 소문자
호스트의 네트워크 구성을 사용한 파드 기동
- 쿠버네티스에 기동하는 파드에 할당된 IP 주소는 쿠버네티스 노드의 호스트 IP 주소와 범위가 달라 외부에서 볼 수 없는 IP 주소가 할당됨
- 호스트의 네트워크를 사용하는 설정(
spec.hostNetwork)을 활성화하면 호스트상에서 프로세스를 기동하는 것과 같은 네트워크 구성(IP 주소, DNS 설정, host 설정 등)으로 파드를 기동시킬 수 있음
hostNetwork 를 사용한 파드는 쿠버네티스 노드의 IP 주소를 사용하는 관계로 포트 번호 충돌을 방지하기 위해 기본적으로 사용하지 않고, 사용할 때는 에지(edge) 환경에서의 사용이나 호스트 측의 네트워크를 감시 또는 제어와 같은 특수한 애플리케이션 등에서만 사용
파드 DNS 설정과 서비스 디스커버리
- DNS 서버에 관한 설정(dnsPolicy)은 파드 정의
spec.dnsPolicy 에 설정
- dnsPolicy 설정값
ClusterFirst(기본값)
- 일반적으로 파드는 클러스터 내부 DNS 를 사용하여 이름을 해석
- 서비스 디스커버리나 클러스터 내부 로드 밸런싱에서 사용
- dnsPolicy 가 ClusterFirst 인 경우 클러스터 내부의 DNS 서버ㅔ 질의를 하고 클러스터 내부 DNS에서 해석이 안 되는 도메인에 대해서는 업스트림 DNS 서버에 질의
None
- 특별한 요건에 따라서는 클러스터 외부 DNS 를 참조하는 경우도 있음
- DNS 서버를 수동으로 설정하려면
spec.dnsPolicy: None 이라고 설정한 후 dnsConfig에 설정하고 싶은 값을 작성
- 정적으로 외부 DNS 서버만 설정하면 클러스터 내부 DNS를 사용한 서비스 디스커버리는 사용할 수 없게 되므로 주의
Default
- 쿠버네티스 노드의 DNS 설정을 그대로 상속받는 경우에는
spec.dnsPolicy: Default 로 설정
- dnsPolicy 의 기본값은 Default 가 아니므로 주의
- 쿠버네티스 노드의 DNS 설정을 상속받게 설정하면 클러스터 내부의 DNS를 사용한 서비스 디스커버리를 할 수 없음
ClusterFirstWithHostNet
- hostNetwork 를 사용한 파드에 클러스터 내부의 DNS를 참조하고 싶은 경우에는
spec.dnsPolicy: ClusterFirstWithHostNet 을 설정
- hostNetwork 를 사용하는 경우 기본값 ClusterFirst 의 설정값은 무시되고 쿠버네티스
ClusterFirstWithHostNet 을 지정해야 함
정적 호스트명 설정
- 리눅스 운영체제에서는 DNS로 호스트명을 해석하기 전에
/etc/hosts 파일로 정적 호스트명을 해석
- 쿠버네티스에서는 파드 내부 모든 컨테이너의
/etc/hosts 를 변경하는 기능이 준비되어 있으며 spec.hostAliases 로 지정하여 사용
작업 디렉터리 설정
- 컨테이너에서 동작하는 애플리케이션의 작업 디렉러티(Working Directory) 는 도커 파일의
WORKDIR 명령 설정을 따르지만, spec.containers[].workingDir 로 덮어 쓸 수 있음
- 특정 스크립트 등이 배치된 볼륨을 파드에 마운트할 때 그 스크립트가 배치된 디렉터리로 이동한 후 실행하고 싶은 경우가 있는데 이는 작업 디렉터리를 변경하는 기능을 사용하여 해결할 수 있음
- 컨테이너에
workingDir 을 설정한 경우 프로세스가 실행되는 디렉터리가 변경된 것을 확인할 수 있음
ReplicaSet / ReplicationController
개요
- Replicaset은 일정한 개수의 동일한 Pod가 항상 실행되도록 관리하는데 이러한 기능이 필요한 이유는 서비스의 지속성 때문
- 노드의 하드웨어에서 발생하는 장애 등의 이유로 파드룰 사용할 수 없을 때 다른 노드에서 파드를 다시 생성해서 사용자에게 중단 없는 서비스를 제공할 수 있음
- 원래 파드의 레플리카를 생성하는 리소스의 이름은 레플리케이션 컨트롤러였는데 레플리카셋을 추가하고 일부 기능을 추가
- 레플리케이션 컨트롤러는 앞으로 사용하지 않는 추세이기 때문에 기본적으로 레플리카셋을 사용하는 것을 권장
파드 정지와 자동화된 복구
- 레플리카셋에서는 노드나 파드에 장애가 발생했을 때 지정한 파드 수를 유지하기 위해 다른 노드에서 파드를 기동시켜 주기 때문에 장애 시에도 많은 영향을 받지 않는데 이것이 쿠버네티스의 중요한 콘셉트 중 하나로
자동화된 복구라는 기능
레플리카셋과 레이블
- 레플리카셋은 쿠버네티스가 파드를 모니터링하여 파드 수를 조정
- 모니터링은 특정 레이블을 가진 파드 수를 계산하는 형태로 이루어 짐
- 레플리카 수가 부족한 경우 매니페스트에 기술된
spec.template 로 파드를 생성하고 레플리카 수가 많을 경우 레이블이 일치하는 파드 중 하나를 삭제
일치성 기준 조건과 집합성 기준 조건
- 레플리카 제어 조건은 서비스 중단 예정인 레플리케이션 컨트롤러의 일치성 기준(
equality-based) 셀렉터였지만, 레플리카셋에서는 좀 더 강화된 집합성 기준(set-based) 셀렉터를 사용하여 유연한 제어도 가능
- 일치성 기준(equality-based): 조건부에 일치 불일치(
=, !=) 조건 지정
- 집합성 기준(set-based): 조건부에 일치 불일치(
=, !=) 조건 지정과 집합(in, notin, exists) 조건 지정 가능
- 쿠버네티스에서 어떤 조전을 지정할 때는 이 두 가지 방법이 있고, 레플리카셋 외에 스케줄링할 때도 이 조건 지정이 사용됨
- 일치성 기준 조건에서는 조건부에 같은지 혹은 같지 않은지에 대한 조건을 사용할 수 있는데
app=sample-app 과 같이 지정하는 것
- 집합성 기준 조건에서는 일치성 기준 조건과 함께 집합 조건을 지정할 수 있는데
env ln [development, staging] 과 같이 지정할 수 있으며 ln 에 해당하는 연산자는 스케줄링 조건에서 사용할 때 수치 비교도 가능
Deployment
Deployment → ReplicaSet → Pods
개요
- 여러 레플리카셋을 관리하여 롤링 업데이트나 롤백 등을 구현하는 리소스
- 디플로이먼트가 레플리카셋을 관리하고 레플리카셋이 파드를 관리하는 관계
- 디플로이먼트는 레플리카셋의 상위 개념으로서 파드의 개수를 유지할 뿐만 아니라 배포 작업을 좀 더 세분화해 관리할 수 있음
- 디플로이먼트를 사용하면 신규 레플리카셋에 컨테이너가 기동되었는지와 헬스 체크는 통과했는지를 확인하면서 전환 작업이 진행되며 레플리카셋의 이행 과정에서 파드 수에 대한 상세한 지정도 가능
- 쿠버네티스에서 가장 권장하는 컨테이너 기동 방법으로 알려져 있음
- 하나의 파드를 기동만 하더라도 디플로이먼트 사용을 권장하는데 파드로만 배포한 경우에는 파드에 장애가 발생하면 자동으로 파드가 다시 생성되지 않으며 레플리카셋으로만 배포한 경우에는 롤링 업데이트 등의 기능을 사용할 수 없음
레플리카셋이 생성되는 조건
- 다플로이먼트에서는 변경이 발생하면 레플리카셋이 생성되는데 변경에는 레플리카 수의 변경 등은 포함되어 있지 않으며 생성된 파드의 내용 변경이 필요
spec.template 에 변경이 있으면 생성된 파드의 설정이 변경되기 때문에 레플리카셋을 신규로 생성하고 롤링 업데이트를 수행
- 실제로 매니페스트를 쿠버네티스에 등록한 후 레플리카셋의 정의를 보면,
spec.template 아래의 해시값(파드 템플릿 해시 - Pod Template Hash) 을 계산하고 이 값을 사용한 레이블로 관리
- 수작업으로 이미지 등을 이전 버전으로 재변경하여 해시값이 동일해진 경우에는 레플리카셋을 신규로 생성하지 않고 기존 레플리카셋을 사용
디플로에먼트에 속한 파드의 삭제 및 복구 과정

변경 롤백
- 디플로이먼트에는 롤백 기능이 있음
- 롤백 기능의 실체는 현재 사용 중인 레플리카셋의 전환과 같은 것
- 디플로이먼트가 생성한 기존 레플리카셋은 레플리카 수가 0인 상태로 남아 있기 때문에 레플리카 수를 변경시켜 다시 사용할 수 있는 상태가 됨

- 변경 이력을 확인할 때는
kubectl rollout history 명령어를 사용하는데 CHANGE-CAUSE 부분은 디플로이먼트를 생성할 때 --record 옵션을 사용하여 이력 내용이 있지만 --record 옵션을 사용하지 않았다면 <none>
실제 환경에서는 롤백 기능을 사용하는 경우가 많지 않은데, CI/CD 파이프라인에서 롤백을 하는 경우 kubectl rollout 명령어보다 이전 매니페스트를 다시 kubectl apply 명령어로 실행하여 적용하는 것이 호환성 면에서 더 좋기 때문이며, spec.template 을 같은 내용으로 되돌렸던 경우에는 pod-template-hash 값이 같기 때문에 kubectl rollout 처럼 기존에 있었던 레플리카셋의 파드가 기동됨
업데이트 전략
- Deployment 의 배포 전략은 주로 애플리케이션이 변경될 때 사용
- 이전 버전의 애플리케이션에서 업데이트가 필요한 경우에 주로 사용되며 방법으로는
RollingUpdate, Recreate 가 있음
- 기본 전략은
RollingUpdate
recreate

- 재생성(recreate) 업데이트는 모든 이전 버전(V1)의 파드를 모두 한 번에 종료하고 새 버전(V2)의 파드로 일괄적으로 교체하는 방식
- 빠르게 교체할 수 있지만 새로운 버전의 파드에 문제가 발생하면 대처가 늦어질 수 있음
RollingUpdate

-
롤링 업데이트는 새 버전의 애플리케이션을 배포할 때 새 버전의 애플리케이션은 하나씩 늘려가고 기존 버전의 애플리케이션은 하나씩 줄여나가는 방식
-
쿠버네티스에서 사용하는 표준 배포 방식
-
새로운 버전(v2)으로 배포된 파드에 문제가 발생하면 다시 이전 버전(v1)의 파드로 서비스를 대체할 수 있어서 상당히 안정적인 배포 방식이지만 업데이트가 느리게 진행된다는 단점이 있음
-
maxSurge
- 롤링 업데이트를 위해 최대로 생성할 수 있는 파드 개수
- maxSurge 를 높게 설정하면 롤링 배포를 빠르게 적용 가능
% 또는 개수로 지정 가능
- 설정하지 않을 경우 기본 값은
25%
-
maxUnavailable
- 롤링 업데이트 중 최대로 삭제할 파드 개수
- maxUnavailable 을 높게 설정하면 롤링 배포를 빠르게 적용 가능
- 한 번에 많은 파드를 삭제할 경우 트래픽이 남아있는 소수의 파드로 집중될 수 있어 값을 적절히 설정 필요
% 또는 개수로 지정 가능
- 설정하지 않을 경우 기본 값은
25%
-
maxUnavailable=0 / maxSurge=1

-
maxUnavailable=1 / maxSurge=0

블루/그린 업데이트

- 블루/그린 업데이트는 애플리케이션의 이전 버전(블루, v1 pod)과 새 버전(그린, v2 pod)을 동시에 운영
- 서비스 목적으로 접속할 수 있는 것은 새 버전의 파드만 가능하며 이전 버전의 파드는 테스트 목적으로만 접속할 수 있음
- 새로운 버전의 파드에 문제가 발생했을 때 빠르게 대응할 수 있으며 안정적으로 배포할 수 있음
- 많은 파드가 필요하므로 그만큼 많은 자원이 필요하다는 단점이 있블로
- 블루/그린 업데이트를 이용해 애플리케이션을 배포할 때는 version으로 구분해 관리
- green 배포용 yaml 파일을 생성하는데 이전 버전의 배포 yaml 파일과 내용이 같지만 사용하는 이미지의 경로와 labels 의 version 만 수정
Canary 업데이트
- Canary 업데이트는 블루/그린과 비슷하지만 더 진보적인 단계적 접근 방식
- Canary는 주로 애플리케이션의 몇몇 새로운 기능을 테스트할 때 사용
- Canary는 두 개의 버전을 모두 배포하지만 새 버전에는 조금씩 트래픽을 증가시켜(처음에는 5% 정도의 트래픽만 흘려 보내지만 나중에는 50%의 트래픽을 흘려보냄) 새로운 기능들을 테스트
- 기능 테스트가 끝나고 새 버전에 문제가 없다고 판단하면 이전 버전은 모두 종료시키고 새 버전으로만 서비스
- Canary 업데이트용 새로운 배포 파일을 생성하는데
track: canary 를 통해 Canary 업데이트를 만들어 줄 수 있음
- Canary 업데이트의 문제점
- 한명의 유저가 서비스를 사용할 때 로드밸런서에 의해 자동으로 여러 서버에 접속될 수 있음
- 유저가 새로고침을 할 때 로드 밸런싱이 일어나서 구버전/신버전으로 바뀌게 되는 문제가 생길 수 있음
- 스티키 세션을 사용하여 사용자가 한 번 특정한 서버에 접속되어 있으면 그 서버에만 계속 접속되도록 만들 수 있움
상세 업데이트 파라미터
minReadySeconds(최소 대기 시간- 초)
- 파드가 Ready 상태가 된 다음부터 디플로이먼트 리소스에서 파드 기동이 완료되었다고 판단(다음 파드의 교체가 가능하다고 판단하기까지의 최소 시간
revisionHistoryLimit(수정 버전 기록 제한)
- 디플로이먼트가 유지할 레플리카셋 수
- 롤백이 가능한 이력 수
progressDeadlineSeconds(진행 기한 시간(초))
- Recreate/Rollingllpdate 처리 타임아웃 시간
- 타임아웃 시간이 경과하면 자동으로 롤백
디플로이먼트 스케일링
- 디플로이먼트가 관리하는 레플리카셋의 레플리카 수는 레플리카셋과 같은 방법으로
kubectl apply -f 또는 kubectl scale 을 사용하여 스케일링
DaemonSet
개요

- ReplicaSet 의 특수한 형태
- 데몬셋은 모든 노드에 파드를 생성
- ReplicaSet 이 특정 개수의 파드를 유지할 때 사용하는 것이라면 데몬셋은 모든 노드에 파드를 배포할 때 사용
- 데몬셋은 레플리카 수를 지정할 수 없고 하나의 노드에 누 개의 파드를 배치할 수도 없음
- 파드를 배치하고 싶지 않은 노드가 있을 경우
nodeselector나 노드 안티어피니티를 사용한 스케줄링으로 예외 처리
- 쿠버네티스 노드를 늘렸을 때도 데몬셋의 파드는 자동으로 늘어난 노드에서 기동하기 때문에 데몬셋은 각 파드가 출력하는 로그를 호스트 단위로 수집하는 플루언트디나 각 파드 리소스 사용 현황 및 노드 상태를 모니터링 하는 데이터독 등 모든 노드에서 반드시 동작해야 하는 프로세스를 위해 사용하는 것이 유용
데몬셋 업데이트 전략: OnDelete & RollingUpdate
OnDelete
- OnDelete 에서는 데몬셋 매니페스트를 수정하여 이미지 등을 변경했더라도 기존 파드는 업데이트 되지 않음
- 디플로이먼트와 달리 데몬셋은 모니터링이나 로그 전송과 같은 용도로 많이 사용하기 때문에 업데이트는 다음 번에 다시 생성할 때나 수동으로 임의의 시점에 하게 되어 있으며 type 외에 지정할 수 있는 항목은 없음
- OnDelete로 설정하고 아무것도 하지 않을 경우 노드의 유지 보수를 이유로 파드가 정지되거나 예기치 못하게 파드가 정지되는 등 다양한 이유로 파드가 정지되어 다시 생성되기 전까지는 업데이트 되지 않기 때문에 운영상의 이유로 정지하면 안 되는 파드이거나 업데이트가 급하게 필요 없는 경우 OnDelete 설정으로 사용해도 되지만 이전 버전이 계속 장기간 사용된다는 점에 주의
- 임의의 시점에 파드를 업데이트 하는 경우에는 데몬셋과 연결된 파드를 kubectl delete pod 명령어로 수동으로 정지시키고 자동화된 복구 기능으로 새로운 파드를 생성해야 함
RollingUpdate
- 데몬셋도 디플로이먼트와 마찬가지로 RollingUpdate 를 사용한 업데이트가 가능
- 데몬셋에서는 하나의 노드에 동일한 파드를 여러 개 생성할 수 없으므로 디플로이먼트와 달리 동시에 생성할 수 있는 최대 파드 수(masSurge)를 설정할 수 없고 동시에 정지 가능한 최대 파드 수(maxUnavailable)만 지정하여 RollingUpdate를 수행
- maxUnavailable=2 의 경우 파드를 두 개씩 동시에 업데이트해 나가는 형태
- maxUnavailable 의 기본값은 1이며 maxUnavailable 을 0으로 지정할 수는 없음
StatefullSet
- 스테이트풀셋도 데몬셋과 마찬가지로 레플리카셋의 특수한 형태라고 할 수 있는 리소스
- 데이터베이스 등과 같은 스테이트풀한 워크로드에 사용하기 위한 리소스
- RepliaSet과 차이점
- 생성되는 파드명의 접미사는 숫자 인덱스가 부여된 것
- 파드명이 바뀌지 변경되어도 내용은 바뀌지 않음
- 데이터를 영구적으로 저정하기 위한 구조
- 스테이트풀셋에서는 spec.volumeClaimTemplates를 지정할 수 있는데 이 설정으로 스테이트풀셋으로 생성되는 각 파드에 영구 볼륨 클레임(영구 볼륨 요청)을 설정할 수 있으며 영구 볼륨 클레임을 사용하면 클러스터 외부의 네트워크를 통해 제공되는 영구 볼륨을 파드에 연결할 수 있으므로 파드를 재기동할 때나 다른 노드로 이동할 때 같은 데이터를 보유한 상태로 컨테이너가 다시 생성되고 영구 볼륨은 하나의 파드가 소유할 수도 있고 영구 볼륨 종류에 따라 여러 파드에서 공유할 수도 있음
스케일링
- 스케일링 수행
kubectl scale statefulset sample-statefulset --replicas=5
- 스테이트풀셋에서 레플리카 수를 변경하여 파드를 생성하고 삭제하면 레플리카셋이나 데몬셋 등과 달리 기본적으로 파드를 동시에 하나씩만 생성하고 삭제하기 때문에 조금 시간이 걸림
- 스케일 아웃일 때는 인덱스가 가장 작은 것부터 파드를 하나씩 생성하고 이전에 생성된 파드가 Ready 상태가 되고 나서 다음 파드를 생성하기 시작하는데, 위 예제에서는
sample-statefulset-0, sample-statefulset-1, sample-statefulset-2 순서로 생성
- 스케일 인일 때는 인덱스가 가장 큰 파드(가장 최근에 생성된 컨테이너)부터 삭제되므로 2 → 1 → 0 순서로 삭제
라이프사이클
- 스테이트풀셋에서도
spec.podManagementPolicy 를 Parallel 로 설정하여 레플리카셋 등과 마찬가지로 병렬로 동시에 파드를 기동시킬 수 있음
spec.podManagementPolicy 기본값은 OrderReady 로 설정되어 있음
업데이트 전략
OnDelete
- OnDelete 에서는 스테이트풀셋 매니페스트를 수정하여 이미지 등을 변경했더라도 기존 파드는 업데이트 되지 않음
- 스테이트풀셋에서 OnDelete는 영속성 영역을 가진 데이터베이스나 클러스터 등에서 많이 사용되기 때문에 수동으로 업데이트 하고 싶을 경우 OnDelete 를 사용하여 임의의 시점에서나 다음에 재기동할 때 업데이트를 진행하게 되어 있는데 type 외에 지정할 수 있는 항목은 없음
RollingUpdate
- 디플로이먼트와 마찬가지로 롤링업데이트를 사용한 스테이트풀셋 업데이트가 가능하지만 스테이트풀셋에는 영속성 데이터가 있으므로 디플로이먼트와 다르게 추가 파드를 생성해서 롤링 업데이트를 할 수 없고, 동시에 정지 가능한 최대 파드 수(maxUnavailable)를 지정하여 롤링 업데이트를 할 수도 없으므로 파드마다 Ready 상태인지를 확인하고 업데이트
spec.podManagementPolicy가 Parallel로 설정되어 있는 경우에도 병렬로 동시에 처리되지 않고 파드 하나씩 업데이트
- 스테이트풀셋의 RollingUpdate에서는 partition이라는 특정 값을 설정할 수 있는데 partition을 설정하면 전체 파드 중 어떤 파드까지 업데이트할지를 지정할 수 있고 이 설정을 사용하면 전체에 영향을 주지 않고 부분적으로 업데이트를 적용하고 확인할 수 있어 안전한 업데이트를 할 수 있음
- OnDelete와 달리 수동으로 재기동한 경우에도 partition 값보다 작은 인덱스를 가진 파드는 업데이트되지 않음
삭제
- 스테이트풀셋을 생성하면 파드에 영구 볼륨 클레임(영구 볼륨 요청(을 설정할 수 있어 영구 볼륨도 동시에 확보할 수 있음
- 영구 볼륨은 스테이프풀셋이 삭제되어도 동시에 해제되지 않음
- 스테이트풀셋이 영구 볼륨을 해제하기 전에 볼륨에서 데이터를 백업할 수 있도록 시간을 주기 때문
- 스테이트풀셋을 삭제하고 스테이트풀셋이 영구 볼륨 클레임으로 확보한 영구 볼륨을 해제하지 않고 다시 스테이트풀셋을 생성한 경우 영구 볼륨 데이터는 그대로 파드가 기동되는데 스케일 인하여 레플리카 수를 줄인 경우도 마찬가지
- 스테이트풀셋을 삭제해도 영구 볼륨이 확보된 상태일 경우 비용이 발생
- 관리형 서비스의 종량 과금 방식인 경우 볼륨을 그대로 유지하면 비용이 발생하고 온프레미스 환경인 경우에도 디스크 공간이 확보된 상태로 남아 있기 때문에 스테이트풀셋을 삭제한 후에는 확보된 영구 볼륨도 해제해야 함
- 스테이트풀셋이 확보한 영구 볼륨 해제
kubectl delete persistentvolumeclaims www-sample-statefulset-{0..4}