배경

얼마 전 큰마음을 먹고 Synology NAS를 다시 써보기로 했다.

가장 큰 니즈는 컨테이너 서비스들을 외부 클라우드 서비스에 의존하지 않고 운영할 수 있는 것이다. 다만 아직 관리가 미숙하다고 생각되는 Kubernetes Cluster와 Database는 관리형으로 두고 있는데 최근에 Kubernetes Cluster로 개인 서비스를 이전하면서 Container Registry부터 NAS에 띄워봐야겠다는 생각이 들었다.

Digital Ocean에서는 Container Registry를 무료로도 제공해 주고 있는데 repository는 하나만 쓸 수 있고 스토리지도 500MB의 리밋이 걸려있다. Kubernetes Cluster 맛보기를 하는 과정에서는 한 번 가볍게 써보는 것까진 좋았는데 repository 수를 풀고 용량도 조금 더 받는데 $5의 비용을 내는 것부터 해결해 볼 수 있겠다는 생각이 들었다.

Registry 설치 및 실행

우선 NAS에 Container Manager가 설치되어 있다는 전제로 registry 이미지를 다운로드한다. (컨테이너 이미지 영역)

컨테이너 메뉴에서 이제 서비스를 띄워야 하는데 입력해야 하는 항목은 아래와 같다.

  • 자동 재시작 활성화: YES
  • 포트: xxxx -> 5000
    • Synology DSM의 기본 포트가 5000번이라서 다른 포트로 받아주고 컨테이너의 5000번으로 맵핑
  • 볼륨 설정
    • {NAS내 폴더 (ex. /docker/registry/tmp/registry)}}:/tmp/registry
    • {NAS내 폴더 (ex. /docker/registry/tmp/registry-dev)}}:/tmp/registry-dev
    • {NAS내 폴더 (ex. /docker/registry/varlibregistry)}}:/var/lib/registry
    • {NAS내 폴더 (ex. /docker/registry/auth)}}:/auth
  • 환경 변수
    • REGISTRY_AUTH=htpasswd
    • REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
    • REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd

이렇게 하고 컨테이너 서비스를 시작하면 NAS에 Private Container Registry가 뚝딱 만들어진다.

위의 변수들 중에서 환경 변수는 Private이니 인증을 넣는 차원에서 필요한 부분인데 기본적인 credential은 직접 htpasswd를 만들어서 쓸 수도 있고 따로 하지 않아도 기본적으로 생성을 해주기 때문에 만들어준 username과 password를 이용해도 무방하다.

기본으로 생성하는 경우에는 컨테이너 로그를 확인해 보면 username과 password를 확인할 수 있다.

docker login {NAS host:5050}
docker tag {image} {NAS host:5050}/{image}
docker push {NAS host:5050}/{image}

위의 방법으로 이미지가 잘 push 되는지 확인할 수 있다.


하지만 이대로라면 이런 문제가 발생할 수 있다.

Error response from daemon: Get "{NAS host}:5050/v2/": http: server gave HTTP response to HTTPS client

인증서 설정이 잘되어 있고 https로 요청을 받았다면 문제가 생기지 않았을 텐데 우리는 NAS로 받아야 하고 이는 홈 라우터의 포트포워딩으로 요청을 받고 있을테니 http로 응답을 주고받기 때문이다. 이 경우에는 같은 해결 방안이지만 docker 기반이나 containerd 기반이냐에 따라 수정해야 할 부분이 다르다. 일반적으로 개인 개발 환경은 docker 베이스이기 때문에 docker 설정만 바꾸면 되지만, kubernetes의 경우 1.22 버전 이후에는 containerd를 쓰고 있어서 설정의 위치와 방식이 달라졌다.

Docker 기반의 설정 변경

/etc/docker/daemon.json 파일을 열고 아래 설정을 추가해준다.

{
  "insecure-registries": ["{NAS host}:5050"]
}

docker 서비스를 재시작 해준다.

sudo systemctl restart docker

Kubernetes 기반의 설정 변경

Cluster에 N 개의 노드가 존재한다면 각 노드마다 설정을 변경해 줘야 한다.

/etc/containerd/config.toml 파일을 열고 아래 설정을 추가해 준다.

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."{NAS host}:5050"]
    endpoint = ["{NAS host}:5050"]

containerd 서비스를 재시작 해준다.

sudo systemctl restart containerd

위의 설정을 마치고 나면 이미지를 pull 하는데 문제없이 되는 것을 확인할 수 있다.