ConfigMap을 통한 구성 업데이트

ConfigMap을 통한 구성 업데이트 (Updating Configuration via a ConfigMap)

이 페이지는 ConfigMap을 통해 파드 내의 구성을 업데이트하는 단계별 예시를 제공하며, 파드가 ConfigMap을 사용하도록 구성 작업을 기반으로 이어져요. 이 튜토리얼이 끝나면 실행 중인 애플리케이션의 구성을 변경하는 방법을 이해하게 돼요. 이 튜토리얼은 예시로 alpine과 nginx 이미지를 사용해요.

출처: 문서

본문

시작하기 전에 (Before you begin)

Kubernetes 클러스터가 있어야 하고 kubectl 명령줄 도구가 클러스터와 통신하도록 구성되어 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트로 작동하지 않는 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 이용해 만들거나, 아래 Kubernetes 플레이그라운드 중 하나를 사용할 수 있어요.

터미널이나 명령 프롬프트에서 HTTP 요청을 하려면 curl(https://curl.se/) 명령줄 도구가 필요해요. curl이 없으면 설치할 수 있어요. 로컬 운영체제의 문서를 확인해주세요.

목표 (Objectives)

  • 볼륨으로 마운트된 ConfigMap을 통해 구성 업데이트
  • ConfigMap을 통해 파드의 환경 변수 업데이트
  • 다중 컨테이너 파드에서 ConfigMap을 통해 구성 업데이트
  • 사이드카 컨테이너를 가진 파드에서 ConfigMap을 통해 구성 업데이트

볼륨으로 마운트된 ConfigMap을 통해 구성 업데이트 (#rollout-configmap-volume)

kubectl create configmap 명령을 사용해 리터럴 값에서 ConfigMap을 만들어요:

kubectl create configmap sport --from-literal=sport=football

아래는 ConfigMap sport볼륨으로 파드의 유일한 컨테이너에 마운트된 Deployment 매니페스트의 예시예요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: configmap-volume
  labels:
    app.kubernetes.io/name: configmap-volume
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: configmap-volume
  template:
    metadata:
      labels:
        app.kubernetes.io/name: configmap-volume
    spec:
      containers:
        - name: alpine
          image: alpine:3
          command:
            - /bin/sh
            - -c
            - while true; do echo "$(date) My preferred sport is $(cat /etc/config/sport)";
              sleep 10; done;
          ports:
            - containerPort: 80
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: sport

Deployment를 만들어요:

kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-volume.yaml

이 Deployment의 파드를 확인해 준비되었는지 확인해요(셀렉터로 일치):

kubectl get pods --selector=app.kubernetes.io/name=configmap-volume

다음과 유사한 출력을 볼 수 있어요:

NAME                                READY   STATUS    RESTARTS   AGE
configmap-volume-6b976dfdcf-qxvbm   1/1     Running   0          72s
configmap-volume-6b976dfdcf-skpvm   1/1     Running   0          72s
configmap-volume-6b976dfdcf-tbc6r   1/1     Running   0          72s

이 파드 중 하나가 실행되는 각 노드에서 kubelet이 그 ConfigMap의 데이터를 가져와 로컬 볼륨의 파일로 변환해요. 그런 다음 kubelet이 파드 템플릿에 지정된 대로 그 볼륨을 컨테이너에 마운트해요. 그 컨테이너에서 실행되는 코드는 파일에서 정보를 로드해 stdout에 보고서를 출력하는 데 사용해요. 이 Deployment의 파드 중 하나의 로그를 보면 이 보고서를 확인할 수 있어요:

# Pick one Pod that belongs to the Deployment, and view its logs
kubectl logs deployments/configmap-volume

다음과 유사한 출력을 볼 수 있어요:

Found 3 pods, using pod/configmap-volume-76d9c5678f-x5rgj
Thu Jan  4 14:06:46 UTC 2024 My preferred sport is football
Thu Jan  4 14:06:56 UTC 2024 My preferred sport is football
Thu Jan  4 14:07:06 UTC 2024 My preferred sport is football
Thu Jan  4 14:07:16 UTC 2024 My preferred sport is football
Thu Jan  4 14:07:26 UTC 2024 My preferred sport is football

ConfigMap을 편집해요:

kubectl edit configmap sport

나타나는 편집기에서 key sport의 값을 football에서 cricket으로 변경해요. 변경 사항을 저장해요. kubectl 도구가 그에 따라 ConfigMap을 업데이트해요(오류가 보이면 다시 시도해요).

편집 후 그 매니페스트가 어떻게 보일 수 있는지에 대한 예시는 다음과 같아요:

apiVersion: v1
data:
  sport: cricket
kind: ConfigMap
# You can leave the existing metadata as they are.
# The values you'll see won't exactly match these.
metadata:
  creationTimestamp: "2024-01-04T14:05:06Z"
  name: sport
  namespace: default
  resourceVersion: "1743935"
  uid: 024ee001-fe72-487e-872e-34d6464a8a23

다음 출력을 볼 수 있어요:

configmap/sport edited

이 Deployment에 속한 파드 중 하나의 로그를 tail(최신 항목을 따라가며)해요:

kubectl logs deployments/configmap-volume --follow

몇 초 후 로그 출력이 다음과 같이 변경되는 것을 볼 수 있어요:

Thu Jan  4 14:11:36 UTC 2024 My preferred sport is football
Thu Jan  4 14:11:46 UTC 2024 My preferred sport is football
Thu Jan  4 14:11:56 UTC 2024 My preferred sport is football
Thu Jan  4 14:12:06 UTC 2024 My preferred sport is cricket
Thu Jan  4 14:12:16 UTC 2024 My preferred sport is cricket

configMap 볼륨이나 projected 볼륨을 사용해 실행 중인 파드에 매핑된 ConfigMap이 있고 그 ConfigMap을 업데이트하면 실행 중인 파드는 거의 즉시 업데이트를 봐요. 하지만 애플리케이션은 변경을 폴링하거나 파일 업데이트를 감시하도록 작성된 경우에만 변경을 봐요. 시작 시 한 번 구성을 로드하는 애플리케이션은 변경을 알아차리지 못해요.

ConfigMap이 변경된 후 파드가 업데이트를 보는 정확한 타이밍은 kubelet 동기화 간격과 팬아웃 지연에 따라 달라져요.

ConfigMap을 통해 파드의 환경 변수 업데이트 (#rollout-configmap-env)

kubectl create configmap 명령을 사용해 리터럴 값에서 ConfigMap을 만들어요:

kubectl create configmap fruits --from-literal=fruits=apples

아래는 ConfigMap fruits를 통해 구성된 환경 변수가 있는 Deployment 매니페스트의 예시예요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: configmap-env-var
  labels:
    app.kubernetes.io/name: configmap-env-var
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: configmap-env-var
  template:
    metadata:
      labels:
        app.kubernetes.io/name: configmap-env-var
    spec:
      containers:
        - name: alpine
          image: alpine:3
          env:
            - name: FRUITS
              valueFrom:
                configMapKeyRef:
                  key: fruits
                  name: fruits
          command:
            - /bin/sh
            - -c
            - while true; do echo "$(date) The basket is full of $FRUITS";
                sleep 10; done;
          ports:
            - containerPort: 80

Deployment를 만들어요:

kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-envvar.yaml

이 Deployment의 파드를 확인해 준비되었는지 확인해요(셀렉터로 일치):

kubectl get pods --selector=app.kubernetes.io/name=configmap-env-var

다음과 유사한 출력을 볼 수 있어요:

NAME                                 READY   STATUS    RESTARTS   AGE
configmap-env-var-59cfc64f7d-74d7z   1/1     Running   0          46s
configmap-env-var-59cfc64f7d-c4wmj   1/1     Running   0          46s
configmap-env-var-59cfc64f7d-dpr98   1/1     Running   0          46s

ConfigMap의 키-값 쌍은 파드의 컨테이너에서 환경 변수로 구성돼요. 이 Deployment에 속한 하나의 파드의 로그를 보고 확인해요.

kubectl logs deployment/configmap-env-var

다음과 유사한 출력을 볼 수 있어요:

Found 3 pods, using pod/configmap-env-var-7c994f7769-l74nq
Thu Jan  4 16:07:06 UTC 2024 The basket is full of apples
Thu Jan  4 16:07:16 UTC 2024 The basket is full of apples
Thu Jan  4 16:07:26 UTC 2024 The basket is full of apples

ConfigMap을 편집해요:

kubectl edit configmap fruits

나타나는 편집기에서 key fruits의 값을 apples에서 mangoes로 변경해요. 변경 사항을 저장해요. kubectl 도구가 그에 따라 ConfigMap을 업데이트해요(오류가 보이면 다시 시도해요).

편집 후 그 매니페스트가 어떻게 보일 수 있는지에 대한 예시는 다음과 같아요:

apiVersion: v1
data:
  fruits: mangoes
kind: ConfigMap
# You can leave the existing metadata as they are.
# The values you'll see won't exactly match these.
metadata:
  creationTimestamp: "2024-01-04T16:04:19Z"
  name: fruits
  namespace: default
  resourceVersion: "1749472"

다음 출력을 볼 수 있어요:

configmap/fruits edited

Deployment의 로그를 tail하고 몇 초 동안 출력을 관찰해요:

# As the text explains, the output does NOT change
kubectl logs deployments/configmap-env-var --follow

ConfigMap을 편집했는데도 출력이 변경되지 않는다는 점을 주목해요:

Thu Jan  4 16:12:56 UTC 2024 The basket is full of apples
Thu Jan  4 16:13:06 UTC 2024 The basket is full of apples
Thu Jan  4 16:13:16 UTC 2024 The basket is full of apples
Thu Jan  4 16:13:26 UTC 2024 The basket is full of apples

그 교체를 트리거할 수 있어요. kubectl rollout(/docs/reference/kubectl/generated/kubectl_rollout/)을 사용해 Deployment에 대한 롤아웃을 수행해요:

# Trigger the rollout
kubectl rollout restart deployment configmap-env-var

# Wait for the rollout to complete
kubectl rollout status deployment configmap-env-var --watch=true

다음으로 Deployment를 확인해요:

kubectl get deployment configmap-env-var

다음과 유사한 출력을 볼 수 있어요:

NAME                READY   UP-TO-DATE   AVAILABLE   AGE
configmap-env-var   3/3     3            3           12m

파드를 확인해요:

kubectl get pods --selector=app.kubernetes.io/name=configmap-env-var

롤아웃으로 Kubernetes가 Deployment에 대한 새 ReplicaSet을 만들게 돼요. 즉 기존 파드는 결국 종료되고 새 파드가 생성되요. 몇 초 후 다음과 유사한 출력을 볼 수 있어요:

NAME                                 READY   STATUS        RESTARTS   AGE
configmap-env-var-6d94d89bf5-2ph2l   1/1     Running       0          13s
configmap-env-var-6d94d89bf5-74twx   1/1     Running       0          8s
configmap-env-var-6d94d89bf5-d5vx8   1/1     Running       0          11s

이 Deployment의 파드 로그를 봐요:

# Pick one Pod that belongs to the Deployment, and view its logs
kubectl logs deployment/configmap-env-var

아래와 유사한 출력을 볼 수 있어요:

Found 3 pods, using pod/configmap-env-var-6d9ff89fb6-bzcf6
Thu Jan  4 16:30:35 UTC 2024 The basket is full of mangoes
Thu Jan  4 16:30:45 UTC 2024 The basket is full of mangoes
Thu Jan  4 16:30:55 UTC 2024 The basket is full of mangoes

이것은 ConfigMap에서 파생된 파드의 환경 변수를 업데이트하는 시나리오를 보여줘요. ConfigMap 값의 변경은 후속 롤아웃 동안 파드에 적용돼요. Deployment 확장처럼 다른 이유로 파드가 생성되면 새 파드도 최신 구성 값을 사용해요. 롤아웃을 트리거하지 않으면 앱이 이전과 새 환경 변수 값의 혼합으로 실행되는 것을 발견할 수 있어요.

다중 컨테이너 파드에서 ConfigMap을 통해 구성 업데이트 (#rollout-configmap-multiple-containers)

kubectl create configmap 명령을 사용해 리터럴 값에서 ConfigMap을 만들어요:

kubectl create configmap color --from-literal=color=red

아래는 각각 두 컨테이너가 있는 파드 집합을 관리하는 Deployment의 예시 매니페스트예요. 두 컨테이너는 통신에 사용하는 emptyDir 볼륨을 공유해요. 첫 컨테이너는 웹 서버(nginx)를 실행해요. 웹 서버 컨테이너에서 공유 볼륨의 마운트 경로는 /usr/share/nginx/html이에요. 두 번째 헬퍼 컨테이너는 alpine 기반이고, 이 컨테이너의 경우 emptyDir 볼륨이 /pod-data에 마운트돼요. 헬퍼 컨테이너는 ConfigMap에 기반한 내용을 가진 HTML 파일을 써요. 웹 서버 컨테이너는 HTTP로 HTML을 서빙해요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: configmap-two-containers
  labels:
    app.kubernetes.io/name: configmap-two-containers
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: configmap-two-containers
  template:
    metadata:
      labels:
        app.kubernetes.io/name: configmap-two-containers
    spec:
      volumes:
        - name: shared-data
          emptyDir: {}
        - name: config-volume
          configMap:
            name: color
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - name: shared-data
              mountPath: /usr/share/nginx/html
        - name: alpine
          image: alpine:3
          volumeMounts:
            - name: shared-data
              mountPath: /pod-data
            - name: config-volume
              mountPath: /etc/config
          command:
            - /bin/sh
            - -c
            - while true; do echo "$(date) My preferred color is $(cat /etc/config/color)" > /pod-data/index.html;
              sleep 10; done;

Deployment를 만들어요:

kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-two-containers.yaml

이 Deployment의 파드를 확인해 준비되었는지 확인해요(셀렉터로 일치):

kubectl get pods --selector=app.kubernetes.io/name=configmap-two-containers

다음과 유사한 출력을 볼 수 있어요:

NAME                                        READY   STATUS    RESTARTS   AGE
configmap-two-containers-565fb6d4f4-2xhxf   2/2     Running   0          20s
configmap-two-containers-565fb6d4f4-g5v4j   2/2     Running   0          20s
configmap-two-containers-565fb6d4f4-mzsmf   2/2     Running   0          20s

Deployment를 노출해요(kubectl 도구가 Service를 만들어줘요):

kubectl expose deployment configmap-two-containers --name=configmap-service --port=8080 --target-port=80

kubectl로 포트를 포워딩해요:

# this stays running in the background
kubectl port-forward service/configmap-service 8080:8080 &

서비스에 접근해요.

curl http://localhost:8080

다음과 유사한 출력을 볼 수 있어요:

Fri Jan  5 08:08:22 UTC 2024 My preferred color is red

ConfigMap을 편집해요:

kubectl edit configmap color

나타나는 편집기에서 key color의 값을 red에서 blue로 변경해요. 변경 사항을 저장해요. kubectl 도구가 그에 따라 ConfigMap을 업데이트해요(오류가 보이면 다시 시도해요).

편집 후 그 매니페스트가 어떻게 보일 수 있는지에 대한 예시는 다음과 같아요:

apiVersion: v1
data:
  color: blue
kind: ConfigMap
# You can leave the existing metadata as they are.
# The values you'll see won't exactly match these.
metadata:
  creationTimestamp: "2024-01-05T08:12:05Z"
  name: color
  namespace: configmap
  resourceVersion: "1801272"
  uid: 80d33e4a-cbb4-4bc9-ba8c-544c68e425d6

몇 초 동안 서비스 URL을 반복해요.

# Cancel this when you're happy with it (Ctrl-C)
while true; do curl --connect-timeout 7.5 http://localhost:8080; sleep 10; done

출력이 다음과 같이 변경되는 것을 볼 수 있어요:

Fri Jan  5 08:14:00 UTC 2024 My preferred color is red
Fri Jan  5 08:14:02 UTC 2024 My preferred color is red
Fri Jan  5 08:14:20 UTC 2024 My preferred color is red
Fri Jan  5 08:14:22 UTC 2024 My preferred color is red
Fri Jan  5 08:14:32 UTC 2024 My preferred color is blue
Fri Jan  5 08:14:43 UTC 2024 My preferred color is blue
Fri Jan  5 08:15:00 UTC 2024 My preferred color is blue

사이드카 컨테이너를 가진 파드에서 ConfigMap을 통해 구성 업데이트 (#rollout-configmap-sidecar)

위 시나리오는 사이드카 컨테이너를 HTML 파일을 쓰는 헬퍼 컨테이너로 사용해 재현할 수 있어요. 사이드카 컨테이너는 개념적으로 Init Container이므로 기본 웹 서버 컨테이너보다 먼저 시작하는 것이 보장돼요. 이것은 웹 서버가 서빙할 준비가 되었을 때 HTML 파일이 항상 사용 가능하도록 보장해요.

이전 시나리오에서 계속한다면 이 시나리오에 color라는 ConfigMap을 재사용할 수 있어요. 이 시나리오를 독립적으로 실행한다면 kubectl create configmap 명령을 사용해 리터럴 값에서 ConfigMap을 만들어요:

kubectl create configmap color --from-literal=color=blue

아래는 각각 기본 컨테이너와 사이드카 컨테이너가 있는 파드 집합을 관리하는 Deployment의 예시 매니페스트예요. 두 컨테이너는 통신에 사용하는 emptyDir 볼륨을 공유해요. 기본 컨테이너는 웹 서버(NGINX)를 실행해요. 웹 서버 컨테이너에서 공유 볼륨의 마운트 경로는 /usr/share/nginx/html이에요. 두 번째 컨테이너는 헬퍼 컨테이너로 작동하는 Alpine Linux 기반 사이드카 컨테이너예요. 이 컨테이너의 경우 emptyDir 볼륨이 /pod-data에 마운트돼요. 사이드카 컨테이너는 ConfigMap에 기반한 내용을 가진 HTML 파일을 써요. 웹 서버 컨테이너는 HTTP로 HTML을 서빙해요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: configmap-sidecar-container
  labels:
    app.kubernetes.io/name: configmap-sidecar-container
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: configmap-sidecar-container
  template:
    metadata:
      labels:
        app.kubernetes.io/name: configmap-sidecar-container
    spec:
      volumes:
        - name: shared-data
          emptyDir: {}
        - name: config-volume
          configMap:
            name: color
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - name: shared-data
              mountPath: /usr/share/nginx/html
      initContainers:
        - name: alpine
          image: alpine:3
          restartPolicy: Always
          volumeMounts:
            - name: shared-data
              mountPath: /pod-data
            - name: config-volume
              mountPath: /etc/config
          command:
            - /bin/sh
            - -c
            - while true; do echo "$(date) My preferred color is $(cat /etc/config/color)" > /pod-data/index.html;
              sleep 10; done;

Deployment를 만들어요:

kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-and-sidecar-container.yaml

이 Deployment의 파드를 확인해 준비되었는지 확인해요(셀렉터로 일치):

kubectl get pods --selector=app.kubernetes.io/name=configmap-sidecar-container

다음과 유사한 출력을 볼 수 있어요:

NAME                                           READY   STATUS    RESTARTS   AGE
configmap-sidecar-container-5fb59f558b-87rp7   2/2     Running   0          94s
configmap-sidecar-container-5fb59f558b-ccs7s   2/2     Running   0          94s
configmap-sidecar-container-5fb59f558b-wnmgk   2/2     Running   0          94s

Deployment를 노출해요(kubectl 도구가 Service를 만들어줘요):

kubectl expose deployment configmap-sidecar-container --name=configmap-sidecar-service --port=8081 --target-port=80

kubectl로 포트를 포워딩해요:

# this stays running in the background
kubectl port-forward service/configmap-sidecar-service 8081:8081 &

서비스에 접근해요.

curl http://localhost:8081

다음과 유사한 출력을 볼 수 있어요:

Sat Feb 17 13:09:05 UTC 2024 My preferred color is blue

ConfigMap을 편집해요:

kubectl edit configmap color

나타나는 편집기에서 key color의 값을 blue에서 green으로 변경해요. 변경 사항을 저장해요. kubectl 도구가 그에 따라 ConfigMap을 업데이트해요(오류가 보이면 다시 시도해요).

편집 후 그 매니페스트가 어떻게 보일 수 있는지에 대한 예시는 다음과 같아요:

apiVersion: v1
data:
  color: green
kind: ConfigMap
# You can leave the existing metadata as they are.
# The values you'll see won't exactly match these.
metadata:
  creationTimestamp: "2024-02-17T12:20:30Z"
  name: color
  namespace: default
  resourceVersion: "1054"
  uid: e40bb34c-58df-4280-8bea-6ed16edccfaa

몇 초 동안 서비스 URL을 반복해요.

# Cancel this when you're happy with it (Ctrl-C)
while true; do curl --connect-timeout 7.5 http://localhost:8081; sleep 10; done

출력이 다음과 같이 변경되는 것을 볼 수 있어요:

Sat Feb 17 13:12:35 UTC 2024 My preferred color is blue
Sat Feb 17 13:12:45 UTC 2024 My preferred color is blue
Sat Feb 17 13:12:55 UTC 2024 My preferred color is blue
Sat Feb 17 13:13:05 UTC 2024 My preferred color is blue
Sat Feb 17 13:13:15 UTC 2024 My preferred color is green
Sat Feb 17 13:13:25 UTC 2024 My preferred color is green
Sat Feb 17 13:13:35 UTC 2024 My preferred color is green

볼륨으로 마운트된 불변(immutable) ConfigMap을 통해 구성 업데이트 (#rollout-configmap-immutable-volume)

불변 ConfigMap은 특히 시간이 지나도 변하지 않을 것으로 예상되는 일정한 구성에 사용돼요. ConfigMap을 불변으로 표시하면 kubelet이 변경을 감시하지 않아 성능이 향상돼요.

변경해야 한다면 다음 중 하나를 계획해야 해요:

  • ConfigMap의 이름을 변경하고 새 이름을 참조하는 실행 중인 파드로 전환
  • 이전 값을 사용한 파드를 이전에 실행한 클러스터의 모든 노드 교체
  • kubelet이 이전 ConfigMap을 이전에 로드한 노드에서 kubelet 재시작

불변 ConfigMap의 예시 매니페스트는 아래와 같아요.

apiVersion: v1
data:
  company_name: "ACME, Inc." # existing fictional company name
kind: ConfigMap
immutable: true
metadata:
  name: company-name-20150801

불변 ConfigMap을 만들어요:

kubectl apply -f https://k8s.io/examples/configmap/immutable-configmap.yaml

아래는 불변 ConfigMap company-name-20150801볼륨으로 파드의 유일한 컨테이너에 마운트된 Deployment 매니페스트의 예시예요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: immutable-configmap-volume
  labels:
    app.kubernetes.io/name: immutable-configmap-volume
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: immutable-configmap-volume
  template:
    metadata:
      labels:
        app.kubernetes.io/name: immutable-configmap-volume
    spec:
      containers:
        - name: alpine
          image: alpine:3
          command:
            - /bin/sh
            - -c
            - while true; do echo "$(date) The name of the company is $(cat /etc/config/company_name)";
              sleep 10; done;
          ports:
            - containerPort: 80
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: company-name-20150801

Deployment를 만들어요:

kubectl apply -f https://k8s.io/examples/deployments/deployment-with-immutable-configmap-as-volume.yaml

이 Deployment의 파드를 확인해 준비되었는지 확인해요(셀렉터로 일치):

kubectl get pods --selector=app.kubernetes.io/name=immutable-configmap-volume

다음과 유사한 출력을 볼 수 있어요:

NAME                                          READY   STATUS    RESTARTS   AGE
immutable-configmap-volume-78b6fbff95-5gsfh   1/1     Running   0          62s
immutable-configmap-volume-78b6fbff95-7vcj4   1/1     Running   0          62s
immutable-configmap-volume-78b6fbff95-vdslm   1/1     Running   0          62s

파드의 컨테이너는 ConfigMap에 정의된 데이터를 참조하고 이를 사용해 stdout에 보고서를 출력해요. 이 Deployment의 파드 중 하나의 로그를 보면 이 보고서를 확인할 수 있어요:

# Pick one Pod that belongs to the Deployment, and view its logs
kubectl logs deployments/immutable-configmap-volume

다음과 유사한 출력을 볼 수 있어요:

Found 3 pods, using pod/immutable-configmap-volume-78b6fbff95-5gsfh
Wed Mar 20 03:52:34 UTC 2024 The name of the company is ACME, Inc.
Wed Mar 20 03:52:44 UTC 2024 The name of the company is ACME, Inc.
Wed Mar 20 03:52:54 UTC 2024 The name of the company is ACME, Inc.

아래에 표시된 매니페스트를 사용해 새 불변 ConfigMap을 만들어요:

apiVersion: v1
data:
  company_name: "Fiktivesunternehmen GmbH" # new fictional company name
kind: ConfigMap
immutable: true
metadata:
  name: company-name-20240312
kubectl apply -f https://k8s.io/examples/configmap/new-immutable-configmap.yaml

다음과 유사한 출력을 볼 수 있어요:

configmap/company-name-20240312 created

새로 만든 ConfigMap을 확인해요:

kubectl get configmap

이전과 새 ConfigMap을 모두 표시하는 출력을 볼 수 있어요:

NAME                    DATA   AGE
company-name-20150801   1      22m
company-name-20240312   1      24s

Deployment를 수정해 새 ConfigMap을 참조해요.

Deployment를 편집해요:

kubectl edit deployment immutable-configmap-volume

나타나는 편집기에서 기존 볼륨 정의를 새 ConfigMap을 사용하도록 업데이트해요.

volumes:
- configMap:
    defaultMode: 420
    name: company-name-20240312 # Update this field
  name: config-volume

다음 출력을 볼 수 있어요:

deployment.apps/immutable-configmap-volume edited

이것은 롤아웃을 트리거해요. 모든 이전 파드가 종료되고 새 파드가 준비 상태가 될 때까지 기다려요.

파드의 상태를 모니터링해요:

kubectl get pods --selector=app.kubernetes.io/name=immutable-configmap-volume
NAME                                          READY   STATUS        RESTARTS   AGE
immutable-configmap-volume-5fdb88fcc8-29v8n   1/1     Running       0          13s
immutable-configmap-volume-5fdb88fcc8-52ddd   1/1     Running       0          14s
immutable-configmap-volume-5fdb88fcc8-n5jx4   1/1     Running       0          15s
immutable-configmap-volume-78b6fbff95-5gsfh   1/1     Terminating   0          32m
immutable-configmap-volume-78b6fbff95-7vcj4   1/1     Terminating   0          32m
immutable-configmap-volume-78b6fbff95-vdslm   1/1     Terminating   0          32m

결국 다음과 유사한 출력을 볼 수 있어요:

NAME                                          READY   STATUS    RESTARTS   AGE
immutable-configmap-volume-5fdb88fcc8-29v8n   1/1     Running   0          43s
immutable-configmap-volume-5fdb88fcc8-52ddd   1/1     Running   0          44s
immutable-configmap-volume-5fdb88fcc8-n5jx4   1/1     Running   0          45s

이 Deployment의 파드 로그를 봐요:

# Pick one Pod that belongs to the Deployment, and view its logs
kubectl logs deployment/immutable-configmap-volume

아래와 유사한 출력을 볼 수 있어요:

Found 3 pods, using pod/immutable-configmap-volume-5fdb88fcc8-n5jx4
Wed Mar 20 04:24:17 UTC 2024 The name of the company is Fiktivesunternehmen GmbH
Wed Mar 20 04:24:27 UTC 2024 The name of the company is Fiktivesunternehmen GmbH
Wed Mar 20 04:24:37 UTC 2024 The name of the company is Fiktivesunternehmen GmbH

모든 배포가 새 불변 ConfigMap을 사용하도록 마이그레이션되면 이전 것을 삭제하는 것이 좋아요.

kubectl delete configmap company-name-20150801

요약 (Summary)

  • 파드의 볼륨으로 마운트된 ConfigMap에 대한 변경은 후속 kubelet 동기화 후 원활하게 사용 가능해요.
  • 파드의 환경 변수를 구성하는 ConfigMap에 대한 변경은 후속 파드 롤아웃 후 사용 가능해요.
  • ConfigMap이 불변으로 표시되면 이 변경을 되돌릴 수 없어요(불변 ConfigMap을 가변으로 만들 수 없어요), 그리고 data 또는 binaryData 필드의 내용도 변경할 수 없어요. ConfigMap을 삭제하고 다시 만들거나, 새롭고 다른 ConfigMap을 만들 수 있어요. ConfigMap을 삭제하면 실행 중인 컨테이너와 그 파드는 그 기존 ConfigMap을 참조한 모든 볼륨에 대한 마운트 지점을 유지해요.

정리 (Cleaning up)

kubectl port-forward 명령이 실행 중이면 종료해요.

튜토리얼 중에 만든 리소스를 삭제해요:

kubectl delete deployment configmap-volume configmap-env-var configmap-two-containers configmap-sidecar-container immutable-configmap-volume
kubectl delete service configmap-service configmap-sidecar-service
kubectl delete configmap sport fruits color company-name-20240312

kubectl delete configmap company-name-20150801 # In case it was not handled during the task execution

더 알아보기 (Learn more)