본문 바로가기
k8s

K8S에서 private docker registry 띄우기

by marble25 2023. 4. 25.

쿠버네티스 상에서 image pull을 할 때, 원격 remote registry에서 pull할 수도 있지만, 때로는 보안 이슈로 원격 레지스트리에 올리지 못하는 경우도 존재한다. 이 경우, 직접 registry를 구축해야 한다.

널리 쓰이는 솔루션으로는 CNCF 프로젝트인 harbor가 존재한다. Harbor는 정책 및 액세스 제어로 아티팩트를 보호하고, 이미지를 스캔하고 취약점이 없는지 확인하고, 이미지를 신뢰할 수 있다고 서명하는 오픈 소스 레지스트리이다. 하지만 우리가 도입하기에는 너무 무겁다고 판단했다. 간단히 도커 이미지를 업로드하고 다운로드하는 정도의 기능만 필요하기 때문이다. 고로, k8s 내의 private docker registry 이미지를 이용하기로 결정했다.

방법

쿠버네티스를 위한 private docker registry를 띄우는데는 여러 가지 방법이 있다. 쿠버네티스 내부에 띄우는 것과 외부에 띄우는 것이 있다.

도커 레지스트리를 관리하는 측면에서 보았을 때 외부에 띄우는 것은 완전히 독립적으로 따로 관리를 해줘야 한다는 것을 의미한다. 인원적인 여유가 없는 실정에서는 따로 관리하기가 어렵다. 그래서 쿠버네티스 내부의 pod에 띄우는 방법을 채택했다.

실습

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-top-of-digitalocean-spaces-and-use-it-with-digitalocean-kubernetes

helm repo add twuni https://helm.twun.io

이 실습에서는 helm 차트를 이용했다. 가장 먼저 helm repo에 docker registry가 포함된 twuni repository를 추가한다.

ingress:
  enabled: true
  hosts:
    - registry.your_domain
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-body-size: "30720m"

persistence:
  enabled: true
  size: 1000Gi
helm install registry twuni/docker-registry -f chart_values.yaml

chart의 value들을 바꿔줄 수 있다. 더 자세한 configuration은 github을 참고할 수 있다.

테스트

먼저 테스트 이미지를 준비해서 넣어보자. mysql 이미지를 사용했다.

docker pull mysql
docker tag mysql registry.your_domain/mysql
docker push registry.your_domain/mysql

dns에도 registry를 추가했음에도 불가하고 push할 때 http server gave http response to https client 와 같은 에러가 발생하게 된다. 그 이유는 docker는 보안상의 이유로 ssl 인증을 하는 https를 기본적으로 사용하고 있기 때문이다.

‘쿠버네티스’를 사용하는데 도커 엔진 설정과 무슨 상관이냐고 생각할 수도 있지만, 기본적으로 쿠버네티스는 컨테이너 엔진 위에 존재하는 레이어이다. 즉, low level의 컨테이너는 도커(또는 containerd 등의 컨테이너 런타임)에게 맡겨놓고, 상위 레벨만 컨트롤하는 것이다.

실제로 쿠버네티스 노드에서 docker ps만 입력해 보더라도 다음과 같이 수많은 컨테이너를 볼 수 있다.

도커 엔진에서 pull & push를 담당하므로, 이와 관련된 설정도 도커 엔진쪽에다 해야 하는 것이다.

따라서 다음과 같이 변경해 주었다.

$ sudo vi /etc/docker/daemon.json
{
...
"insecure-registries": ["registry.your_domain"],
...
}

$ systemctl restart docker

docker에서 https를 사용하지 않는 registry로 새로 설치한 docker registry를 추가해 준 것이다. 이 설정을 모든 노드마다 해 주어야 한다. 마스터 노드를 restart하면 클러스터 정보가 날아갈 수도 있으니 주의하자.

docker push가 성공적으로 이루어졌다면 deployment도 만들어볼 수 있다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: registry.your_domain/mysql
        ports:
        - containerPort: 8080
kubectl apply -f mysql.yaml

정상적으로 설치가 이루어졌다면 mysql deployment를 확인할 수 있다.

'k8s' 카테고리의 다른 글

K8S role 파헤치기  (0) 2023.09.10
[TIL] regcred 알아보기  (0) 2023.04.24
K8S 컴포넌트 정리  (0) 2023.03.31
Kubernetes에서 NAS 사용하기  (0) 2023.03.26
Kubernetes 스토리지 구조  (0) 2023.03.26