LabHub
배우기 러닝패스 코스

CKAD — Kubernetes Application Developer

Injecting Configuration With ConfigMaps and Secrets

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

같은 이미지를 환경마다 다르게 동작시키는 네 가지 주입 경로(전체 환경변수, 개별 환경변수, 파일 볼륨, subPath 파일)를 구분해서 쓰고, Secret 과 ConfigMap 의 차이를 필드 수준에서 다룰 수 있게 된다.

왜 중요한가

설정 주입에서 실무 사고가 나는 지점은 대부분 "갱신이 반영되는가"이다. 환경변수로 넣은 값은 프로세스가 시작할 때 한 번 읽히고 끝이라, ConfigMap 을 고쳐도 파드를 다시 만들기 전에는 절대 바뀌지 않는다. 볼륨으로 넣은 파일은 kubelet 이 주기적으로 갱신해 주지만, subPath 로 얹은 파일만은 예외라 갱신되지 않는다. 이 세 가지 동작 차이를 모르면 "설정을 바꿨는데 왜 안 먹지"에서 시간을 다 쓴다.

defaultMode 도 실무에서 자주 걸린다. Secret 을 마운트하면 기본 권한이 0644 라 같은 노드의 다른 프로세스가 읽을 수 있다. TLS 키처럼 민감한 파일은 0400 으로 좁힌다. YAML 에서 0400 을 따옴표 없이 쓰면 8진수로 해석되지만, 400 만 쓰면 10진수 400 으로 읽혀 엉뚱한 권한이 된다.

immutable: true 는 보안 기능이 아니라 성능 기능이다. kubelet 은 마운트된 ConfigMap/Secret 의 변경을 감시하려고 API 서버를 계속 두드리는데, immutable 이면 감시를 멈춘다. 수천 파드 규모에서 apiserver 부하가 눈에 띄게 줄어든다.

단계

  1. 네임스페이스 ckad-config 를 만들고, 그 안에 ConfigMap app-config 를 리터럴로 만든다. 키는 APP_MODE=production, LOG_LEVEL=info.
  2. 디렉터리 /root/ckad-config 를 만들고 파일 /root/ckad-config/app.propertiestimeout=30 한 줄을 쓴 뒤, 그 파일로 ConfigMap app-props 를 만든다(키 이름은 app.properties).
  3. 파드 cfg-env 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]. envFrom 으로 app-config 전체를 주입하고, 추가로 envLOG 라는 이름으로 app-configLOG_LEVEL 키를 참조한다.
  4. Secret db-secret 을 만든다. 타입은 generic(Opaque), 키는 DB_USER=appuser, DB_PASSWORD=s3cr3t.
  5. 파드 secret-consumer 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]. 환경변수 DB_PASSWORDdb-secretDB_PASSWORD 키에서 가져오고, 같은 Secret 을 볼륨 dbcreds/etc/db 에 마운트하되 defaultMode0400 으로 준다.
  6. 파드 cfg-vol 을 만든다. 이미지 nginx:1.27. ConfigMap app-props 를 볼륨 props 로 두 번 마운트한다 — 하나는 /etc/app 에 디렉터리째, 다른 하나는 subPath: app.properties/opt/app/app.properties 에.
  7. ConfigMap feature-flags 를 만든다. 키 NEW_UI=on, 그리고 immutable: true. 파드 optional-cm 을 만들어(이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]) 존재하지 않는 ConfigMap maybe-configenvFrom 으로 참조하되 optional: true 를 준다.
  8. Deployment web-config 를 만든다. 레플리카 2, 라벨 app=web-config, 이미지 nginx:1.27. envFromapp-config(configMapRef)와 db-secret(secretRef)을 모두 넣고, ConfigMap app-props 를 볼륨 props/etc/app 에 마운트한다.

참고

리터럴로 ConfigMap 만들기

네임스페이스 ckad-config 를 만들고, 그 안에 ConfigMap app-config 를 리터럴로 만든다. 키는 APP_MODE=production, LOG_LEVEL=info.

kubectl create configmap--from-literal=키=값 을 여러 번 줄 수 있다. 네임스페이스를 먼저 만들어 두고 -n 을 빠뜨리지 않는다.

파일에서 ConfigMap 만들기

디렉터리 /root/ckad-config 를 만들고 파일 /root/ckad-config/app.propertiestimeout=30 한 줄을 쓴 뒤, 그 파일로 ConfigMap app-props 를 만든다(키 이름은 app.properties).

--from-file=경로 를 쓰면 파일 이름이 키가 되고 파일 내용 전체가 값이 된다. 키 이름을 바꾸고 싶으면 --from-file=키이름=경로 형태를 쓴다.

envFrom 과 configMapKeyRef 를 같이 쓰기

파드 cfg-env 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]. envFrom 으로 app-config 전체를 주입하고, 추가로 envLOG 라는 이름으로 app-configLOG_LEVEL 키를 참조한다.

envFrom[].configMapRef 는 모든 키를 그대로 변수명으로 만들고, env[].valueFrom.configMapKeyRef 는 키 하나를 골라 다른 이름으로 넣는다. 두 방식을 한 컨테이너에 함께 쓸 수 있다.

Secret 만들기와 인코딩 확인

Secret db-secret 을 만든다. 타입은 generic(Opaque), 키는 DB_USER=appuser, DB_PASSWORD=s3cr3t.

kubectl create secret generic--from-literal 값은 자동으로 base64 인코딩된다. YAML 로 직접 쓸 때 평문을 넣고 싶으면 data 대신 stringData 를 쓴다.

Secret 을 환경변수와 파일로 함께 주입

파드 secret-consumer 를 만든다. 이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]. 환경변수 DB_PASSWORDdb-secretDB_PASSWORD 키에서 가져오고, 같은 Secret 을 볼륨 dbcreds/etc/db 에 마운트하되 defaultMode0400 으로 준다.

환경변수는 env[].valueFrom.secretKeyRef, 파일은 volumes[].secret.secretName 과 볼륨 마운트다. 파일 권한은 볼륨 쪽 defaultMode 로 정하고, YAML 에서는 8진수 앞의 0 을 빠뜨리기 쉬우니 주의한다.

ConfigMap 볼륨과 subPath

파드 cfg-vol 을 만든다. 이미지 nginx:1.27. ConfigMap app-props 를 볼륨 props 로 두 번 마운트한다 — 하나는 /etc/app 에 디렉터리째, 다른 하나는 subPath: app.properties/opt/app/app.properties 에.

디렉터리에 통째로 마운트하면 그 디렉터리의 원래 내용이 가려진다. 파일 하나만 얹고 싶으면 volumeMounts[].subPath 에 키 이름을 적는다. subPath 로 얹은 파일은 ConfigMap 을 고쳐도 갱신되지 않는다.

optional 참조와 immutable ConfigMap

ConfigMap feature-flags 를 만든다. 키 NEW_UI=on, 그리고 immutable: true. 파드 optional-cm 을 만들어(이미지 busybox:1.36, command: ["/bin/sh","-c","sleep 3600"]) 존재하지 않는 ConfigMap maybe-configenvFrom 으로 참조하되 optional: true 를 준다.

immutable: true 는 ConfigMap 스펙의 최상위 필드다(데이터 안이 아니다). 존재하지 않는 ConfigMap 을 참조해도 파드가 뜨게 하려면 참조하는 쪽에 optional: true 를 준다.

Deployment 에 세 가지를 한꺼번에 (종합)

Deployment web-config 를 만든다. 레플리카 2, 라벨 app=web-config, 이미지 nginx:1.27. envFromapp-config(configMapRef)와 db-secret(secretRef)을 모두 넣고, ConfigMap app-props 를 볼륨 props/etc/app 에 마운트한다.

앞에서 만든 ConfigMap 둘과 Secret 하나를 한 Deployment 에서 쓴다. envFrom 배열에는 configMapRefsecretRef 를 나란히 넣을 수 있다. 볼륨 마운트도 잊지 않는다.