웹사이트 검색

Ubuntu 14.04에서 개인 Docker 레지스트리를 설정하는 방법


소개

Docker는 서버 배포를 위한 훌륭한 도구입니다. Docker에는 Docker 이미지를 저장하기 위한 Docker Hub라는 공용 레지스트리도 있습니다. Docker를 사용하면 Docker 생성을 Docker 허브에 무료로 업로드할 수 있지만 업로드하는 모든 항목도 공개됩니다. 이것은 프로젝트에 가장 적합한 옵션이 아닐 수 있습니다.

이 가이드는 개인 Docker 레지스트리를 설정하고 보호하는 방법을 보여줍니다. 이 자습서가 끝나면 사용자 지정 Docker 이미지를 개인 레지스트리에 푸시하고 다른 호스트에서 안전하게 이미지를 가져올 수 있습니다.

이 자습서에서는 자체 애플리케이션 컨테이너화를 다루지 않고 배포를 저장할 수 있는 레지스트리를 만드는 방법만 다룹니다. Docker 자체를 시작하는 방법(레지스트리와 반대)을 배우려면 Docker 설치 및 사용 방법: 시작하기 자습서를 읽으십시오.

이 가이드는 Ubuntu 14.04를 실행하는 레지스트리 서버와 레지스트리 클라이언트 모두에서 테스트되었지만 다른 Debian 기반 배포판에서도 작동할 수 있습니다. 또한 Docker Registry 버전 2.0도 다룹니다.

도커 개념

이전에 Docker를 사용해 본 적이 없다면 Docker의 몇 가지 주요 개념을 살펴보는 데 시간을 할애할 가치가 있습니다. 이미 Docker를 사용 중이고 자신의 레지스트리 실행을 시작하는 방법을 알고 싶다면 다음 섹션으로 건너뛰십시오.

Docker 사용 방법에 대한 복습을 위해 훌륭한 Docker Cheat Sheet를 살펴보세요.

Docker의 핵심은 운영 체제 자체에서 애플리케이션을 실행하는 데 필요한 종속성과 애플리케이션을 분리하는 방법입니다. 이를 가능하게 하기 위해 Docker는 컨테이너이미지를 사용합니다. Docker 이미지는 기본적으로 파일 시스템의 템플릿입니다. Docker 이미지를 실행하면 이 파일 시스템의 인스턴스가 활성화되어 Docker 컨테이너 내부의 시스템에서 실행됩니다. 기본적으로 이 컨테이너는 원본 이미지 자체 또는 Docker가 실행 중인 호스트의 파일 시스템을 건드릴 수 없습니다. 독립된 환경입니다.

컨테이너에서 변경한 사항은 해당 컨테이너 자체에 보존되며 원본 이미지에는 영향을 주지 않습니다. 이러한 변경 사항을 유지하기로 결정한 경우 docker commit 명령을 통해 컨테이너를 Docker 이미지에 \커밋\할 수 있습니다. 즉, 다음으로 시작하는 새 컨테이너를 생성할 수 있습니다. 원본 컨테이너(또는 이미지)에 영향을 주지 않고 이전 컨테이너의 콘텐츠. git에 익숙하다면 워크플로가 상당히 비슷해 보일 것입니다. 새 브랜치를 만들 수 있습니다(Docker 용어로 이미지). 이미지를 실행하는 것은 git checkout을 수행하는 것과 비슷합니다.

비유를 계속하자면 개인 Docker 레지스트리를 실행하는 것은 Docker 이미지에 대한 개인 Git 리포지토리를 실행하는 것과 같습니다.

전제 조건

이 자습서를 완료하려면 다음이 필요합니다.

  • 2개의 Ubuntu 14.04 드롭릿: 개인 Docker 레지스트리용 하나와 Docker 클라이언트용 하나
  • 각 Droplet에 대한 sudo 권한이 있는 루트가 아닌 사용자(Ubuntu 14.04의 초기 서버 설정에 설정 방법이 설명되어 있음)
  • Ubuntu 14.04에서 Docker Compose를 설치하고 사용하는 방법의 지침에 따라 설치된 Docker 및 Docker Compose
  • 개인 Docker 레지스트리의 Droplet으로 확인되는 도메인 이름

1단계 - 보안 강화를 위한 패키지 설치

Docker 레지스트리에 대한 보안을 설정하려면 Docker Compose를 사용하는 것이 가장 좋습니다. 이렇게 하면 하나의 컨테이너에서 Docker 레지스트리를 쉽게 실행하고 Nginx가 다른 컨테이너에서 보안 및 외부 세계와의 통신을 처리하도록 할 수 있습니다. 필수 구성 요소 섹션에서 이미 설치되어 있어야 합니다.

Nginx를 사용하여 보안을 처리할 것이므로 레지스트리에 액세스하려는 사용자 이름과 비밀번호 조합 목록을 저장할 장소도 필요합니다. Nginx가 이해할 수 있는 암호 해시를 쉽게 생성할 수 있는 htpasswd 유틸리티가 포함된 apache2-utils 패키지를 설치합니다.

  1. sudo apt-get -y install apache2-utils

2단계 - Docker 레지스트리 설치 및 구성

Docker 명령줄 도구는 Docker 컨테이너를 시작하고 관리하는 데 적합하지만 Docker 컨테이너 내에서 실행되는 대부분의 앱은 독립적으로 존재하지 않습니다. 대부분의 앱을 완전히 배포하려면 병렬로 실행되는 몇 가지 구성 요소가 필요합니다. 예를 들어 대부분의 웹 애플리케이션은 앱의 코드를 제공하는 웹 서버, PHP 또는 Ruby(Rails 포함)와 같은 해석된 스크립팅 언어, MySQL과 같은 데이터베이스 서버로 구성됩니다.

Docker Compose를 사용하면 각 컨테이너의 구성에 대한 하나의 .yml 구성 파일과 컨테이너가 서로 통신하는 방법에 대한 정보를 작성할 수 있습니다. 그런 다음 docker-compose 명령줄 도구를 사용하여 애플리케이션을 구성하는 모든 구성 요소에 명령을 실행합니다.

Docker 레지스트리 자체는 여러 구성 요소가 있는 애플리케이션이므로 Docker Compose를 사용하여 구성을 관리합니다.

기본 레지스트리를 시작하기 위해 필요한 유일한 구성은 레지스트리가 데이터를 저장할 위치를 정의하는 것입니다. 기본 Docker Compose YAML 파일을 설정하여 레지스트리의 기본 인스턴스를 가져오겠습니다.

먼저 이 튜토리얼의 파일이 저장될 폴더와 필요한 일부 하위 폴더를 만듭니다.

  1. mkdir ~/docker-registry && cd $_
  2. mkdir data

즐겨 사용하는 텍스트 편집기를 사용하여 docker-compose.yml 파일을 만듭니다.

  1. nano docker-compose.yml

파일에 다음 콘텐츠를 추가합니다.

registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

여기서 흥미로운 부분은 끝에 있습니다. environment 섹션은 /data 경로를 사용하여 Docker 레지스트리 컨테이너에 환경 변수를 설정합니다. Docker 레지스트리 앱은 시작할 때 이 환경 변수를 확인하고 그 결과 데이터를 /data 폴더에 저장하기 시작한다는 것을 알고 있습니다.

이 경우에만 volumes: - ./data:/data 비트는 해당 컨테이너의 /data 디렉토리가 실제로 /에 매핑되어야 함을 Docker에 알려줍니다. 데이터 호스트 시스템에 있습니다. 따라서 최종 결과는 Docker 레지스트리의 데이터가 모두 로컬 시스템의 ~/docker-registry/data에 저장된다는 것입니다.

계속해서 시작하여 모든 것이 정상인지 확인하십시오.

  1. cd ~/docker-registry
  2. docker-compose up

많은 다운로드 막대가 화면을 가로질러 이동하는 것을 볼 수 있습니다(이는 Docker가 Docker의 자체 Docker 레지스트리에서 실제 Docker 레지스트리 이미지를 다운로드함). 1~2분 안에 모든 것이 잘 진행되면 다음과 같은 출력이 표시됩니다(버전은 다를 수 있음).

Output of docker-compose up
registry_1 | time="2015-10-18T23:45:58Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1 registry_1 | time="2015-10-18T23:45:58Z" level=info msg="redis not configured" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1 registry_1 | time="2015-10-18T23:45:58Z" level=info msg="using inmemory blob descriptor cache" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1 registry_1 | time="2015-10-18T23:45:58Z" level=info msg="listening on [::]:5000" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1 registry_1 | time="2015-10-18T23:45:58Z" level=info msg="Starting upload purge in 1m0s" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1

제공된 HTTP 비밀 없음 메시지에 대해 걱정하지 마십시오. 정상입니다.

엄청난! 이 시점에서 이미 전체 Docker 레지스트리가 준비되어 있고 포트 5000에서 수신 대기하고 있습니다(이는 docker-compose.ymlports: 비트에 의해 설정됨). 파일). 이 시점에서 레지스트리는 아직 그다지 유용하지 않습니다. 레지스트리를 수동으로 불러오지 않으면 시작되지 않습니다. 또한 Docker 레지스트리에는 인증 메커니즘이 내장되어 있지 않으므로 현재로서는 안전하지 않고 완전히 공개되어 있습니다.

Docker Compose는 기본적으로 입력을 영원히 기다리므로 계속해서 CTRL-C를 눌러 Docker 레지스트리 컨테이너를 종료합니다.

3단계 - Nginx 컨테이너 설정

이러한 보안 문제를 해결하기 위해 노력하겠습니다. 첫 번째 단계는 다른 Docker 컨테이너 내에 Nginx 사본을 설정하고 이를 Docker 레지스트리 컨테이너에 연결하는 것입니다.

Nginx 구성을 저장할 디렉토리를 생성하여 시작하겠습니다.

  1. mkdir ~/docker-registry/nginx

이제 ~/docker-registry 디렉터리에서 docker-compose.yml 파일을 다시 엽니다.

  1. nano docker-compose.yml

파일 상단에 다음을 붙여넣습니다.

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro

이렇게 하면 공식 Nginx 이미지를 기반으로 새로운 Docker 컨테이너가 생성됩니다. 여기서 흥미로운 부분은 links 섹션입니다. 하나의 Docker 컨테이너에서 다른 Docker 컨테이너로 "링크\를 자동으로 설정합니다. Nginx 컨테이너가 시작되면 호스트 이름 registryregistry 컨테이너에 도달할 수 있습니다. > registry 컨테이너가 최종적으로 갖게 되는 실제 IP 주소가 무엇이든 상관없습니다.(뒤에서 Docker는 실제로 항목을 /etc/hosts 파일에 삽입합니다. >nginx 컨테이너에 registry 컨테이너의 IP를 알려줍니다.

volumes: 섹션은 registry 컨테이너에 대해 수행한 것과 유사합니다. 이 경우 Nginx에 사용할 구성 파일을 Docker 컨테이너 내부가 아닌 호스트 시스템에 저장할 수 있습니다. 끝에 있는 :ro는 Nginx 컨테이너가 호스트 파일 시스템에 대한 읽기 전용 액세스 권한만 가져야 함을 Docker에 알려줍니다.

전체 docker-compose.yml 파일은 이제 다음과 같아야 합니다.

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

이제 docker-compose up을 실행하면 두 개의 컨테이너가 동시에 시작됩니다. 하나는 Docker 레지스트리용이고 다른 하나는 Nginx용입니다.

이것이 작동하기 전에 Nginx를 구성해야 하므로 새 Nginx 구성 파일을 생성하겠습니다.

registry.conf 파일을 만듭니다.

  1. nano ~/docker-registry/nginx/registry.conf

다음을 파일에 복사합니다.

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  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 plus add_header
    # auth_basic "registry.localhost";
    # auth_basic_user_file /etc/nginx/conf.d/registry.password;
    # add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;
  }
}

파일을 저장하고 종료합니다.

이제 하나의 명령으로 Nginx를 설치하고 두 개의 Docker 컨테이너를 시작할 수 있습니다.

  1. docker-compose up

Nginx는 시작할 때 어떤 출력도 출력하지 않지만 모든 것이 잘 되었다면 이제 레지스트리 컨테이너에 프록시하도록 설정된 Nginx 복사본을 실행하고 있는 것입니다. 이를 테스트하기 위해 curl을 사용하여 Docker 레지스트리에 직접 HTTP 요청을 한 다음 Nginx 포트에 또 다른 요청을 합니다. 모든 것이 올바르게 설정되면 Nginx가 Docker 레지스트리를 통해 요청을 프록시하므로 출력은 두 경우 모두 동일합니다(이 글을 쓰는 시점에서 Docker는 빈 json 객체 "{}”를 반환함). .

먼저 Docker 레지스트리에 직접 HTTP 요청을 수행합니다.

  1. curl http://localhost:5000/v2/

이 글을 쓰는 시점에서 Docker는 빈 json 객체를 반환하므로 다음을 볼 수 있습니다.

Output
{}

이제 Nginx 포트에 HTTP 요청을 보냅니다.

  1. curl http://localhost:5043/v2/

동일한 출력이 표시되어야 합니다.

Output
{}

올바르게 작동하는 경우 docker-compose 터미널에 다음과 같은 일부 출력이 표시됩니다.

Output of docker-compose
registry_1 | time="2015-08-11T10:24:53.746529894Z" level=debug msg="authorizing request" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1 registry_1 | time="2015-08-11T10:24:53.747650205Z" level=info msg="response completed" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" http.response.contenttype="application/json; charset=utf-8" http.response.duration=8.143193ms http.response.status=200 http.response.written=2 instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1 registry_1 | 172.17.0.21 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.35.0" nginx_1 | 172.17.42.1 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.35.0" "-"

registry_ 접두사가 있는 줄이 보이면(_ 뒤의 숫자는 시스템에 따라 다를 수 있음) 아무 문제가 없으며 Nginx가 성공적으로 HTTP 요청을 도커 레지스트리.

계속해서 docker-compose 터미널에서 CTRL-C를 다시 눌러 Docker 컨테이너를 종료하세요.

4단계 - 인증 설정

이제 Nginx가 요청을 적절하게 프록시하고 있으므로 HTTP 인증으로 설정하여 Docker 레지스트리에 액세스할 수 있는 사용자를 제어할 수 있습니다. 이를 위해 이전에 설치한 htpasswd 유틸리티를 통해 Apache 형식(Nginx도 읽을 수 있음)으로 인증 파일을 만들고 여기에 사용자를 추가합니다.

다음과 같이 첫 번째 사용자를 생성하고 USERNAME을 사용하려는 사용자 이름으로 바꿉니다.

  1. cd ~/docker-registry/nginx
  2. htpasswd -c registry.password USERNAME

메시지가 표시되면 이 사용자의 새 암호를 생성합니다.

나중에 더 많은 사용자를 추가하려면 -c 옵션(c는 만들기용임) 없이 위 명령어를 다시 실행하세요.

  1. htpasswd registry.password USERNAME

이제 사용자가 설정한 registry.password 파일과 사용 가능한 Docker 레지스트리가 있습니다. 사용자를 보려면 언제든지 파일을 들여다볼 수 있습니다(액세스를 취소하려면 사용자를 제거해야 함).

다음으로 Nginx에게 해당 인증 파일을 사용하도록 지시해야 합니다.

원하는 텍스트 편집기에서 ~/docker-registry/nginx/registry.conf를 엽니다.

  1. nano ~/docker-registry/nginx/registry.conf

파일 중간으로 스크롤하면 다음과 같은 줄이 표시됩니다.

# To add basic authentication to v2 use auth_basic setting plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

auth_basic로 시작하는 두 줄과 # 문자를 제거하여 add_header로 시작하는 줄의 주석 처리를 제거합니다. 처음에

# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

이제 Nginx에 Docker 레지스트리로 프록시되는 모든 요청에 대해 HTTP 기본 인증을 활성화하고 방금 생성한 암호 파일을 사용하도록 지시했습니다.

인증이 작동하는지 확인하기 위해 컨테이너를 백업해 보겠습니다.

  1. cd ~/docker-registry
  2. docker-compose up

이전 컬 테스트를 반복합니다.

  1. curl http://localhost:5043/v2/

승인되지 않은 것에 대해 불평하는 메시지를 받아야 합니다.

Output of curl
<html> <head><title>401 Authorization Required</title></head> <body bgcolor="white"> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.9.7</center> </body> </html>

이제 이전에 만든 사용자 이름과 비밀번호를 curl 요청에 추가해 보세요.

  1. curl http://USERNAME:PASSWORD@localhost:5043/v2/

이전에 얻었던 것과 동일한 출력, 즉 빈 json 객체 {}를 얻어야 합니다. 또한 docker-compose 터미널에 동일한 registry_ 출력이 표시되어야 합니다.

계속해서 docker-compose 터미널에서 CTRL-C를 사용하여 Docker 컨테이너를 종료합니다.

5단계 - SSL 설정

이 시점에서 우리는 HTTP 기본 인증이 작동하는 Nginx 뒤에서 레지스트리를 실행하고 있습니다. 그러나 연결이 암호화되지 않았기 때문에 설정은 여전히 안전하지 않습니다. 이전에 만든 Nginx 구성 파일에서 주석 처리된 SSL 행을 눈치챘을 것입니다.

활성화합시다. 먼저 편집을 위해 Nginx 구성 파일을 엽니다.

  1. nano ~/docker-registry/nginx/registry.conf

화살표 키를 사용하여 이동하고 다음 줄을 찾습니다.

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

앞에 있는 # 문자를 제거하여 SSL 주석 아래 줄의 주석을 해제합니다. 서버에 도메인 이름을 설정한 경우 server_name 값을 도메인 이름으로 변경하세요. 완료되면 파일의 맨 위가 다음과 같아야 합니다.

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  ssl on;
  ssl_certificate /etc/nginx/conf.d/domain.crt;
  ssl_certificate_key /etc/nginx/conf.d/domain.key;

파일을 저장합니다. Nginx는 이제 SSL을 사용하도록 구성되었으며 /etc/nginx/conf.d/domain.crt/etc/nginx/conf.d/에서 SSL 인증서 및 키 파일을 찾습니다. domain.key 각각. 이전에 docker-compose.yml 파일에서 설정한 매핑으로 인해 Nginx 컨테이너의 /etc/nginx/conf.d/ 경로는 < 폴더에 해당합니다.~/docker-registry/nginx/ 호스트 컴퓨터에 있으므로 인증서 파일을 거기에 넣습니다.

이미 SSL 인증서를 설정했거나 구입할 계획이라면 인증서와 키 파일을 registry.conf(ssl_certificatessl_certificate_key).

무료로 서명된 SSL 인증서를 받을 수도 있습니다.

그렇지 않으면 자체 서명된 SSL 인증서를 사용해야 합니다.

자신의 인증서 서명

Docker는 현재 자체 서명된 SSL 인증서를 사용하는 것을 허용하지 않기 때문에 평소보다 약간 더 복잡합니다. 또한 자체 인증서 서명 기관 역할을 하도록 시스템을 설정해야 합니다.

시작하려면 ~/docker-registry/nginx 폴더로 변경하고 인증서를 만들 준비를 합니다.

  1. cd ~/docker-registry/nginx

새 루트 키를 생성합니다.

  1. openssl genrsa -out devdockerCA.key 2048

루트 인증서를 생성합니다(프롬프트에 원하는 대로 입력).

  1. openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt

그런 다음 서버용 키를 생성합니다(Nginx 구성의 ssl_certificate_key에서 참조하는 파일임).

  1. openssl genrsa -out domain.key 2048

이제 인증서 서명 요청을 해야 합니다.

이 명령을 입력하면 OpenSSL이 몇 가지 질문에 답하라는 메시지를 표시합니다. 처음 몇 개는 원하는 대로 작성하되 OpenSSL에서 "일반 이름\을 입력하라는 메시지가 표시되면 서버의 도메인이나 IP를 입력해야 합니다.

  1. openssl req -new -key domain.key -out dev-docker-registry.com.csr

예를 들어 Docker 레지스트리가 도메인 www.ilovedocker.com에서 실행될 경우 입력 내용은 다음과 같아야 합니다.

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.ilovedocker.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

챌린지 암호를 입력하지 마십시오.

다음으로 인증서 요청에 서명해야 합니다.

  1. openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000

방금 생성한 인증서는 알려진 인증 기관(예: VeriSign)에서 확인하지 않았기 때문에 이 Docker 레지스트리를 사용할 모든 클라이언트에게 이것이 합법적인 인증서임을 알려야 합니다. Docker 레지스트리 서버 자체에서 Docker를 사용할 수 있도록 호스트 시스템에서 로컬로 이 작업을 수행해 보겠습니다.

  1. sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
  2. sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
  3. sudo update-ca-certificates

인증서 저장소에 대한 변경 사항을 선택하도록 Docker 데몬을 다시 시작합니다.

  1. sudo service docker restart

경고: 이 Docker 레지스트리에 연결하는 모든 머신에 대해 이 단계를 반복해야 합니다! Ubuntu 14.04 클라이언트에 대해 이 작업을 수행하는 방법에 대한 지침은 9단계 — 클라이언트 시스템에서 Docker 레지스트리 액세스에 나열되어 있습니다.

6단계 - SSL 테스트

이제 친숙한 docker-compose up을 통해 Docker 컨테이너를 불러옵니다.

  1. cd ~/docker-registry
  2. docker-compose up

다른 터미널에서 다른 curl 테스트를 수행하여(이번에는 https만 사용) SSL 설정이 제대로 작동하는지 확인합니다. SSL이 제대로 작동하려면 이전에 SSL 인증서를 만드는 동안 일반 이름 입력란에 입력한 것과 동일한 도메인 이름을 사용해야 합니다.

  1. curl https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

참고: 자체 서명된 인증서를 사용하는 경우 curl에서 다음 오류가 표시됩니다.

curl: (60) SSL certificate problem: self signed certificate

-k 옵션을 사용하여 curl에게 피어와 확인하지 않도록 지시하십시오.

  1. curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

예를 들어 설정한 사용자 및 비밀번호가 sammytest이고 SSL 인증서가 www.example.com용인 경우 다음을 입력합니다.

  1. curl https://sammy:test@www.example.com:5043/v2/

모든 것이 잘 되었다면 curl은 빈 json 객체 {}를 인쇄하고 docker-compose 터미널은 일반적인 registry_<를 인쇄합니다. /코드> 출력.

그렇지 않은 경우 SSL 단계와 Nginx 구성 파일을 다시 확인하여 모든 것이 올바른지 확인하십시오.

이 시점에서 SSL을 통해 인증 및 암호화를 제공하는 Nginx 서버 뒤에서 작동하는 Docker 레지스트리 2.0이 실행되고 있습니다. 방화벽이 외부에서 포트 5043에 대한 액세스를 허용하도록 구성된 경우 모든 머신 docker login https:// 에서 이 Docker 레지스트리에 로그인할 수 있어야 합니다. 이전 섹션에서 설정한 사용자 이름과 암호를 입력합니다.

7단계 - SSL 포트를 443으로 설정

완료하기 전에 몇 가지 단계만 더 수행하면 됩니다. 표준 SSL 포트인 443(선택 사항)을 사용하도록 포트를 변경하고 docker-compose를 설정하여 이 작업을 시작하세요. 시작 시 컨테이너 세트.

지금까지 사용했던 비표준 포트 5043이 아닌 포트 443(SSL의 표준 포트)에서 수신 대기하도록 Docker화된 Nginx 컨테이너를 설정하는 것으로 시작하겠습니다. 1024 미만의 포트는 Linux에서 "권한 있는\ 포트이므로 docker-compose 컨테이너를 루트로 실행해야 합니다.

먼저 텍스트 편집기에서 docker-compose.yml을 엽니다.

  1. nano ~/docker-registry/docker-compose.yml

Nginx 섹션 아래에 ports: 섹션이 표시되고 - 5043:443 줄을 변경합니다(이는 호스트 시스템의 포트 5043을 Nginx 컨테이너 내부의 포트 443에 매핑합니다). )를 - 443:443로 변경하여 Nginx 컨테이너의 포트 443이 호스트 시스템의 포트 443에 매핑되도록 합니다. 완료되면 docker-compose.yml은 다음과 같아야 합니다.

nginx:
  image: "nginx:1.9"
  ports:
    - 443:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

여전히 실행 중인 경우 CTRL-C를 통해 docker-compose 세션을 종료하고 포트 443에서 다시 시작합니다.

  1. sudo docker-compose up

참고: 루트 사용자만 1024 미만의 포트를 수신할 수 있습니다. Nginx가 기본 SSL 포트에서 실행될 수 있도록 이번에는 docker-compose 명령과 함께 sudo를 사용해야 합니다. 443.

평소처럼 docker-compose가 시작되는 것을 볼 수 있습니다.

도메인 이름을 사용하여 다른 curl 테스트를 시도해 보겠습니다. 이번에는 URL에 :5043을 지정하지 않습니다.

  1. curl https://<YOURUSERNAME>:<YOURPASSWORD>@YOUR-DOMAIN/v2/

모든 것이 잘 되었다면 docker-compose 터미널에 일반적인 registry_ 출력이 표시되어야 합니다. 다른 시스템에서 이와 동일한 curl 명령을 실행하여 포트 443이 외부 세계에 노출되고 있는지 확인할 수도 있습니다.

다음 단계로 이동하기 전에 docker-compose 터미널에서 CTRL-C를 사용하여 Docker 컨테이너를 종료하세요.

8단계 — Docker Registry as a Service 시작

모든 것이 좋아 보인다면 시스템이 부팅될 때마다 Docker 레지스트리가 시작되도록 Upstart 스크립트를 만들어 보겠습니다.

먼저 기존 컨테이너를 제거하고 Docker 레지스트리를 시스템 전체 위치로 이동하고 해당 권한을 루트로 변경합니다.

  1. cd ~/docker-registry
  2. docker-compose rm # this removes the existing containers
  3. sudo mv ~/docker-registry /docker-registry
  4. sudo chown -R root: /docker-registry

그런 다음 좋아하는 텍스트 편집기를 사용하여 Upstart 스크립트를 만듭니다.

  1. sudo nano /etc/init/docker-registry.conf

다음 콘텐츠를 추가하여 Upstart 스크립트를 생성합니다(Upstart가 Docker 컨테이너를 제대로 모니터링하도록 하는 것은 약간 까다롭습니다. 이 Upstart 스크립트가 수행하는 작업에 대한 자세한 내용은 이 블로그 게시물을 확인하십시오).

description "Docker Registry"

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 10 5

chdir /docker-registry

exec /usr/local/bin/docker-compose up

Upstart 스크립트에 대한 자세한 내용은 이 가이드를 읽어보세요.

다음을 실행하여 새로운 Upstart 스크립트를 테스트해 보겠습니다.

  1. sudo service docker-registry start

다음과 같은 내용이 표시되어야 합니다.

docker-registry start/running, process 25303

다음을 실행하여 서버가 실행 중인지 확인할 수 있습니다.

  1. docker ps

출력은 다음과 유사해야 합니다(이름은 모두 dockerregistry_로 시작합니다.

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                          NAMES
d4b6fef0b4d1        nginx:1.9           "nginx -g 'daemon of   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:443->443/tcp   dockerregistry_nginx_1
77668352bd39        registry:2          "registry cmd/regist   2 minutes ago       Up 2 minutes        127.0.0.1:5000->5000/tcp       dockerregistry_registry_1

Upstart는 docker-compose 명령의 출력을 /var/log/upstart/docker-registry.log에 기록합니다. 최종 테스트를 위해 tail이 있는 로그 파일을 "live-watch\해 보겠습니다(upstart 로그는 루트 사용자로 작성되기 때문에 sudo가 필요함).

  1. sudo tail -f /var/log/upstart/docker-registry.log

일반적인 registry_ 출력이 표시되어야 합니다. 다른 터미널이나 컴퓨터에서 이제 친숙한 curl 테스트를 실행하십시오.

  1. curl https://<YOUR_USERNAME>:<YOURPASSWORD>@[YOUR-DOMAIN]/v2/

모든 것이 올바르게 작동하면 curl이 터미널에 {}를 인쇄하고 평소와 같이 표시되어야 합니다.

registry_1 | time="2015-08-12T08:01:12.241887501Z" level=debug msg="authorizing request" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | time="2015-08-12T08:01:12.242206499Z" level=info msg="response completed" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" http.response.contenttype="application/json; charset=utf-8" http.response.duration=3.359883ms http.response.status=200 http.response.written=2 instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | 172.17.0.4 - - [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.37.1"
nginx_1    | 106.1.247.4 - nik [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.37.1" "-"

9단계 - 클라이언트 시스템에서 Docker 레지스트리에 액세스

다른 시스템에서 Docker 레지스트리에 액세스하려면 먼저 이전에 생성한 SSL 인증서를 새 클라이언트 시스템에 추가하십시오. 원하는 파일은 ~/docker-registry/nginx/devdockerCA.crt에 있습니다.

새 컴퓨터에 직접 복사하거나 아래 지침을 사용하여 복사하여 붙여넣을 수 있습니다.

레지스트리 서버에서 인증서를 봅니다.

  1. sudo cat /docker-registry/nginx/devdockerCA.crt

다음과 같은 출력이 표시됩니다.

Output of sudo cat /docker-registry/nginx/devdockerCA.crt
-----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwOTIxMDYwODE2WhcNNDIwMjA2MDYwODE2WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAuK4kNFaY3k/0RdKRK1XLj9+IrpR7WW5lrNaFB0OIiItHV9FjyuSWK2mj ObR1IWJNrVSqWvfZ/CLGay6Lp9DJvBbpT68dhuS5xbVw3bs3ghB24TntDYhHMAc8 GWor/ZQTzjccHUd1SJxt5mGXalNHUharkLd8mv4fAb7Mh/7AFP32W4X+scPE2bVH OJ1qH8ACo7pSVl1Ohcri6sMp01GoELyykpXu5azhuCnfXLRyuOvQb7llV5WyKhq+ SjcE3c2C+hCCC5g6IzRcMEg336Ktn5su+kK6c0hoD0PR/W0PtwgH4XlNdpVFqMST vthEG+Hv6xVGGH+nTszN7F9ugVMxewIDAQABo1AwTjAdBgNVHQ4EFgQULek+WVyK dJk3JIHoI4iVi0FPtdwwHwYDVR0jBBgwFoAULek+WVyKdJk3JIHoI4iVi0FPtdww DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkignESZcgr4dBmVZqDwh YsrKeWSkj+5p9eW5hCHJ5Eg2X8oGTgItuLaLfyFWPS3MYWWMzggxgKMOQM+9o3+k oH5sUmraNzI3TmAtkqd/8isXzBUV661BbSV0obAgF/ul5v3Tl5uBbCXObC+NUikM O0C3fDmmeK799AM/hP5CTDehNaFXABGoVRMSlGYe8hZqap/Jm6AaKThV4g6n4F7M u5wYtI9YDMsxeVW6OP9ZfvpGZW/n/88MSFjMlBjFfFsorfRd6P5WADhdfA6CBECG LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H 6g== -----END CERTIFICATE-----

해당 출력을 클립보드에 복사하고 클라이언트 시스템에 연결합니다.

클라이언트 시스템에서 다음과 같이 인증서 디렉터리를 만듭니다.

  1. sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert

편집할 인증서 파일을 엽니다.

  1. sudo nano /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

인증서 내용을 붙여넣습니다.

파일을 확인하여 파일이 클라이언트 시스템에 올바르게 저장되었는지 확인합니다.

  1. cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

모든 것이 제대로 작동하면 이전과 동일한 텍스트가 표시됩니다.

Output of cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt
-----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV ... ... LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H 6g== -----END CERTIFICATE-----

이제 인증서를 업데이트합니다.

  1. sudo update-ca-certificates

다음과 같은 출력이 표시되어야 합니다(1 추가됨 참고).

Output of sudo update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d....done.

아직 클라이언트에 Docker가 설치되어 있지 않은 경우 지금 설치하십시오(전제 조건 섹션 참조).

Docker를 다시 시작하여 시스템의 CA 인증서를 다시 로드하는지 확인하십시오.

  1. sudo service docker restart

이제 클라이언트 머신에서 Docker 레지스트리에 로그인할 수 있습니다.

  1. docker login https://YOUR-DOMAIN

현재 https://를 사용 중입니다. 이전에 설정한 사용자 이름과 비밀번호를 입력합니다(메시지가 표시되면 이메일에 원하는 내용 입력).

Output of docker login
Username: USERNAME Password: PASSWORD Email: Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

다음 메시지가 표시되어야 합니다.

Output of docker login
Login Succeeded

이 시점에서 Docker 레지스트리가 실행 중입니다! 레지스트리에 푸시할 테스트 이미지를 만들어 봅시다.

10단계 - 개인 Docker 레지스트리에 게시

이제 프라이빗 Docker 레지스트리에 이미지를 게시할 준비가 되었지만 먼저 이미지를 생성해야 합니다. Docker Hub의 ubuntu 이미지를 기반으로 간단한 이미지를 생성합니다.

클라이언트 시스템에서 새 레지스트리에 푸시할 작은 빈 이미지를 만듭니다.

  1. docker run -t -i ubuntu /bin/bash

다운로드가 완료되면 Docker 프롬프트 안에 있게 됩니다. SUCCESS라는 파일을 만들어 파일 시스템을 빠르게 변경해 보겠습니다.

  1. touch /SUCCESS

Docker 컨테이너를 종료합니다.

  1. exit

변경 사항을 커밋합니다.

  1. docker commit $(docker ps -lq) test-image

이 명령은 이미 실행 중인 이미지와 변경 사항을 기반으로 test-image라는 새 이미지를 만듭니다. 이 경우 /SUCCESS 파일 추가가 새 이미지에 포함됩니다.

이 이미지는 현재 로컬에만 존재하므로 생성한 새 레지스트리로 푸시하겠습니다.

이전 단계에서 개인 Docker 레지스트리에 로그인했습니다. 아직 로그인하지 않은 경우 다시 로그인해 보겠습니다(https:// 사용).

  1. docker login https://YOUR-DOMAIN

이전에 설정한 사용자 이름과 비밀번호를 입력합니다.

Username: USERNAME
Password: PASSWORD
Email: 
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

Docker에는 푸시할 레지스트리를 지정하는 특이한 메커니즘이 있습니다. 푸시하려면 개인 레지스트리 위치로 이미지에 태그를 지정해야 합니다. 이미지를 개인 레지스트리에 태그를 지정해 보겠습니다.

  1. docker tag test-image [YOUR-DOMAIN]/test-image

먼저 이미지의 로컬 이름을 사용한 다음 이미지에 추가하려는 태그를 사용하고 있습니다. 태그는 https://를 사용하지 않고 도메인, 포트, 이미지 이름만 사용합니다.

이제 해당 이미지를 레지스트리에 푸시할 수 있습니다. 이번에는 태그 이름만 사용합니다.

  1. docker push [YOUR-DOMAIN]/test-image

레지스트리 서버에 업로드하는 데 약간의 시간이 걸립니다. 다음과 유사한 내용으로 끝나는 출력이 표시되어야 합니다.

Output of docker push
latest: digest: sha256:5ea1cfb425544011a3198757f9c6b283fa209a928caabe56063f85f3402363b4 size: 8008

11단계 - Docker 레지스트리에서 가져오기

모든 것이 제대로 작동하는지 확인하기 위해 원래 서버(Docker 레지스트리를 설치한 위치)로 돌아가 방금 클라이언트에서 푸시한 이미지를 가져옵니다. 세 번째 서버에서 이를 테스트할 수도 있습니다.

테스트 풀 서버에 Docker가 설치되어 있지 않으면 돌아가서 6단계의 설치 지침(세 번째 서버인 경우 SSL 지침)을 따릅니다.

이전에 설정한 사용자 이름과 비밀번호로 로그인합니다.

  1. docker login https://[YOUR-DOMAIN]

이제 이미지를 당깁니다. 도메인 이름, 포트 및 이미지 이름이 포함된 "tag\ 이미지 이름만 필요합니다(https:// 제외).

  1. docker pull [YOUR-DOMAIN]/test-image

Docker는 일부 다운로드를 수행하고 프롬프트로 돌아갑니다. 새 컴퓨터에서 이미지를 실행하면 이전에 생성한 SUCCESS 파일이 있음을 알 수 있습니다.

  1. docker run -t -i [YOUR-DOMAIN]/test-image /bin/bash

bash 셸 내부에 파일을 나열합니다.

  1. ls

이전에 이 이미지에 대해 만든 SUCCESS 파일이 표시되어야 합니다.

SUCCESS  bin  boot  dev  etc  home  lib  lib64  media   mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

결론

축하해요! 개인 Docker 레지스트리를 사용하여 첫 번째 Docker 컨테이너를 푸시 및 풀했습니다!

행복한 도커링!