포스트

Docker - Distribution (Registry)

docker image를 private로 공유하기 위해 사용한다.

처음에 사용하던 이름은 Registry였으나 CNCF에 기부되어 Distribution으로 명칭이 변경되었다.

https://docs.docker.com/registry/


0. 과정 요약

  1. 서버에 docker registry 공식 이미지 다운 받아 컨테이너 생성
    • registry가 사용하는 기본 포트는 5000번
    • container 내에서 docker image를 저장하는 경로는 /var/lib/registry/docker
  2. registry 컨테이너 실행
  3. 로컬 컴퓨터에서 이미지 생성 후 registry 서버로 업로드
  4. registry 서버에서 이미지 다운 받아 실행


1. registry 컨테이너 실행

서버에 접속해서 registry 이미지로 컨테이너를 실행한다.

1
2
3
4
5
6
7
8
9
10
11
12
# registry 컨테이너 실행
docker run -d \
-p 5555:5000 \
-v /usr/share/docker/images:/var/lib/registry/docker/ \
-e REGISTRY_STORAGE_DELETE_ENABLED=true \
-e REGISTRY_LOG_LEVEL=debug \
--name registry \
--restart always \
registry

# 컨테이너 상태 확인
docker ps
  • 환경 변수 중 REGISTRY_STORAGE_DELETE_ENABLED=true 은 이미지 삭제 활성화 옵션.
    이 옵션을 활성화 해야 registry에 올린 이미지를 삭제할 수 있다.


2. 로컬 컴퓨터에서 작업

1. 이미지 생성

다운 받아둔 nginx 이미지에 태그만 수정

1
docker image tag nginx localhost:5555/nginx:1.0


2. 이미지 업로드

1
2
3
4
5
docker push localhost:5555/nginx:1.0

# 로컬에 저장 된 이미지 삭제
docker rmi localhost:5555/nginx:1.0
docker rmi nginx


3. 이미지 다운 및 실행

1
2
3
4
5
6
7
docker pull localhost:5555/nginx:1.0

# 이미지 확인
docker images

# 실행
docker run -d -p 99:80 --name my-registry-web localhost:5555/nginx:1.0


4. 업로드한 이미지 목록 조회

1
curl http://localhost:5555/v2/_catalog


5. 업로드한 이미지 태그 목록 조회

1
curl http://localhost:5555/v2/{IMAGE_NAME}/tags/list


6. 업로드한 이미지 삭제

이미지를 삭제하려면 registry 컨테이너 실행 시 환경 변수 값으로 REGISTRY_STORAGE_DELETE_ENABLED=true을 추가해주어야 한다.

1. 이미지 Digest 가져오기

1
2
3
4
5
curl -v -s \
 -H "Cache-Control: no-cache" \
 -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
 "http://localhost:5555/v2/{IMAGE_NAME}/manifests/{TAG}" \
  2>&1 | grep -E 'Docker-Content-Digest|digest'
  • 응답 값 예시
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      Docker-Content-Digest: sha256:0db204f933b6d1def0c0c15578f61a80091f8316b04150918413fc4d5c87be69
          "digest": "sha256:4f67c83422ec747235357c04556616234e66fc3fa39cb4f40b2d4441ddd8f100"
             "digest": "sha256:09f376ebb190216b0459f470e71bec7b5dfa611d66bf008492b40dcc5f1d8eae"
             "digest": "sha256:5529e0792248c08c2352ae43a116a81867dcf661b77e422c99e3e14a7c9d4fa2"
             "digest": "sha256:9b3addd3eb3dbfb5b3d69303cd4aae75af5164f17e5d0319555c792af67536f9"
             "digest": "sha256:57910a8c431625fa6695de9a283b99d7b854c979b750c85c51ab6e987c602125"
             "digest": "sha256:7b5f78f214490830815a00b45e379db71d68f862ca8e8d523405188e5d253694"
             "digest": "sha256:b7923aa4e8a627b32d375c4f9a44c40f91a79acf706b7b0adaf4f0fc993ba8f5"
             "digest": "sha256:785625911f125e287a8a7b28a70c09a0229405ad28bfa837e1e25f06c967cc68"
    


2. 이미지 삭제

1
2
3
4
5
# DIGEST에 `Docker-Content-Digest` 값 사용
curl -X DELETE "http://localhost:5555/v2/{IMAGE_NAME}/manifests/{DIGEST}"

# DIGEST에 `digest` 값 사용
curl -X DELETE "http://localhost:5555/v2/{IMAGE_NAME}/blobs/{DIGEST}"
  • 응답 결과로 {"errors":[{"code":"UNSUPPORTED","message":"The operation is unsupported."}]} 이런 문구가 나타났다면 registry 서버에 이미지 삭제 옵션이 비활성화 되어있는 것이므로 활성화 해주어야 한다.


1
2
# GC 실행
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml


3. 볼륨 빈 디렉터리 삭제

1
find /HOST/PATH/VOLUMN/MOUNT/registry/v2/ -type d -empty -exec rmdir {} \; 
  • 이 작업을 해주어야 /v2/_catalog 조회 시 삭제한 이미지 이름이 사라짐



* let’s encrypt를 사용해서 서브 도메인에 registry 연결하기

서버에 nginx와 let’s encrypt가 세팅되어 있는 환경에서 docker registry에 SSL/TLS 인증서를 연결하여 서브 도메인으로 연결되도록 작업


1. 서브 도메인을 준비해둔다.

내 경우 registry.zhyun.kim 사용


2. 서버에 접속하여 서브 도메인으로 인증서를 설치

1
certbot --nginx -d registry.zhyun.kim
  • certbot이 nginx 설정 파일을 수정하도록 --nginx 옵션 사용


3. nginx 서버 설정 수정

nginx proxy pass를 이용해서 해당 서브 도메인으로 유입된 사용자를 registry port로 redirect 되도록 수정한다.

certbot에 의해 /etc/nginx/sites-enabled/default 파일의 맨 마지막 부분에 추가된 server 블록을 수정!
(server_name 확인)

1
2
# 설정파일 수정
vi /etc/nginx/sites-enabled/default
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 맨 아래에 추가된 서브 도메인의 server 블록을 수정한다.
..

server {
  server_name registry.zhyun.kim;

  # 파일 전송 최대 크기 수정. 0 = no limit
  client_max_body_size 0;
  
  location / {
      proxy_pass http://localhost:5555; # Docker Registry port 
      proxy_set_header Host               $host;
      proxy_set_header X-Real-IP          $remote_addr;
      proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto  $scheme;

      # 특수 ip 허용 설정 
      allow 허용.ip.add.ress;
      deny all;
  }

  ..
  
}


4. nginx 재시작

1
sudo systemctl restart nginx


5. 로컬 컴퓨터에서 registry 서버로 이미지 push/pull

1
2
3
4
5
# registy 서버로 전송
docker push registry.zhyun.kim/nginx:1.0

# registry 서버에서 다운로드
docker pull registry.zhyun.kim/nginx:1.0


* 계정 추가

registry 서버에 추가된 계정을 사용하는 접근만 registry 사용 할 수 있도록 설정

1. nginx 설정

registry 도메인 설정 파일의 server 블록에 다음을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
  ..
  
  location /v2/ {
      # Do not allow connections from docker 1.5 and earlier
      # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }
  
      # To add basic authentication to v2 use auth_basic setting.
      auth_basic "Registry realm";
      auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
  
      proxy_pass http://localhost:5555; # Docker Registry  
      proxy_set_header Host               $host;
      proxy_set_header X-Real-IP          $remote_addr;
      proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto  $scheme;
      proxy_read_timeout                  900;
   }
}


2. 계정 추가

id : testuser pw : testpassword

1
docker run --rm --entrypoint htpasswd httpd -Bbn testuser testpassword > /etc/nginx/conf.d/nginx.htpasswd


3. nginx 재시작

1
sudo systemctl restart nginx


4. 로컬에서 push / pull

registry 계정으로 docker 로그인 후 진행해야 한다.

1
2
3
4
5
6
7
8
9
10
11
# login
docker login registry.zhyun.kim -u=testuser -p=testpassword 

# image tag 수정
docker tag nginx:latest registry.zhyun.kim/nginx:latest

# push
docker push registry.zhyun.kim/nginx:latest

# pull
docker pull registry.zhyun.kim/nginx:latest


5. registry 이미지 삭제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# digest 가져오기
curl -v -s \
 -u testuser:testpassword \
 -H "Cache-Control: no-cache" \
 -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
 "https://registry.zhyun.kim/v2/cp-server-connect-datagen/manifests/latest" \
  2>&1 | grep Docker-Content-Digest

# 이미지 삭제
curl -u testuser:testpassword \
 -X DELETE "https://registry.zhyun.kim/v2/{IMAGE_NAME}/manifests/{DIGEST}"
curl -u testuser:testpassword \
 -X DELETE "https://registry.zhyun.kim/v2/{IMAGE_NAME}/blobs/{DIGEST}"
..




참고한 사이트

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.