2015년 3월 23일 월요일

Docker 개인저장소 구축

1.  개인저장소 구축

Docker 저장소 서버는 Docker 레지스트리 서버라고 부릅니다. 레지스트리 서버에 이미지를 올리거나 받을 수 있습니다.
먼저 --insecure-registry 옵션을 사용하여 Docker 데몬을 실행합니다.
$ sudo docker -d --insecure-registry localhost:5000
보통 Docker 데몬을 직접 실행하지 않고 서비스 형태로 실행합니다. 이때는 /etc/init.d/docker 파일의 DOCKER_OPTS 부분을 다음과 같이 설정합니다(이 파일은 root 권한으로 수정해야 합니다).
/etc/init.d/docker
DOCKER_OPTS=--insecure-registry localhost:5000
/etc/init.d/docker 파일을 수정했으면 Docker 서비스를 재시작합니다.
$ sudo service docker restart

1.1    로컬 저장소 구축

Docker 레지스트리 서버도 Docker Hub를 통해 Docker 이미지로 제공됩니다. Docker 레지스트리 이미지를 받습니다.
$ sudo docker pull registry:latest
registry:latest 이미지를 컨테이너로 실행합니다.
$ sudo docker run -d -p 5000:5000 --name hello-registry \
    -v /tmp/registry:/tmp/registry \
    registry
이렇게 실행하면 이미지 파일은 호스트의 /tmp/registry 디렉터리에 저장됩니다
앞에서 만든 hello:0.1 이미지를 개인 저장소에 올려보겠습니다.
$ sudo docker tag hello:0.1 localhost:5000/hello:0.1
$ sudo docker push localhost:5000/hello:0.1
docker tag <이미지 이름>:<태그> <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식입니다.
docker push <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식입니다.
먼저 docker tag 명령으로 hello:0.1 이미지를 localhost:5000/hello:0.1 태그로 생성합니다. 그리고 docker push 명령으로localhost:5000/hello:0.1 이미지를 개인 저장소에 올립니다(태그를 생성했으므로 실제로는 hello:0.1 이미지가 올라갑니다).
이제 다른 서버에서 개인 저장소(레지스트리 서버)에 접속하여 이미지를 받아올 수 있습니다. 개인 저장소 서버 IP 주소가 192.168.0.39라면 아래와 같이 명령을 실행합니다.
$ sudo docker pull 192.168.0.39:5000/hello:0.1
이미지 목록을 출력합니다.
$ sudo docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos                    latest              0c752394b855        4 weeks ago         124.1 MB
192.168.0.39:5000/hello   0.1                 2031ee0736e8        4 weeks ago         298.4 MB
개인 저장소에서 192.168.0.39:5000/hello 이미지를 받았습니다.
이미지를 삭제할 때에는 아래와 같이 실행합니다.
$ sudo docker rmi 192.168.0.39:5000/hello:0.1

1.2    DockerHub 사용하기

Docker Hub Docker 공식 이미지를 제공하고, 사용자들끼리 이미지를 공유하는 사이트입니다.

l  공개 저장소(Public Repository): 저장된 이미지를 다른 사람들도 사용할 수 있습니다. 또한, 개수 제한 없이 무료로 생성할 수 있습니다.
l  개인 저장소(Private Repository): 저장된 이미지를 혼자만 사용할 수 있습니다. 1개까지 무료로 생성할 수 있고 그 이상부터는 유료입니다.
l  즐겨 찾기(Starred): 다른 사람의 유용한 저장소를 다음에 사용할 수 있도록 즐겨 찾기에 추가할 수 있습니다.
l  Automated Build: GitHub 또는 BitBucket 저장소와 연동하여 Dockerfile Push했을 때 이미지를 자동으로 빌드하는 기능입니다.

1.2.1     DockerHub 가입

Docker Hub를 사용하려면 먼저 가입을 해야 합니다. 웹 브라우저를 실행하고 https://hub.docker.com에 접속합니다.

ID, 비밀번호, 이메일 주소를 입력한 뒤 Sign up 버튼을 클릭합니다. 만약 GitHub 계정이 있다면 GitHub 계정을 이용하여 바로 가입할 수 있습니다.

1.2.2     DockerHub 이미지 push

이제 Docker Hub 공개 저장소(Public Repository)에 이미지를 올려보겠습니다.

Docker Hub에 이미지를 올리기 전에 로그인부터 합니다. 사용자 계정, 비밀번호, 가입할 때 사용한 이메일 주소를 입력합니다.

docker@docker-ThinkCentre-M82:~/GitTest$ sudo docker login
Username: longbe00
Password:********
Email: longbe00@*******@naver.com
Login Succeeded
이제 docker push 명령으로 이미지를 올립니다.

Docker Hub에 이미지를 올리려면 이미지 이름을 <Docker Hub 사용자 계정>/<이미지 이름>:<태그> 형식으로 생성해야 합니다. 아무 사용자 이름이나 사용할 수 있지만 내 계정 이름과 일치해야 이미지를 올릴 수 있습니다. 태그를 지정하지 않으면 latest가 됩니다.

~/example-nginx$ sudo docker push longbe00/base_image:1.0
docker push <Docker Hub 사용자 계정>/<이미지 이름>:<태그> 형식입니다.

잠시 기다리면 이미지가 Docker Hub의 공개 저장소에 완전히 올라갑니다. Docker Hub 페이지에서 Repositories 메뉴를 클릭하면 방금 올렸던 <Docker Hub 사용자 계정>/example-nginx 이미지가 표시됩니다(Docker Hub에 생성된 공개 저장소가 없다면 이미지를 올렸을 때 공개 저장소가 자동으로 생성됩니다).

1.2.3     DockerHub 개인저장소 생성

docker login 명령으로 Docker Hub에 로그인한 뒤 docker push 명령으로 이미지를 올리면 자동으로 공개 저장소(Public Repository)가 생성됩니다.
이번에는 Docker Hub에서 개인 저장소(Private Repository)를 생성하는 방법입니다.
Docker Hub에 로그인한 뒤 왼쪽 메뉴에서 Repositories를 클릭합니다. 그리고 위쪽 Add Repository Repository를 클릭합니다.
l  Namespace (optional) and Repository Name: 저장소 이름을 입력합니다.
l  Description: 저장소 설명입니다. 입력하지 않아도 상관없습니다.
l  Repository Type: 저장소 형식입니다. 개인 저장소를 생성할 것이므로 Private를 선택합니다.
설정이 완료되었으면 Add Repository 버튼을 클릭합니다.

해당 Repository가 생성되었다면 동일한 방법으로 push를 진행하면 개인저장소에 이미지가 저장됩니다.

1.3    Amazon S3에 이미지 데이터 저장

이번에는 AWS S3에 이미지 데이터를 저장하는 방법입니다.
Docker 레지스트리 이미지를 받습니다.
$ sudo docker pull registry:latest
registry:latest 이미지를 컨테이너로 실행합니다.
$ sudo docker run -d -p 5000:5000 --name s3-registry \
     -e SETTINGS_FLAVOR=s3 \
     -e AWS_BUCKET=examplebucket10 \
     -e STORAGE_PATH=/registry \
     -e AWS_KEY=AKIABCDEFGHIJKLMNOPQ \
     -e AWS_SECRET=sF4321ABCDEFGHIJKLMNOPqrstuvwxyz21345Afc \
     registry
·         SETTINGS_FLAVOR: s3을 설정합니다.
·         AWS_BUCKET: 이미지 데이터를 저장할 S3 버킷 이름을 설정합니다.
·         STORAGE_PATH: 이미지 데이터 저장 경로입니다. /registry를 설정합니다.
·         AWS_KEY: AWS 액세스 키를 설정합니다.
·         AWS_SECRET: AWS 시크릿 키를 설정합니다.
이제 s3-retistry 저장소에 Docker 이미지를 push하면 S3 버킷에 저장됩니다.

1.4    기본 인증 사용하기

Docker 레지스트리에는 로그인 기능이 없습니다. 따라서 Nginx의 기본 인증(Basic Authentication) 기능을 사용해야 합니다. 또한, HTTP 프로토콜에서는 인증을 지원하지 않으므로 반드시 HTTPS 프로토콜을 사용해야 합니다.
먼저 /etc/hosts 파일을 편집하여 테스트용 도메인을 추가합니다. 이 파일은 root 권한으로 수정해야 합니다. 도메인을 구입하지 않았을 때는 이 부분을 반드시 설정해주어야 하며, 도메인 구입하여 DNS를 설정하였다면 이 부분은 건너뛰어도 됩니다.
/etc/hosts
127.0.0.1       localhost
127.0.1.1       ubuntu
<레지스트리 서버 IP 주소>    registry.example.com
 
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
여러분의 레지스트리 서버 IP 주소를 registry.example.com으로 설정합니다. 이 문서에서는 registry.example.com을 기준으로 설명하겠습니다.
이제 SSL 사설 인증서(Self Signed)를 생성하겠습니다. SSL 공인 인증서를 구입하였다면 이 부분은 건너뛰어도 됩니다.
다음 명령을 입력하여 개인 키 파일을 생성합니다.
$ openssl genrsa -out server.key 2048
인증서 서명 요청(Certificate signing request) 파일을 생성합니다.
·         Country Name: 국가 코드입니다. KO를 입력합니다.
·         State or Province Name: 주 또는 도입니다. 자신의 상황에 맞게 입력합니다.
·         Locality Name: 도시입니다. 자신의 상황에 맞게 입력합니다.
·         Organization Name: 회사 이름을 입력합니다.
·         Organizational Unit Name: 조직 이름을 입력합니다.
·         Common Name: Docker 레지스트리를 실행하는 서버의 도메인입니다. 이 부분을 정확하게 입력하지 않으면 인증서를 사용해도 로그인할 때 에러가 발생합니다. /etc/hosts 파일에 설정한대로 registry.example.com를 입력합니다.
·         Email Address: 이메일 주소입니다.
$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KO
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Company
Organizational Unit Name (eg, section) []:Example Company
Common Name (e.g. server FQDN or YOUR name) []:registry.example.com
Email Address []:exampleuser@example.com
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:<아무것도 입력하지 않음>
An optional company name []:<아무것도 입력하지 않음>
서버 인증서 파일을 생성합니다.
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
이제 server.crt 인증서 파일을 시스템에 설치를 해주어야 합니다(인증서 파일을 설치하지 않으려면 --insecure-registry 옵션을 사용해야 합니다. 이 부분은 뒤에 따로 설명하겠습니다).
우분투
$ sudo cp server.crt /usr/share/ca-certificates/
$ echo "server.crt" | sudo tee -a /etc/ca-certificates.conf
$ sudo update-ca-certificates
CentOS
$ sudo cp server.crt /etc/pki/ca-trust/source/anchors/
$ sudo update-ca-trust enable
$ sudo update-ca-trust extract
/etc/hosts에 도메인을 추가하고, 인증서 파일을 설치했으면 Docker 서비스를 재시작합니다. Docker 서비스를 재시작해야 추가된 도메인과 설치된 인증서가 적용됩니다.
$ sudo service docker restart
Docker 레지스트리에 접속할 다른 시스템에도 server.crt 인증서 파일을 복사하여 같은 방식으로 설치를 하고 Docker 서비스를 재시작합니다. 그리고 도메인을 구입하지 않았다면 /etc/hosts에 레지스트리 서버(registry.example.com) IP 주소를 설정합니다.


--insecure-registry 옵션
server.crt
인증서 파일을 시스템에 설치하지 않으려면 Docker 데몬을 실행할 때 --insecure-registry 옵션을 사용해야 합니다.
$ sudo docker -d --insecure-registry registry.example.com
·           --insecure-registry 옵션에 Docker 레지스트리의 도메인을 설정합니다. 도메인 여러 개를 설정하려면 --insecure-registry 옵션을 여러 번 사용하면 됩니다.
보통 Docker 데몬을 직접 실행하지 않고 서비스 형태로 실행합니다. 이때는 /etc/init.d/docker 파일의 DOCKER_OPTS 부분을 다음과 같이 설정합니다(이 파일은 root 권한으로 수정해야 합니다).
/etc/init.d/docker
DOCKER_OPTS=--insecure-registry registry.example.com
/etc/init.d/docker 파일을 수정했으면 Docker 서비스를 재시작합니다.
$ sudo service docker restart
Docker 레지스트리에 접속할 다른 시스템에도 같은 방식으로 --insecure-registry 옵션을 사용하여 Docker 데몬을 실행합니다.


이제 사용자 계정과 비밀번호를 저장할 .htpasswd 파일을 생성해야 합니다. 먼저 다음 패키지를 설치합니다.
우분투
$ sudo apt-get install apache2-utils
CentOS
$ sudo yum install httpd-tools
htpasswd 명령으로 .htpasswd 파일을 생성하고 hellouser라는 예제 사용자를 추가합니다. 비밀번호 입력 부분에는 사용할 비빌번호를 입력합니다.
$ htpasswd -c .htpasswd hellouser
New password:<비밀번호 입력>
Re-type new password:<비밀번호 입력>
Adding password for user hellouser
이번에는 Nginx 이미지를 따로 생성하지 않고 공식 이미지를 그대로 사용하겠습니다. 다음 내용을 nginx.conf 파일로 저장합니다.
nginx.conf
worker_processes  1;
 
events {
    worker_connections  1024;
}
 
http {
    server {
        listen       443;
        server_name  registry.example.com;
 
        ssl on;
        ssl_certificate /etc/server.crt;
        ssl_certificate_key /etc/server.key;
 
        proxy_set_header Host           $http_host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header Authorization  "";
 
        client_max_body_size 0;
 
        chunked_transfer_encoding on;
 
        location / {
            proxy_pass          http://docker-registry:5000;
            proxy_set_header    Host  $host;
            proxy_read_timeout  900;
 
            auth_basic            "Restricted";
            auth_basic_user_file  .htpasswd;
        }
    }
}
·        server_name: Docker 레지스트리 서버의 도메인을 설정합니다. 여기서는 registry.example.com을 설정합니다.
·        ssl_certificate, ssl_certificate_key: /etc/server.crt, /etc/server.key를 설정합니다.
·        proxy_pass: 리버스 프록시 설정입니다. Docker 레지스트리 컨테이너와 포트인 docker-registry:5000을 설정합니다.
·        auth_basic: 인증 설정입니다. "Restricted"를 설정하여 기본 인증을 사용합니다.
·        auth_basic_user_file: 사용자 정보가 저장된 .htpasswd 파일을 설정합니다.


daemon off; 옵션
Nginx
공식 이미지 1.7.5 버전부터는 다음과 같이 Nginx 실행 파일을 실행할 때 옵션에 직접 daemon off;를 설정해줍니다. 따라서 nginx.conf 파일에는 daemon off; 옵션을 넣지 않아도 됩니다.
CMD ["nginx", "-g", "daemon off;"]


다음 명령을 실행하여 Docker 레지스트리 컨테이너를 먼저 생성합니다. 컨테이너의 이름은 nginx.conf 파일에서 설정한 대로 docker-registry로 지정합니다.
$ sudo docker run -d --name docker-registry \
   -v /tmp/registry:/tmp/registry \
   registry:0.8.1
·         Nginx를 통해서 사용자 인증을 하고 이미지를 주고 받을 것이기 때문에 Docker 레지스트리는 5000번 포트를 외부에 노출하지 않습니다.
Nginx 공식 이미지 1.7.5 버전으로 컨테이너를 생성하고 docker-registry 컨테이너와 연결합니다.
$ sudo docker run -d --name nginx-registry \
   -v ~/nginx.conf:/etc/nginx/nginx.conf \
   -v ~/.htpasswd:/etc/nginx/.htpasswd \
   -v ~/server.key:/etc/server.key \
   -v ~/server.crt:/etc/server.crt \
   --link docker-registry:docker-registry \
   -p 443:443 \
   nginx:1.7.5
·         -v 옵션으로 nginx.conf 파일은 컨테이너의 /etc/nginx/nginx.conf로 연결합니다. 마찬가지로 .htpasswd 파일도 /etc/nginx/.htpasswd로 연결합니다. server.key, server.crt 파일은 앞에서 설정한 것처럼 /etc 디렉터리 아래에 연결합니다.
o    저는 사용자 계정 디렉터리에 설정 파일과 인증서 파일을 생성했으므로 ~/nginx.conf 처럼 ~가 붙습니다. 여러분이 생성한 설정 파일과 인증서 파일의 경로를 절대 경로로 지정합니다.
·         --link docker-registry:docker-registry 옵션으로 앞에서 생성한 docker-registry 컨테이너를 docker-registry 별칭으로 연결합니다. 이렇게하면 nginx.conf proxy_pass 설정으로 Docker 레지스트리에 트래픽을 보낼 수 있습니다.
·         -p 443:443 옵션으로 443번 포트를 외부에 노출합니다.
docker login 명령으로 https://registry.example.com에 로그인합니다. Username Password에는 htpasswd 명령으로 생성한 사용자와 비밀번호를 입력합니다. 이메일은 입력하지 않아도 됩니다.
$ docker login https://registry.example.com
Username: hellouser
Password: <비밀번호 입력>
Email:
Login Succeeded
docker login <Docker 레지스트리 URL> 형식입니다.


주의
도메인 설정이 귀찮다고 그냥 건너뛰고 IP 주소만 사용하면 로그인이 안됩니다. 인증서에 설정한 도메인과 docker login 명령에 입력한 도메인이 반드시 일치해야 합니다. HTTPS 프로토콜은 IP 주소 접속을 허용하지 않으므로 구입하지 않은 도메인은 /etc/hosts 파일에 등록하여 사용합니다.


이제 앞에서 만든 hello:0.1 이미지를 개인 저장소에 올려보겠습니다.
$ sudo docker tag hello:0.1 registry.example.com/hello:0.1
$ sudo docker push registry.example.com/hello:0.1
The push refers to a repository [registry.example.com/hello] (len: 1)
Sending image list
Pushing repository registry.example.com/hello (1 tags)
511136ea3c5a: Image successfully pushed
bfb8b5a2ad34: Image successfully pushed
c1f3bdbd8355: Image successfully pushed
897578f527ae: Image successfully pushed
9387bcc9826e: Image successfully pushed
809ed259f845: Image successfully pushed
96864a7d2df3: Image successfully pushed
ba3b051655b4: Image successfully pushed
11ae3a0f7f28: Image successfully pushed
e75f421fc19c: Image successfully pushed
507149de4094: Image successfully pushed
ce11bd8322f9: Image successfully pushed
bb5b14a7e9b8: Image successfully pushed
548b98b8a152: Image successfully pushed
e376f7a8e74c: Image successfully pushed
e2626c81818f: Image successfully pushed
7a06b68da607: Image successfully pushed
Pushing tag for rev [7a06b68da607] on {https://registry.example.com/v1/repositories/hello/tags/0.1}
이미지의 태그는 <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식으로 생성합니다. 우리는 registry.example.com으로 설정했으므로registry.example.com/hello:0.1이 됩니다.
다른 서버에서는 다음 명령을 실행하여 registry.example.com에 저장된 이미지를 받을 수 있습니다.
$ sudo docker pull registry.example.com/hello:0.1


댓글 없음:

댓글 쓰기