쿠버네티스(Kubernetes)를 운영하다 보면 가장 자주 마주치는 오류 중 하나가 바로 CreateContainerConfigError
입니다. 특히 ConfigMap이나 Secret과 관련된 설정 문제로 인해 파드가 정상적으로 시작되지 않을 때 발생하는데요, 이 문제를 겪어보신 분들이라면 얼마나 답답한지 아실 겁니다. 오늘은 이 오류의 정확한 원인부터 체계적인 해결 방법까지, 실무에서 바로 적용할 수 있는 완벽한 가이드를 준비했습니다. 복잡해 보이지만 원리를 이해하면 생각보다 간단하게 해결할 수 있습니다.
1. CreateContainerConfigError란 무엇인가?
CreateContainerConfigError는 쿠버네티스가 컨테이너를 Pending 상태에서 Running 상태로 전환하는 과정에서 컨테이너 설정을 생성하지 못할 때 발생하는 오류입니다. 쉽게 말해, 컨테이너가 시작되기 전에 필요한 설정 정보를 찾지 못해서 생기는 문제라고 보시면 됩니다.
이 오류는 주로 generateContainerConfig 메서드가 파드 메타데이터나 설정 데이터를 읽는 과정에서 참조된 리소스를 찾지 못할 때 발생합니다.
오류 발생 시점
- 파드가 Pending 상태에서 Running 상태로 전환되는 시점
- 컨테이너 설정 검증 단계
- ConfigMap이나 Secret 참조를 해석하는 과정
일반적인 증상
kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-5d7c8b9f4-xyz12 0/1 CreateContainerConfigError 0 2m30s
2. 주요 원인 분석
CreateContainerConfigError의 가장 일반적인 원인은 누락되거나 잘못 구성된 ConfigMap 또는 Secret 때문입니다. 실제 운영 환경에서 자주 발생하는 원인들을 살펴보겠습니다.
ConfigMap 관련 문제
- 존재하지 않는 ConfigMap 참조: YAML에서 참조한 ConfigMap이 클러스터에 존재하지 않음
- 잘못된 ConfigMap 이름: 오타나 네이밍 실수로 인한 참조 오류
- 존재하지 않는 키 참조: ConfigMap은 존재하지만 특정 키가 없는 경우
Secret 관련 문제
- 누락된 Secret: 파드에서 참조하는 Secret이 생성되지 않음
- 네임스페이스 불일치: Secret이 다른 네임스페이스에 존재하는 경우
- 잘못된 키 참조: Secret 내부의 특정 키를 찾을 수 없는 경우
기타 원인
- 볼륨 마운트 오류: 스토리지 볼륨이나 다른 오브젝트 누락
- 권한 문제: ServiceAccount의 리소스 접근 권한 부족
3. 문제 진단 방법
오류가 발생했을 때 정확한 원인을 파악하는 것이 해결의 첫 단계입니다. 단계별로 진단해보겠습니다.
3.1 파드 상태 확인
kubectl get pods
kubectl get pods -o wide
3.2 상세 정보 확인
kubectl describe pod <pod-name>
describe 명령어 출력의 하단 Events 섹션을 주의깊게 살펴보세요. 다음과 같은 메시지를 찾을 수 있습니다:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Failed 30s (x6 over 2m) kubelet Error: configmap "app-config" not found
Warning Failed 25s (x8 over 2m) kubelet Error: secret "db-secret" not found
3.3 리소스 존재 여부 확인
# ConfigMap 확인
kubectl get configmap
kubectl get configmap <configmap-name> -o yaml
# Secret 확인
kubectl get secret
kubectl get secret <secret-name> -o yaml
4. ConfigMap 오류 해결 방법
4.1 누락된 ConfigMap 생성
먼저 오류 예제부터 살펴보겠습니다:
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: nginx:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config # 이 ConfigMap이 존재하지 않음
key: db_url
해결방법: 누락된 ConfigMap 생성
# 방법 1: 명령어로 생성
kubectl create configmap app-config \
--from-literal=db_url="mongodb://localhost:27017/myapp" \
--from-literal=api_key="your-api-key"
# 방법 2: YAML 파일로 생성
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
db_url: "mongodb://localhost:27017/myapp"
api_key: "your-api-key"
EOF
4.2 존재하지 않는 키 해결
ConfigMap은 존재하지만 특정 키가 없는 경우에도 CreateContainerConfigError가 발생합니다.
문제 상황:
# 현재 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_host: "localhost"
# db_url 키가 없음
# 파드에서 존재하지 않는 키 참조
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: db_url # 존재하지 않는 키
해결방법:
# ConfigMap에 누락된 키 추가
kubectl patch configmap app-config --patch='{"data":{"db_url":"mongodb://localhost:27017/myapp"}}'
# 또는 ConfigMap 편집
kubectl edit configmap app-config
5. Secret 오류 해결 방법
5.1 누락된 Secret 생성
Secret 관련 오류 예제:
apiVersion: v1
kind: Pod
metadata:
name: db-pod
spec:
containers:
- name: database
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret # 이 Secret이 존재하지 않음
key: root-password
해결방법:
# 방법 1: 명령어로 Secret 생성
kubectl create secret generic mysql-secret \
--from-literal=root-password="my-secure-password" \
--from-literal=username="admin"
# 방법 2: YAML 파일로 생성 (base64 인코딩 필요)
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
root-password: bXktc2VjdXJlLXBhc3N3b3Jk # base64 encoded
username: YWRtaW4= # base64 encoded
EOF
5.2 네임스페이스 문제 해결
Secret이 다른 네임스페이스에 있거나 현재 네임스페이스에 없는 경우에도 이 오류가 발생합니다.
# 현재 네임스페이스 확인
kubectl config get-contexts
# 특정 네임스페이스의 Secret 확인
kubectl get secret -n <namespace>
# 올바른 네임스페이스에 Secret 생성
kubectl create secret generic mysql-secret \
--from-literal=root-password="password" \
-n <target-namespace>
6. 실제 에러 해결 과정에 대한 예시
실제 운영 환경에서 발생할 수 있는 복합적인 문제와 해결 과정을 살펴보겠습니다.
6.1 전체 시나리오 예제
문제 상황: 웹 애플리케이션 배포 중 CreateContainerConfigError 발생
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-settings
key: db_connection
- name: API_SECRET
valueFrom:
secretKeyRef:
name: api-credentials
key: secret_key
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-settings
단계별 해결:
- 문제 진단:
kubectl get pods
kubectl describe pod web-app-xxx-xxx
- 누락된 리소스 확인:
kubectl get configmap app-settings
kubectl get secret api-credentials
- 리소스 생성:
# ConfigMap 생성
kubectl create configmap app-settings \
--from-literal=db_connection="postgresql://user:pass@db:5432/myapp" \
--from-literal=app_env="production"
# Secret 생성
kubectl create secret generic api-credentials \
--from-literal=secret_key="your-super-secret-key" \
--from-literal=api_token="your-api-token"
- 파드 재시작:
kubectl rollout restart deployment web-app
6.2 진단 및 해결 체크리스트
단계 | 확인 사항 | 명령어 |
---|---|---|
1 | 파드 상태 확인 | kubectl get pods |
2 | 상세 이벤트 확인 | kubectl describe pod <name> |
3 | ConfigMap 존재 여부 | kubectl get configmap |
4 | Secret 존재 여부 | kubectl get secret |
5 | 네임스페이스 일치 여부 | kubectl get all -n <namespace> |
6 | 키 존재 여부 | kubectl get configmap <name> -o yaml |
오류 해결이 복잡하게 느껴질 수 있지만, 위의 체계적인 접근법을 따라하시면 대부분의 CreateContainerConfigError를 해결할 수 있습니다. 무엇보다 중요한 것은 문제가 발생했을 때 당황하지 말고 차근차근 진단하는 것입니다.
실제 운영 환경에서 이런 문제들을 미리 방지하려면 CI/CD 파이프라인에 검증 단계를 포함시키고, 인프라를 코드로 관리하는 것을 추천드립니다. 그러면 휴먼 에러를 크게 줄일 수 있습니다.