사설 레지스트리(Harbor · Nexus 등)에서 이미지를 받으려면 kubelet 이 쓸 자격증명을 kubernetes.io/dockerconfigjson 타입 Secret 으로 두고, Pod 나 ServiceAccount 의 imagePullSecrets 로 지정한다. Secret 은 네임스페이스 단위라서 이미지를 쓰는 네임스페이스마다 만들어야 한다[1].
kubectl create secret docker-registry regcred \
--namespace $NAMESPACE \
--docker-server=$REGISTRY_HOST:$PORT \
--docker-username=$USERNAME \
--docker-password='${PASSWORD}' \
--docker-email=$EMAIL
Docker Hub 는 --docker-server=https://index.docker.io/v1/ 다. 명령줄에 암호를 쓰면 셸 히스토리에 남으므로 공용 서버에서는 아래 방법을 쓴다.
이미 docker login 한 호스트의 ~/.docker/config.json 을 그대로 넣는다. 자격증명 저장소(credsStore)를 쓰는 데스크톱 Docker 는 파일에 토큰이 없으므로 이 방법이 안 된다.
kubectl create secret generic regcred \
--namespace $NAMESPACE \
--from-file=.dockerconfigjson=$HOME/.docker/config.json \
--type=kubernetes.io/dockerconfigjson
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: default
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64 로 인코딩한 config.json>
kubectl get secret regcred --output=yaml
kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: app
image: harbor.example.com/demo/app:1.0
imagePullSecrets:
- name: regcred
네임스페이스의 모든 Pod 에 자동으로 넣고 싶으면 ServiceAccount 에 붙인다. default ServiceAccount 에 붙이면 그 네임스페이스에서 만드는 Pod 가 전부 받는다.
kubectl patch serviceaccount default -n $NAMESPACE \
-p '{"imagePullSecrets": [{"name": "regcred"}]}'
kubectl get serviceaccount default -n $NAMESPACE -o yaml
kubectl run pull-test --image=harbor.example.com/demo/app:1.0 --overrides='{"spec":{"imagePullSecrets":[{"name":"regcred"}]}}'
kubectl describe pod pull-test | grep -A3 Events
kubectl delete pod pull-test
ErrImagePull · ImagePullBackOff 가 나면 describe 의 이벤트에 401(자격증명) 인지 x509(인증서) 인지가 찍힌다. 인증서 문제는 노드의 containerd 에 CA 를 넣어야 한다 — Private repository 설정 - Harbor.