쿠버네티스는 어떻게 애플리케이션을 스케일링하는가설명디플로이먼트와 레플리카셋을 이용한 부하 스케일링데몬셋을 이용한 스케일링으로 고가용성 확보하기관리 대상 리소스(파드)는 남겨둔채 데몬셋만 삭제쿠버네티스의 객체 간 오너십
쿠버네티스는 어떻게 애플리케이션을 스케일링하는가
쿠버네티스에서는 동일한 애플리케이션이 돌아가는 파드를 replica 라고 함
파드는 직접 실행하는 경우가 드물고, 파드를 관리하는 다른 리소스를 정의하여 사용한다. 이런 리소스를
컨트롤러
라고 함. 그 후로 컨트롤러 중에서도 디플로이먼트
를 주로 사용함컨트롤러 리소스 정의는 파드의 템플릿을 포함함. 컨트롤러 리소스는 파드를 생성하고 대체하는 데 이 템플릿을 사용

- 레플리카셋이 파드를 관리함. 레플리카셋에서 레플리카 수를 변경하면 파드가 추가되거나 감소
- 관리하던 파드가 사라지면 레플리카셋이 대체 파드를 생성함
- 파드는 컨테이너를 관리. 관리하던 컨테이너가 종료되면 대체 컨테이너를 생성
- 디플로이먼트는 레플리카셋을 관리.
- 디플로이먼트 -(관리)→ 레플리카셋 -(관리)→ 파드
- 디플로이먼트 없이 레플리카셋을 바로 만들 수도 있음
apiVersion: apps/v1 kind: ReplicaSet metadata: name: whoami-web labels: kiamol: ch06 spec: replicas: 1 selector: matchLabels: app: whoami-web template: # 일반적인 파드 정의 metadata: labels: app: whoami-web spec: containers: - image: kiamol/ch02-whoami name: web ports: - containerPort: 80 name: http
- 디플로이먼트 정의와 차이점은 리소스 유형(
kind
)과 파드 수를 기재한replicas
필드가 있다는 것 뿐임
# 레플리카셋 목록 조회 kubectl get rs
설명

- 쿠버네티스의 스케일링이 간단한 것은 이런 네트워킹과 컴퓨팅을 분리하는 추상화 덕분임.
- 네트워킹 : 서비스
- 컴퓨팅 : 파드
- 서비스의 레이블 셀렉터도 레플리카셋의 레이블 셀렉터와 동일한 레이블을 가진 리소스를 찾음. 따라서 모든 파드가 서비스의 엔드포인트로 추가됨
- 레플리카셋은 레이블 셀렉터로 자신이 관리하는 파드를 식별. 이 레이블은 레플리카셋이 파드를 만들 때 부여되고 그러므로 레플리카셋이 파드 수를 변경하면 그 변경도 서비스의 엔드포인트에 반영됨
- 로드밸런싱은 쿠버네티스에 있는 모든 유형의 서비스가 가진 기능임(LoadBalancer, ClusterIP ..)
디플로이먼트와 레플리카셋을 이용한 부하 스케일링

- 디플로이먼트는 여러 개의 레플리카셋을 관리할 수 있다.
- v2 업데이트는 v1 레플리카의 파드 수를 0으로 줄이는 것과 같다.
- 디플로이먼트에 스케일링을 적용하려면 레플리카셋과 마찬가지로
replicas
필드가 있어야 함 - 디플로이먼트를 스케일링하면 먼저 기존 레플리카셋의 레플리카 수만 수정
- 하지만 디플로이먼트에서 파드 정의를 변경했다면 대체 레플리카셋을 생성한 후 기존 레플리카셋의 레플리카 수를 0으로 만듦
kubectl apply -f pi/web/ kubectl get rs -l app=pi-web NAME DESIRED CURRENT READY AGE pi-web-cfcbc4f49 2 2 2 8s # replicas 필드 3으로 변경 -> replica set 의 pod 수 3개로 변경됨 kubectl apply -f pi/web/update/web-replicas-3.yaml kubectl get rs -l app=pi-web NAME DESIRED CURRENT READY AGE pi-web-cfcbc4f49 3 3 3 67s # pod 정의 변경 -> 기존의 replicaset의 pod 수를 0으로 만들고 새 replicaset 생성 kubectl apply -f pi/web/update/web-logging-level.yaml # rs 목록 NAME DESIRED CURRENT READY AGE pi-web-686686697b 3 3 3 14s pi-web-cfcbc4f49 0 0 0 108s kubectl get pod NAME READY STATUS RESTARTS AGE pi-web-686686697b-g9vd9 1/1 Running 0 30s pi-web-686686697b-lzwfm 1/1 Running 0 23s pi-web-686686697b-ww4fl 1/1 Running 0 26s kubectl get rs -l app=pi-web --show-labels NAME DESIRED CURRENT READY AGE LABELS pi-web-686686697b 3 3 3 8m58s app=pi-web,pod-template-hash=686686697b pi-web-cfcbc4f49 0 0 0 10m app=pi-web,pod-template-hash=cfcbc4f49
686686697b
). 파드 템플릿의 해시값은 레이블에 포함되어 있음데몬셋을 이용한 스케일링으로 고가용성 확보하기
데몬셋은 클러스터 내 모든 노드 또는 셀렉터와 일치하는 일부 노드에서 단일 레플리카 또는 파드로 동작하는 리소스를 의미함
데몬셋은 각 노드에서 정보를 수집하여 중앙의 수집 모듈에 전달하거나 하는 인프라 수준의 관심사와 관련된 목적으로 많이 쓰인다.
apiVersion: apps/v1 kind: DaemonSet metadata: name: pi-proxy labels: kiamol: ch06 spec: selector: matchLabels: app: pi-proxy template: metadata: labels: app: pi-proxy spec: containers: ...
apiVersion: apps/v1 kind: DaemonSet metadata: name: pi-proxy labels: kiamol: ch06 spec: selector: matchLabels: app: pi-proxy template: metadata: labels: app: pi-proxy spec: containers: - image: nginx:1.17-alpine name: nginx ports: - containerPort: 80 name: http volumeMounts: - name: config mountPath: "/etc/nginx/" readOnly: true - name: cache-volume mountPath: /data/nginx/cache volumes: - name: config configMap: name: pi-proxy-configmap - name: cache-volume hostPath: path: /volumes/nginx-cache type: DirectoryOrCreate nodeSelector: kiamol: ch06
- 노드에 원하는 레이블을 부여하고 파드 정의에서
nodeSelector
필드를 추가하면 됨
# 셀렉터와 일치하는 레이블을 노드에 부여 kubectl label node $(kubectl get nodes -o jsonpath='{.items[0].metadata.name}' kiamol=ch06 --overwrite # 파드의 상태를 다시 확인 kubectl get ds pi-proxy
- nodeSelector 필드를 추가하고 해당 node label 이 없으면 DaemonSet의 파드 수가 0이 됨. 그 후 노드에 레이블을 부여하면 데몬셋의 레플리카 수도 해당하는 노드 갯수만큼 생성
관리 대상 리소스(파드)는 남겨둔채 데몬셋만 삭제
모든 컨트롤러 리소스는 자신이 관리하는 파드의 생애 주기를 관장하지만, 대상 파드와 연결이 끊길 수 있다.
# 관리 대상 파드는 남겨둔채 데몬셋만 삭제 kubectl delete ds pi-proxy --cascade=orphan # 파드 상태 확인 kubectl get pod -l app=pi-proxy # 데몬셋을 다시 생성 # 데몬셋과 파드의 상태를 확인 kubectl get ds pi-proxy kubectl get po -l app=pi-proxy # cascade 옵션 없이 데몬셋 삭제 -> 파드 다 삭제 # 파드 상태 확인
- 관리 대상 리소스는 남겨 둔채 컨트롤러 리소스만 삭제하는 기능은 자주 사용할 일은 없어도 필요할 때는 매우 유용함. 기존 파드에는 문제 없는데 노드에 유지 보수 작업을 해야 할 때를 생각해보면 노드 작업을 마친 후 데몬셋을 다시 생성하면서 불필요하게 파드를 삭제하고 다시 생성하는 것보다 데몬셋만 간단하게 다시 생성하는 것이 더 낫다.
- 데몬셋은 고가용성을 위한 리소스이지만, 적합한 애플리케이션이 제한적임. 이를테면 각각의 인스턴스가 독립적인 데이터 저장소를 가져도 괜찮은 애플리케이션을 들 수 있음
- 고가용성이 필요하지만, 여러 인스턴스가 데이터 저장소를 공유할 필요도 함께 있다면 스테이트풀셋을 쓰는 것이 나음
쿠버네티스의 객체 간 오너십
- 컨트롤러 리소스는 레이블 셀렉터를 이용하여 자신의 관리 대상 리소스를 결정함
- 쿠버네티스에는 관리 주체가 사라진 객체를 찾아 제거하는 가비지 컬렉터가 있음. 객체 간 이런 오너십은 일종의 위계를 형성
# 각 파드의 관리 주체 리소스를 확인 kubectl get pod -o custom-columns=NAME:'{.metadata.name}',OWNER:'{.metadata.ownerReferences[0].name}',OWNER_KIND:'{.metadata.ownerReferences[0].kind}' NAME OWNER OWNER_KIND pi-proxy-78t6t pi-proxy DaemonSet pi-web-686686697b-g9vd9 pi-web-686686697b ReplicaSet pi-web-686686697b-lzwfm pi-web-686686697b ReplicaSet pi-web-686686697b-ww4fl pi-web-686686697b ReplicaSet whoami-web-hw5jd whoami-web ReplicaSet whoami-web-rqvbv whoami-web ReplicaSet whoami-web-skkdc whoami-web ReplicaSet # 각 레플리카셋의 관리 주체 리소스를 확인 kubectl get rs -o custom-columns=NAME:'{.metadata.name}',OWNER:'{.metadata.ownerReferences[0].name}',OWNER_KIND:'{.metadata.ownerReferences[0].kind}' NAME OWNER OWNER_KIND pi-web-686686697b pi-web Deployment pi-web-cfcbc4f49 pi-web Deployment whoami-web <none> <none>
- 쿠버네티스가 리소스 간 이런 의존 관계를 잘 관리하지만, 이들 관계가 형성되는 수단은 레이블셀렉터 하나 뿐임. 따라서 레이블을 멋대로 수정하면 이런 의존 관계가 깨질 수 있음