오늘 알게 된 건데, 아직도 노드마다 /etc/containerd/config.toml 안에 레지스트리별 auth를 박아두고 운영하는 팀이 생각보다 많다. 우리 팀도 작년까지 그랬다. 사내 Harbor, ECR, GHCR, Docker Hub 미러까지 네 개를 한 파일에 우겨넣다 보니 누가 한 줄만 잘못 건드려도 컨테이너런타임 재시작이 필요했다.
근데 containerd 1.5에서 추가되고 1.7 이후로는 사실상 표준이 된 config_path 방식 쓰면 이 짓을 안 해도 된다. 노드 재시작 없이, hot reload로 레지스트리 설정만 바꿀 수 있다.
핵심은 디렉터리 구조
/etc/containerd/config.toml에는 딱 한 줄만 둔다.
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
그리고 실제 설정은 디렉터리에 호스트별로 분리한다.
/etc/containerd/certs.d/
├── docker.io/
│ └── hosts.toml
├── ghcr.io/
│ └── hosts.toml
├── harbor.internal.corp/
│ └── hosts.toml
└── 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/
└── hosts.toml
hosts.toml 한 개당 한 레지스트리. 예를 들어 사내 Harbor에 미러를 두고 Docker Hub로 fallback 하는 설정이라면 docker.io/hosts.toml은 이렇게 쓴다.
server = "https://registry-1.docker.io"
[host."https://harbor.internal.corp/v2/dockerhub-proxy"]
capabilities = ["pull", "resolve"]
override_path = true
[host."https://registry-1.docker.io"]
capabilities = ["pull", "resolve"]
override_path = true가 은근히 함정인데, Harbor 같은 proxy cache 프로젝트는 경로 prefix가 다르기 때문에 이걸 안 주면 404가 난다. 한참 헤맸었다.
인증은 CRI 경로로 넘기는 게 정석
hosts.toml의 [host.* .auth] 필드에 직접 username/password를 쓸 수도 있는데, 노드에 평문이 깔리는 게 싫다면 kubelet의 ImagePullSecret 경로를 쓰면 된다. EKS 같은 환경에서는 IRSA나 Pod Identity로 ECR 토큰을 받아오기 때문에 노드 단에 굳이 cred를 둘 필요가 없다.
ECR처럼 토큰이 만료되는 레지스트리라면 kubelet-credential-provider 쪽을 보자. --image-credential-provider-config로 ecr-credential-provider 바이너리를 물려두면, hosts.toml에는 server URL만 있으면 된다.
노드 재시작 없이 바뀐다 — 정말로
가장 큰 장점이 이거다. /etc/containerd/certs.d/ 아래 파일을 갈아끼우면 containerd는 새 풀 요청부터 자동으로 새 설정을 읽는다. DaemonSet으로 hostPath 마운트해서 파일 뿌리는 식으로 운영하면, 레지스트리 추가/변경할 때 노드 재부팅이나 systemctl restart가 필요 없다.
다만 이미 진행 중인 pull은 기존 설정으로 끝나니까, 레지스트리 URL 바꿀 때 잠깐 혼란스러울 수 있다는 건 알아두면 좋다.
혹시 아직 config.toml 한 덩어리로 관리하고 있다면 한번 분리해 보세요. 운영 부담이 꽤 줄어듭니다.
'IT > 컨테이너' 카테고리의 다른 글
| BuildKit cache mount으로 CI 빌드 시간 7분 -> 40초 만든 가이드 (0) | 2026.06.21 |
|---|---|
| containerd NRI, 사실 내부적으로는 이렇게 돌아간다 (1) | 2026.06.11 |
| BuildKit cache mount 제대로 쓰는 법 — Rust/Node CI 빌드 시간을 절반으로 (0) | 2026.06.08 |
| cgroup v2 전환 후 OOMKill 동작이 바뀐 이유 (0) | 2026.06.04 |
| Spegel로 in-cluster 이미지 미러 만들기 (0) | 2026.05.27 |