k8s application lifecycle management

yeongjin·2025년 10월 7일

Deployment 객체의 update와 rollback

  • Deployment 객체를 처음 생성하거나 Deployment Pod의 이미지 버전 변경 같은 것이 있을 때 Rollout이 실행된다.
  • 새로운 Rollout은 새로운 ReplicaSet을 생성하고, Deployment의 Revision 버전을 갱신한다.
  • Revision 기록을 통해 Rollback도 가능하다.
  • kubectl rollout status : Rollout 상태 확인
  • kubectl rollout history : Rollout Revision 기록 확인
  • kubectl rollout undo : Rollback 명령어

Deployment 객체의 배포 전략

  • Recreate : 기존 버전의 Pod를 모두 제거한 후, 새로운 버전의 Pod를 생성한다. 때문에 downtime이 발생할 수 밖에 없다.
  • Rolling Update (기본값) : 오래된 버전의 Pod를 하나씩 내리면서 동시에 새로운 버전의 Pod를 하나씩 올린다.

Dockerfile의 CMD, ENTRYPOINT값

  • Dockerfile로 이미지를 만들때, CMD 또는 ENTRYPOINT 값 설정을 통해 컨테이너에서 실행될 프로세스에 전달될 argument들을 정의할 수 있다.
  • ENTRYPOINT vs CMD : 아래 표 참고
Dockerfile 정의docker run 명령어프로세스에 전달될 argument
ENTRYPOINTENTRYPOINT ["sleep"]docker run my-image 10sleep 10
CMDCMD ["sleep", "5"]docker run my-image 1010
  • ENTRYPOINT에는 실행할 프로그램을 정의하고 CMD에는 ENTRYPOINT에 전달될 기본 인자를 정의하여 같이 사용할 수도 있다.

Pod 정의 파일에서 ENTRYPOINT, CMD 값 overriding하기

  • command 필드 : ENTRYPOINT 값을 override
  • args 필드 : CMD 값을 override
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    command: ["sleep-2.0"] # <-- Dockerfile의 ENTRYPOINT ["sleep"]을 "sleep-2.0"으로 오버라이드
    args: ["10"]           # <-- ENTRYPOINT 뒤에 덧붙여질 인자

Pod의 환경변수 설정

  • Pod 정의 파일에서 환경변수 값을 주입할 수 있다.
  • value 속성을 사용할 경우 직접 환경변수 값을 명시할 수 있고, envFrom 또는 valueFrom 속성을 사용할 경우 환경변수 값을 ConfigMap이나 Secret에서 가져온다.
# value 속성 사용
apiVersion: v1
kind: Pod
metadata:
  name: env-value-pod
spec:
  containers:
  - name: my-container
    image: busybox
    command: ["sh", "-c", "echo '앱 환경:' $APP_ENV ' / 버전:' $APP_VERSION && sleep 3600"]
    env:
    - name: APP_ENV         # 환경변수 이름
      value: "production"   # 고정된 값 (문자열)
    - name: APP_VERSION
      value: "v1.0.0"
# valueFrom 속성 사용
apiVersion: v1
kind: Pod
metadata:
  name: env-from-configmap-pod
spec:
  containers:
  - name: my-container
    image: busybox
    command: ["sh", "-c", "echo '로그 레벨:' $LOG_LEVEL && sleep 3600"]
    env:
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config        # 참조할 ConfigMap의 이름
          key: APP_COLOR          # ConfigMap에서 가져올 Key

ConfigMap

  • 환경 변수 값을 Pod 정의 파일에서 분리하여 중앙에서 관리하기 위해 ConfigMap을 사용할 수 있다.
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_COLOR: blue
  DB_HOST: mysql-service
  • Pod Volume에 ConfigMap 파일을 마운트하여 프로세스가 설정값을 읽도록 할 수도 있다.

Secret

  • 민감한 정보를 저장할 때는 ConfigMap 객체보다 Secret 객체를 사용하여 Base64 형태의 인코딩된 형식으로 저장하는 것이 권장된다.
apiVersion: v1
kind: Secret
metadata:
  name: my-database-secret # Secret의 이름
data:
  # Secret 데이터는 key-value 쌍으로 정의하며, value는 반드시 Base64로 인코딩되어야 합니다.
  username: YWRtaW4= # 'admin'을 Base64 인코딩
  password: cGFzc3dvcmQ= # 'password'를 Base64 인코딩
  • Pod에 Secret 객체 주입 방법은 ConfigMap과 유사하다.
  • Secret을 사용하더라도 암호화되어 저장되지는 않는다. etcd에 접근이 가능하다면 누구나 쉽게 Secret 값 평문을 확인할 수 있다. 때문에 보안을 위해 EncryptionConfiguration 객체를 만들어 kube-apiserver 설정에 등록해 Secret 값이 암호화가 되어 etcd에 저장되게 할 수도 있다.

Multi Container Pod

  • 때로는 두 서비스가 함께 작동해야 할 때가 있는데 이런 경우 Multi Container Pod를 사용할 수도 있다
  • 한 Pod 내의 Container들은 함께 생성되고 파괴되며, 네트워크 공간(localhost로 통신 가능)과 스토리지 볼륨을 기본적으로 공유한다.

Multi Container Pod의 디자인 패턴

  • Co-located Containers : 순서 없이 동시에 시작하여 Pod의 전체 lifecycle 동안 계속 실행됨
spec:
  containers:
  - name: container-one
    image: image-a
  - name: container-two
    image: image-b
# 두 컨테이너가 순서 없이 동시에 시작되어 계속 실행됨
  • Init Containers : 메인 컨테이너보다 먼저 순차적으로 실행되고, 작업을 완료하면 종료된다. 모든 Init Container가 성공적으로 종료된 후에만 메인 컨테이너가 시작된다.
spec:
  initContainers:
  - name: wait-for-db
    image: init-image-db
    command: 'wait_for_db_script.sh'
  - name: api-checker
    image: init-image-api
    command: 'wait_for_api_script'
  containers:
  - name: main-app
    image: main-app-image
# 1. wait-for-db가 실행되고 종료.
# 2. api-checker가 실행되고 종료.
# 3. main-app이 시작되어 Pod 종료까지 실행.
  • Sidecar Containers : 메인 컨테이너보다 먼저 시작하여 함께 계속 실행되다가, 메인 컨테이너 종료후 종료 로그까지 확인하고 끝난다. 이 방식은 특히 로깅, 모니터링 기능을 앱 코드에 포함시키지 않고 독립적으로 관리하고자 할 때 유용하다.
spec:
  initContainers:
  - name: log-shipper
    image: image-logger
	command: 'setup-logger.sh'
	restartPolicy: Always
  containers:
  - name: main-app
	image: main-app-image

Kubernetes의 Scaling

  • Pod Scaling
유형의미Manual 방식Automated 방식
HorizontalPod를 추가/제거kubectl scale 명령어 사용HPA
Vertical기존 Pod의 CPU/Memory 할당량 증가Pod의 requests, limits 값 변경VPA
  • Node Scaling
유형의미Manual 방식Automated 방식
HorizontalCluster에 Node를 추가/제거새 Node를 수동으로 추가Cluster Autoscaler
Vertical기존 Node의 CPU/Memory 증가서버 downtime이 발생하기 때문에 일반적으로 사용되지 않음x

Horizontal Pod Autoscaler

  • HPA는 Deployment/StatefulSet/ReplicaSet에 있는 Pod의 개수를 CPU, 메모리, 또는 커스텀 메트릭을 기반으로 자동으로 늘리거나 줄인다.
  • CPU/Memory 같은 표준 메트릭 정보로 오토스케일링을 진행한다면 Metrics Server가 클러스터에 실행되고 있어야 작동한다.
apiVersion: autoscaling/v2 # v2 API 버전 사용
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:         # HPA가 모니터링할 대상 리소스 지정
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization # 목표를 사용률(Utilization)로 설정
        averageUtilization: 50 # 50%를 목표로 설정

In-place Resizing

  • k8s v1.32 기준으로 pod resource 할당량을 변경하면, k8s는 기존 pod를 삭제하고 새로운 pod를 생성하여 변경사항을 적용하는 것이 기본동작이다. 이런 방식을 사용할 경우 pod가 재생성되는 과정에서 서비스 중단이 발생한다.
  • In-place Resizing 기능을 사용하면 서비스 중단 없이 Pod의 resource 할당량을 실시간으로 변경할 수 있다. 클러스터의 Feature Flag인 InPlacePodVerticalScaling을 true로 설정하고 Pod 정의 파일에 resizePolicy 필드를 설정하여 In-place Resizing 기능을 활성화 시킬수 있다.

Vertical Pod Autoscaler

  • VPA는 Metric을 지속적으로 모니터링하여 Deployment의 Pod에 할당된 리소스를 자동으로 늘리거나 줄인다.
  • VPA는 k8s에 기본 내장되어있지 않으므로, 별도로 배포(github repository의 정의 파일을 이용)해야 한다.
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePlicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
      - containerName: "my-app"
        minAllowed:
          cpu: "250m"
        maxAllowed:
          cpu: "2"
        controlledResources: ["cpu"]

VPA의 구성 요소와 updateMode

  • VPA를 배포하면 Recommender, Updater, Admission Controller 3가지 구성요소가 Pod형태로 만들어진다.
  • Recommander : k8s의 자원 사용량을 지속적으로 모니터링 및 수집하고, 최적의 cpu 메모리 값을 추천한다.
  • Updater : Recommender의 정보를 받아 현재 최적이 아닌 리소스(CPU, 메모리)로 실행중인 파드를 감지하여 종료시킨다.
  • Admission Controller : Recommender의 추천 값을 사용하여 새로 생성되는 해당 Pod가 올바른 CPU 및 메모리 값으로 시작하도록 보장한다.
  • VPA 정의 파일에서 설정하는 updateMode 값은 4가지가 존재하며, VPA 구성요소들의 작동 방식을 결정한다.
모드작동 방식
Off추천만 제공하고 아무 작업도 하지 않는다. (Recommender만 작동)
InitialPod 생성 시에만 리소스를 변경하고 실행 중인 Pod는 변경하지 않는다. (Recommender, Admission Controller만 작동)
Recreate리소스 최적화가 안된 Pod들은 종료시켜 재시작을 유도한다. (3가지 VPA 구성요소 모두 작동)
Auto현재는 Recreate와 동일하지만, 향후 버전에서는 In-Place Resizing을 지원하는 모드가 될 것이다.

0개의 댓글