Total Pageviews

Monday 6 August 2018

搭建自己的Docker Registry仓库


本文实验的环境

  • 本地端为自己的Mac笔记本电脑
  • 云端为Ubuntu Server 14.04
  • 本地与云端都需要安装Docker,按照官网文档安装:https://docs.docker.com/engine/installation/

在本地制作Docker镜像

本步骤环境为本地Mac。
编写Dockefile,将我们的python api server打包成一个镜像:
1
2
$ cd ~/etc/docker/
$ cat Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
FROM alpine:3.5
 
RUN apk add --no-cache python && \
    python -m ensurepip && \
    rm -r /usr/lib/python*/ensurepip && \
    pip install --upgrade pip setuptools && \
    rm -r /root/.cache && \
    apk add --no-cache vim py-mysqldb musl-dev linux-headers g++ python-dev libxml2-dev \
    libxml2 libxslt libxslt-dev && \
    ln -s /usr/include/locale.h /usr/include/xlocale.h
 
##############
 
COPY VikiQA/requirements.txt /src/
RUN pip install -r /src/requirements.txt
 
COPY VikiQA /src/VikiQA
COPY VikiAIML /src/VikiAIML
RUN cd /usr/lib/python2.7/site-packages && ln -s /src/VikiQA/viki_qa . && \
    cd /src/VikiQA/viki_qa && cp config_sample.py config.py && \
    mkdir /var/log/viki_qa
 
WORKDIR /src/VikiQA/viki_qa/
 
ENTRYPOINT ["/usr/bin/gunicorn", "-k", "tornado", "-b", "0.0.0.0:80", "--workers=4", "viki_qa.wsgi:app"]
然后制作好镜像:
1
2
$ cd ~/etc/docker/
$ docker build -t kyle/viki_qa .
完成后,可以通过命令查看制作好的镜像:
1
2
3
4
$ docker images
kyle@kyledeMacBook-Pro ~/p/a/VikiDocker> docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
kyle/viki_qa                     latest              5cd56c45db67        27 hours ago        347 MB

在云端运行Docker registry

本步骤环境为云端Ubuntu Server。
假设云端服务器地址为 docker.kyle.ai,在上面安装好docker后,运行registry容器,这里我们用docker-compose来运行。
1
2
$ cd ~/etc/docker/
$ cat docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '2'
 
services:
 
    registry:
        image: registry:2
        restart: always
        ports:
          - 5000:5000
        volumes:
          - /home/deploy/data/docker/registry:/var/lib/registry
#          - /home/deploy/etc/docker/cert/:/certs
#          - /home/deploy/etc/docker/auth/:/auth
#        environment:
#          REGISTRY_HTTP_TLS_CERTIFICATE: /certs/214053375670003.pem
#          REGISTRY_HTTP_TLS_KEY: /certs/214053375670003.key
#          REGISTRY_AUTH: htpasswd
#          REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
#          REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
        container_name: registry
解释一下,就是在本地运行registry窗口服务,端口号为5000,并把仓库的文件数据持久化到本地磁盘 /home/deploy/data/docker/registry 。
注释的那些行,是用来配置使用auth认证与ssl证书的,但由于我们使用nginx来做这个事情,所以docker registry服务就不用了。不能nginx与registry同时配置这两个,不然会访问不成功。
然后把容器运行起来
1
2
3
4
5
6
$ cd ~/etc/docker/
$ sudo docker-compose up -d
$ sudo docker-compose ps
  Name                Command               State           Ports         
--------------------------------------------------------------------------
registry   /entrypoint.sh /etc/docker ...   Up      0.0.0.0:5000->5000/tcp
下一步就需要配置nginx,将服务器的80端口转发到registry服务的5000端口,并设置好ssl与auth认证。
nginx配置文件如下:
1
2
$ cd ~/etc/nginx/sites-enabled/
$ cat docker.kyle.ai
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
server {
    listen 80;
    listen 443 ssl;
    ssl_certificate   /etc/nginx/cert/docker.kyle.ai/ssl.pem;
    ssl_certificate_key  /etc/nginx/cert/docker.kyle.ai/ssl.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    add_header X-Frame-Options SAMEORIGIN;
    add_header Strict-Transport-Security "max-age=8640000;";
    add_header X-Content-Type-Options: nosniff;
 
    server_name docker.kyle.ai;
    access_log  /var/log/nginx/docker-access.log;
    error_log  /var/log/nginx/docker-error.log;
 
    root /home/deploy/www/;
    client_max_body_size 0;      # 不限制上传文件的大小,一个镜像可能有几百M
    chunked_transfer_encoding on;
 
    if ($ssl_protocol = "") {
        return 302 https://$server_name$request_uri;
    }
 
    location ^~ / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
    }
 
    upstream docker_registry{
        server 127.0.0.1:5000;
    }
 
    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;
        }
        auth_basic "Registry realm";
        auth_basic_user_file /home/deploy/etc/docker/auth/htpasswd;
        add_header 'Docker-Distribution-Api-Version' 'registry/2.0';
 
        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;
    }
 
}
ssl证书,我是直接在阿里云申请的免费dv证书,申请地址:https://common-buy.aliyun.com/?commodityCode=cas#/buy
申请成功后,相应的配置 ssl_certificate 与 ssl_certificate_key 文件路径。
然后就是basic auth的用户文件:/home/deploy/etc/docker/auth/htpasswd,可以通过如下命令生成:
1
sudo docker run --entrypoint htpasswd registry:2 -bn username password > htpasswd
注意不要添加-B参数,之前我用的 -Bbn 参数,结果后面nginx会出现如下错误:
1
[crit] 12472#0: *29935 crypt_r() failed (22: Invalid argument)
nginx的这个配置,可能跟nginx版本有关系
1
add_header 'Docker-Distribution-Api-Version' 'registry/2.0';
高版本的nginx可能需要在后面添加个 always
1
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
配置好nginx后,就可以通过访问api来测试: curl https://docker.kyle.ai/v2 这样,这里我只是用了示例域名,你需要换成你自己的。

将本地的image push到云端的registry

本步骤是在本地Mac系统环境。
上面的步骤中,我们已经成功地在本地build了一个Image,叫 kyle/viki_qa,现在把这个image映射到云端的registry:
1
$ sudo docker tag kyle/viki_qa docker.kyle.ai/kyle/viki_qa
然后 push 到云端:
1
2
$ sudo docker push docker.kyle.ai/kyle/viki_qa
Error: Status 405 trying to push repository kyle/viki_qa: "<html>\r\n<head><title>405 Not Allowed</title>
报405 Not Allowed的错误, 是由于需要先登陆,还记得我们在上面配置nginx的时候,设置的basic auth的用户与密码,用这个来登陆一下
1
2
$ sudo docker login docker.kyle.ai
输入密码与密码
之后再push就行了。

在其它机器拉取我们的镜像

直接
1
2
$ sudo docker pull docker.kyle.ai/kyle/viki_qa
$ sudo docker run -it --rm -d docker.kyle.ai/kyle/viki_qa

其它

删除远程的image比较麻烦,官方没有提供很好的办法。
目前docker官方提供了如下3个软删除的方法:
  • DELETE:/v2//manifests/:这个API是软删除一个清单(manifest),但是真正占用存储空间的层还在。
  • DELETE:/v2//blobs/:这个API类似上面那个,只不过它要软删除的对象是层(layer)罢了。
  • DELETE:/v2//blobs/uploads/:这个只是取消掉另一个上传的进程罢了

No comments:

Post a Comment