Private Registry를 구축하게 된 이유는 딱 하나였다.
you have reached your pull rate limit
개발을 하면서 Docker의 Base Image들을 Docker hub에서 당겨오는데 이게 limit에 걸린 것 같다.
6시간내에 100번 당겨오면 정책에 걸리는 것 같은데 IP 기반으로 제한되기에, 장비 하나에서 많은 서비스들을 빌드하다보니 이렇게 된 것이다.
그렇다고 계속 IP를 바꾸기도 뭐하고, 6시간동안 가만히 있자니 뭐하고 해서 차라리 Private Registry를 구축해서 Docker Image를 넣어놓고 사용하고자 했다.
Kubernetes에 Registry 구축하기
Registry는 StatefulSet으로 올라면 되게 간단하게 구성할 수 있다.
registry.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: docker-registry
namespace: registry
spec:
replicas: 1
selector:
matchLabels:
app: docker-registry
template:
metadata:
labels:
app: docker-registry
spec:
containers:
- name: docker-registry
image: registry:2.7.1
ports:
- containerPort: 5000
volumeMounts:
- mountPath: /var/lib/registry
name: registry-storage
volumeClaimTemplates:
- metadata:
name: registry-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
storageClassName: standard-rwo
---
apiVersion: v1
kind: Service
metadata:
name: docker-registry
namespace: registry
spec:
type: ClusterIP
selector:
app: docker-registry
ports:
- protocol: TCP
port: 5000
targetPort: 5000
위처럼 yaml을 작성하고 kubectl apply로 설치해주면 끝이다.
Registry에 Image Push하기
Registry에 Push하기 전에 먼저 포트포워딩이 필요하다.
kubectl port-forward service/docker-registry 5000:5000 -n registry
docker-registry 서비스를 localhost에 5000 포트로 포워딩한 다음 아래 명령어를 순서대로 작성한다.
docker pull nginx:alpine
docker tag nginx:alpine localhost:5000/nginx:alpine
docker push localhost:5000/nginx:alpine
이렇게 되면 nginx:alpine의 이미지를 docker hub에서 당겨오고 docker-registry에 push하게 된다.
Registry Image 확인하기
apk add curl
registry는 cli를 지원하지 않고 API로 통신하기 때문에 curl을 설치해줘야한다.
curl localhost:5000/v2/_catalog
- 내부 Repo(Image) 리스트
curl localhost:5000/v2/nginx/tags/list
- nginx 이미지의 tag 리스트
다른 API들은 https://github.com/opencontainers/distribution-spec/blob/v1.0.1/spec.md#api 여기에 있는 것 같은데 뭔가 엉성하다…
(registry 공식문서 – https://docs.docker.com/registry/)
그렇기에 다른 블로그들을 참조하는게 더 편해보인다.
Dockerfile 수정하기
변경 전:
FROM nginx:alpine
변경 후:
FROM docker-registry.registry.svc.cluster.local:5000/nginx:alpine
Dockerfile에서 FROM으로 사용했던 Base Image에 docker-registry 서비스 명만 작성해주면 된다.
물론 Ingress를 붙여서 https 도메인을 통한 Pull도 되지만 Kubernetes에서 Pod의 Image로 사용하는 경우라면 서비스명이 더 좋다고 생각한다.
현재는 위처럼 적용해서 limit 자체를 피하고 있는데 추후에는 Cache 적용을 통해 빌드 속도를 개선해봐야겠다.