최근 외부 인터넷으로의 접근이 제한된 환경에 k8s를 구축하고 spaceone을 설치해볼 일이 생겼다.
외부 인터넷으로의 접근이 제한된 환경이라면 외부 image repository(docker hub등)에 접근이 불가능어려우니,
내부 네트워크에 image repository 구축하고 그곳을 통해 application image를 가져오도록 해야했다.
그 과정에서 잊고 지내던 pause container와 재회(?)하게 되면서 겪은 내용에 대해 기록한다.
(사실, 내가 잘 찾아보지 않아서...)
이번 설치 과정에서는 harbor를 구축해 내부 repository를 바라볼 수 있도록 했고, 처음 테스트는 성공이었다.
그런데 정확한 검증을 위해 Out-bound를 차단하여 다시 설치를 진행해보니, pod가 ContainerCreating
에서 멈춰서 더 이상 진행이 되지 않았다.
이미 첫 테스트에서 내부 repository에서 이미지를 가져와 설치에 성공했으니, 다른 의심은 하지않고
harbor에 이미지 요청이 몰려서 그런가?(테스트용인 만큼, 낮은 spec의 서버에 올렸다.)
worker node가 열일 중이라 느린건가? 싶었다.
그런데 너무 지나치다 싶어 살펴보니, 아래와 같은 로그를 발견했다.
Warning FailedCreatePodSandBox 9s (x20 over 13m) kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "registry.k8s.io/pause:3.6": failed to pull image "registry.k8s.io/pause:3.6": failed to pull and unpack image "registry.k8s.io/pause:3.6": failed to resolve reference "registry.k8s.io/pause:3.6": failed to do request: Head "https://registry.k8s.io/v2/pause/manifests/3.6": dial tcp 34.107.244.51:443: i/o timeout
핫... registry.k8s.io/pause:3.6
라니... 뭐지... 얘는 어디서 많이 본 것 같은데..
멘붕에 빠질 무렵, 기억 저편에서부터 뭔가 기억나기 시작했다.
FailedCreatePodSandBox
...Failed to create pod sandbox
...pause
...
아.. 맞다... 독립된 pod environment(network 등)유지를 위해 pause container가 돌지...
얘도 이미지를 가져오는거구나...그렇겠지... 그럼 얘도 내부 repository에서 가져오도록 설정해줘야겠구나...
ㅠㅠ... 직접 k8s cluster를 구축하지 않고, managed만 써왔던 내 잘못이었다..
podSandbox, pause container에 대해서는 추후에 정리하겠다.
podSandbox와 pause container에 대해서는 여기....
pod가 container creating 단계에서 멈춘 원인을 알았으니, 이제 이를 위한 설정을 해보자.
custom sandbox를 사용하기 위해서는, container runtime의 설정을 바꿔주면 OK였다.
이런 설정을 통해 kubelet이 pod sandbox를 만들때 pause image를 설정한 repository에서 가져오기 시작했다.
NOTE: 본 테스트 환경의 경우 containerd가 runtime으로 돌고있다.
sandbox_image
in container config (default: /etc/containerd/config.toml
) [plugins."io.containerd.grpc.v1.cri"]
(...omit...)
sandbox_image = "<your.registry.address>/pause:3.6"
systemctl restart containerd
image repository가 내부 네트워크에 있더라도 비공개로 되어있어 인증이 필요한 경우가 있다.
repository credential을 설정하는 방법은 여러가지 있지만, 마찬가지로 container runtime 설정으로 해결할 수 있다.
mirror
,auth
in container config (default: /etc/containerd/config.toml
) [plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
+ [plugins."io.containerd.grpc.v1.cri".registry.configs."<your.repository.address>".auth]
+ username = "<username>"
+ password = "<password>"
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
+ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."<your.repository.address>"]
+ endpoint = ["https://<your.repository.address>"]
systemctl restart containerd
설정 후 문제없이 특정 repository에서 이미지를 가져오는지 crictl
로 확인할 수 있다.
crictl pull <your.repository.address>/pause:<tag>
이번 내용은 사실 처음부터 차단된 네트워크 환경에서 k8s cluster 구축을 계획하고 실행했었다면
사실 여기에 일기처럼 써낼 필요도 없을 만큼 당연히 고려를 했어야할 문제라고 생각한다.
최근 클라우드에서만 지내다보니, 이렇게 실수아닌 실수를 하는 것이 종종 발생하곤 하는데
그럼에도 이러한 삽질을 통해 잊고 지내던 것들과 다시 재회하고 새롭게 알아가는 과정을 거치면서
그에 대한 지식도 조금식 더 단단해지는 것이 아닐까 생각된다.
뭐... 앞으로도 삽질 또 삽질이다.