Kubernetes를 사용하다 보면 직접 빌드한 이미지를 Docker Hub의 프라이빗 레지스트리에 저장하고 배포해야 하는 경우가 많습니다. 그런데 kubectl apply -f deployment.yaml 명령어를 실행했을 때, Pod이 정상적으로 실행되지 않고 ImagePullBackOff 또는 ErrImagePull 같은 에러 메시지를 마주할 때가 있습니다.
이것은 Kubernetes 클러스터가 여러분의 프라이빗 레지스트리에 접근할 권한, 즉 로그인 정보가 없기 때문에 발생하는 자연스러운 문제입니다.
이번 글에서는 이 문제를 해결하고 Docker Hub의 프라이빗 이미지를 원활하게 가져올 수 있도록 Kubernetes에 인증 정보를 추가하는 가장 확실한 방법을 알아보겠습니다.
Kubernetes는 어떻게 인증 정보를 관리할까? imagePullSecret
Kubernetes는 레지스트리 인증 정보와 같은 민감한 데이터를 **시크릿(Secret)**이라는 오브젝트를 통해 안전하게 관리합니다. 특히 Docker 레지스트리 인증을 위해서는 kubernetes.io/dockerconfigjson 타입의 시크릿을 사용하며, 이를 흔히 imagePullSecret 이라고 부릅니다.
이제 이 imagePullSecret을 직접 생성하고 적용하는 방법을 단계별로 알아보겠습니다.
1단계: imagePullSecret 생성하기
가장 간단한 방법은 kubectl CLI 명령어를 사용하는 것입니다.
⚠️ 잠깐! 비밀번호 대신 액세스 토큰을 사용하세요
본격적으로 시작하기 전에 중요한 보안 팁이 있습니다. Docker Hub 계정의 실제 비밀번호를 직접 사용하는 것보다, 보안 강화를 위해 **액세스 토큰(Access Token)**을 생성하여 사용하는 것을 강력히 권장합니다. 액세스 토큰은 특정 권한만 부여할 수 있고 언제든 비활성화할 수 있어 훨씬 안전합니다.
Docker Hub 액세스 토큰 생성 방법:
- Docker Hub 로그인 > 우측 상단 프로필 클릭 > Account Settings
- 왼쪽 메뉴에서 Security > New Access Token 클릭
이제 준비된 액세스 토큰으로 아래 명령어를 실행합니다.
kubectl create secret docker-registry dockerhub-auth \
--docker-server=docker.io \
--docker-username=<도커허브_사용자이름> \
--docker-password=<도커허브_액세스토큰> \
-n my-app-space # 파드와 동일한 네임스페이스(필수)
- <시크릿_이름>: 나중에 사용하기 위해 지어주는 시크릿의 이름입니다. (예: dockerhub-auth)
- --docker-server: Docker Hub의 공식 서버 주소인 docker.io 입니다.
- --docker-username: 여러분의 Docker Hub 아이디입니다.
- --docker-password: 방금 생성한 액세스 토큰입니다.
- -n <네임스페이스>: 이 시크릿을 생성하고 사용할 네임스페이스입니다. Pod은 같은 네임스페이스에 있는 시크릿만 사용할 수 있으므로 매우 중요합니다.
2단계: 생성된 Secret 적용하기
시크릿을 만드는 것만으로는 끝나지 않습니다. Kubernetes에게 "이 시크릿을 사용해서 이미지를 가져와!"라고 알려주어야 합니다. 여기에는 두 가지 방법이 있습니다.
방법 1: Pod/Deployment에 직접 지정하기
가장 기본적인 방법입니다. 이미지를 사용하는 Pod, Deployment, StatefulSet 등의 YAML 파일에 직접 imagePullSecrets 필드를 추가합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-private-app
namespace: my-app-space
spec:
replicas: 3
selector:
matchLabels:
app: my-private-app
template:
metadata:
labels:
app: my-private-app
spec:
containers:
- name: app-container
image: mydockerid/my-private-image:1.0
imagePullSecrets:
- name: dockerhub-auth # 1단계에서 생성한 시크릿 이름
방법 2: ServiceAccount에 연결하여 네임스페이스 전체에 적용하기 (권장 👍)
매번 YAML 파일을 수정하는 것은 번거롭고 실수의 여지가 있습니다. 특정 네임스페이스의 모든 Pod이 기본적으로 이 인증 정보를 사용하게 하려면 ServiceAccount에 시크릿을 연결하는 것이 훨씬 효율적입니다.
아래 명령 한 줄이면 해당 네임스페이스의 default ServiceAccount에 시크릿이 영구적으로 연결됩니다.
kubectl patch serviceaccount default \
-p '{"imagePullSecrets": [{"name": "dockerhub-auth"}]}' \
-n my-app-space
이제 my-app-space 네임스페이스에 생성되는 모든 Pod은 YAML 파일에 imagePullSecrets를 명시하지 않아도 자동으로 dockerhub-auth 시크릿을 사용하여 프라이빗 이미지를 가져올 수 있습니다.
결론
이제 여러분의 Kubernetes 클러스터는 더 이상 ImagePullBackOff 에러를 뿜어내지 않고 Docker Hub의 프라이빗 이미지를 원활하게 배포할 수 있게 되었습니다.
정리하자면, kubectl create secret docker-registry 명령어로 액세스 토큰을 사용해 시크릿을 생성하고, 가급적 ServiceAccount에 연결하여 자동화하는 것이 가장 효율적이고 안전한 방법입니다. 이 간단한 설정으로 여러분의 CI/CD 파이프라인은 한 단계 더 부드러워질 것입니다.
'클라우드 > 쿠버네티스' 카테고리의 다른 글
| 놓치면 반드시 후회! 쿠버네티스 환경에서 꼭 수집해야 할 로그 총정리 (3) | 2025.07.31 |
|---|---|
| 쿠버네티스 Ingress Controller 대표 주자 3대장: NGINX, Traefik, HAProxy 전격 비교 (5) | 2025.07.31 |
| ☸️ 쿠버네티스와 🏦 Vault를 연동한 시크릿 관리 아키텍처 (5) | 2025.07.30 |
| 🤫 쿠버네티스 시크릿 관리의 정석: Vault와 KMS로 etcd 데이터 안전하게 지키기 (1) | 2025.07.30 |
| 쿠버네티스 프로브(Probe) 3대장: Liveness, Readiness, Startup은 왜 필요할까? (5) | 2025.07.30 |