개요

Kubernetes에서 개발을 하다보면 public repository에 배포하기엔 좀 그렇고 private repository에 테스트를 위해 잠깐 배포하고자 할 경우가 생긴다. Minikube에서 private repository에 접근하는 방법을 알아보자.
Public network상의 repository를 구현하는 방법은 문서가 잘 되어있고 테스트 목적이기 때문에 private network 상에서 구현하는 방법을 다룬다. 그리고 local이 아닌 환경에서도 적용할 수 있도록 https위에서 구현하는 방법을 다룬다.

Private netowrk에서 SSL 필요성

간단하게 local machine에서 구동하는 경우 공격자가 해당 공유기에 접근할 수 있지 않은 이상 사실 상 공격당할 일은 거의 없다. 따라서 대부분의 경우 insecure registries에 추가해서 사용해도 상관없다. 하지만 private network의 규모가 큰 경우에는 하나의 호스트가 감염될 경우 Man In The Middle, ARP Spoofing등 과 같은 공격에 취약할 수 있기 때문에 SSL을 사용하는게 바람직하다.

openssl을 이용해 key와 증명서 만들기

openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
  -addext "subjectAltName = DNS:myregistry.domain.com" \
  -x509 -days 365 -out certs/domain.crt

myregistry.domain.com 대신 본인이 사용할 도메인 네임을 사용하면 된다. 후에 반드시 자체 네임 서버를 이용하든 local dns 서버를 사용하든 해당 repository ip로 resolve되면 된다.

Private repository 만들기

이제 증명서를 만들었으니 해당 증명서를 활용하여 repository를 만들어야 한다. local machine에서 작동하든 다른 machine에서 하든 방법은 동일하다.

docker run -d \
  --restart=always \
  --name registry \
  -v "$(pwd)"/certs:/certs \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  -p 443:443 \
  registry:2

환경 변수 REGISTRY_HTTP_TLS_CERTIFICATE, REGISTRY_HTTP_TLS_KEY는 증명서의 위치에 따라 변경해 주면 된다. 이후 추가 정보를 입력할 때 Common Name만 으로 잘 입력해 주면 된다. 나머지는 아무거나 적어도 상관없다.

Minikube 설정하기

Minikube에서 ssl을 이용해 접근하려면 도메인 네임으로 접근할 수 있어야한다. /etc/hosts파일에 다음을 추가한다.

# ...
<ip_address>    <domain_name>

ip_address에는 private repository의 주소, domain_name에는 증명서를 만들때 정했던 도메인 네임을 사용하면 된다.
예를 들어 다음과 같이 추가하면 된다.

192.168.11.111  myregistry.domain.com

이제 도커에서 해당 증명서를 신뢰할 수 있도록 만들어진 증명서를 복사해야 한다. openssl을 통해 만든 domain.crt를 접근할 호스트의 /etc/docker/certs.d/<domain_name>/ca.crt에 복사한다.

우리는 Minikube에서 접근할 것이므로 minikube 쉘에서 복사하면 된다.

확인하고 싶으면 private repository에 이미지를 push한 후 Minikube 쉘에서 pull 해보면 잘 되는지 확인할 수 있다.

docker image pull <domain_name>/<image_name>

주의사항으로 minikube를 끄고 다시 실행할 경우 증명서는 남아있지만 hosts내부의 내용은 초기화 되므로 다시 설정해 주어야 한다!!!


Reference