Jusene's Blog

Docker镜像仓库

字数统计: 2.4k阅读时长: 13 min
2017/09/03 Share

Docker仓库

Docker镜像仓库简单来说就是用来存储自己制作的docker镜像,这docker镜像仓库我称为docker-registry,Docker官方给我们提供了公共仓库(Docker Hub)和私有仓库(Docker registry),想要使用Docker Hub我们只需要在Docker Hub上注册自己的docker仓库即可,而Docker registry则需要我们自己来搭建仓库。

Docker仓库的组件:

  • registry:保存docker镜像及镜像层次结构和元数据
  • repository:由具有某个功能的镜像的所有相关版本构成的集合
  • index:管理用户的账号、访问权限、镜像及镜像标签等等相关的
  • graph:从registry中下载的docker镜像需要保存在本地,此功能即由graph完成

Docker-registry分为1和2版本,1版本是有Python语言写的,而现在的registry2版本即docker distribution更加安全和快速,并且使用go语言编写,docker1.6后的版本不再支持registry1。

Docker Hub

我们想要使用docker hub就需要我们在docker hub上建立自己的repository,下面演示下这么上传自己制作的docker镜像:

  1. 首先登陆docker hub

    1
    ~]# docker login
    2
    Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
    3
    Username: jusene
    4
    Password: 
    5
    Login Succeeded
  2. 接下来我们去网页docker hub上创建自己的repository

  3. 我们重新打标签给需要上传给docker hub的镜像

    1
    ~]# docker tag httpd:v0 docker.io/jusene/test
    2
    ~]# docker images
    3
    REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
    4
    docker.io/jusene/test   latest              09e7250f1e0e        15 hours ago        225.2 MB
    5
    httpd                   v0                  09e7250f1e0e        15 hours ago        225.2 MB
  4. docker push到docker hub

    1
    ~]# docker push docker.io/jusene/test
    2
    The push refers to a repository [docker.io/jusene/test]
    3
    5af69ca6ca17: Pushed 
    4
    latest: digest: sha256:e4b1a4315eab841e7930f96a07bd843be48534c930515c3fed62ba3fd2693257 size: 528
  5. 登陆网页docker hub查看下docker repository的信息

Docker registory

基于容器安装运行

基于容器运行十分简单,只需要一条命令:

1
~]# docker run -d -p 5000:5000 --restart=always -v /data/registry/conf/config.yml:/etc/docker/registry/config.yml -v /data/registry/data:/var/lib/registry --name registry registry

本地安装运行

1
~]# yum install -y docker-distribution
2
~]# vim /etc/docker-distribution/registry/config.yml
3
version: 0.1
4
log:
5
  fields:
6
    service: registry
7
storage:
8
    cache:
9
        layerinfo: inmemory
10
    filesystem:
11
        rootdirectory: /var/lib/registry
12
http:
13
    addr: :5000

这是默认配置,相信配置文件是没什么难度。

1
~]# docker tag httpd:v1 10.211.55.43:5000/httpd
2
The push refers to a repository [10.211.55.43:5000/httpd]
3
Get https://10.211.55.43:5000/v1/_ping: http: server gave HTTP response to HTTPS client
4
这个原因是docker客户端使用了https协议来上传docker 镜像,而docker registry采用了http的协议来解释客户端协议。

解决方案:

1
客户端
2
~]# vim /etc/sysconfig/docker
3
...
4
INSECURE_REGISTRY='--insecure-registry 10.211.55.43:5000'
5
...
6
~]# systemctl restart docker
7
~]# docker push 10.211.55.43:5000/httpd                
8
The push refers to a repository [10.211.55.43:5000/httpd]
9
5af69ca6ca17: Pushed 
10
latest: digest: sha256:e4b1a4315eab841e7930f96a07bd843be48534c930515c3fed62ba3fd2693257 size: 528

查看下:

1
~]# curl  10.211.55.43:5000/v2/_catalog
2
{"repositories":["httpd"]}
3
~]# curl  10.211.55.43:5000/v2/httpd/tags/list
4
{"name":"httpd","tags":["latest"]}
5
6
~]# docker pull 10.211.55.43:5000/httpd
7
Using default tag: latest
8
Trying to pull repository 10.211.55.43:5000/httpd ... 
9
latest: Pulling from 10.211.55.43:5000/httpd
10
Digest: sha256:e4b1a4315eab841e7930f96a07bd843be48534c930515c3fed62ba3fd2693257

这样的仓库基本可以使用了。

如果我门不希望使用http来制作仓库,那么就需要自己制作证书来使用https:

生成私有ca:

1
[root@node2 ~]# (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
2
Generating RSA private key, 4096 bit long modulus
3
.........................................................................................................++
4
........................................................................................++
5
e is 65537 (0x10001)
6
[root@node2 ~]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3655
7
You are about to be asked to enter information that will be incorporated
8
into your certificate request.
9
What you are about to enter is what is called a Distinguished Name or a DN.
10
There are quite a few fields but you can leave some blank
11
For some fields there will be a default value,
12
If you enter '.', the field will be left blank.
13
-----
14
Country Name (2 letter code) [XX]:CN       
15
State or Province Name (full name) []:ZJ
16
Locality Name (eg, city) [Default City]:HZ
17
Organization Name (eg, company) [Default Company Ltd]:JU
18
Organizational Unit Name (eg, section) []:TE
19
Common Name (eg, your name or your server's hostname) []:ca.jusene.com     
20
Email Address []:ca@1234.com
21
[root@node2 ~]# mkdir /etc/pki/CA/{certs,crl,newcerts}
22
mkdir: cannot create directory ‘/etc/pki/CA/certs’: File exists
23
mkdir: cannot create directory ‘/etc/pki/CA/crl’: File exists
24
mkdir: cannot create directory ‘/etc/pki/CA/newcerts’: File exists
25
[root@node2 ~]# touch /etc/pki/CA/{serial,index.txt}
26
[root@node2 ~]# echo 01 > /etc/pki/CA/serial

生产证书并请求签署证书:

1
[root@node2 ssl]# (umask 077;openssl genrsa -out docker.key 2048)
2
Generating RSA private key, 2048 bit long modulus
3
............+++
4
........................+++
5
e is 65537 (0x10001)
6
[root@node2 ssl]# openssl req -new -key docker.key -out docker.csr -days 365
7
You are about to be asked to enter information that will be incorporated
8
into your certificate request.
9
What you are about to enter is what is called a Distinguished Name or a DN.
10
There are quite a few fields but you can leave some blank
11
For some fields there will be a default value,
12
If you enter '.', the field will be left blank.
13
-----
14
Country Name (2 letter code) [XX]:CN
15
State or Province Name (full name) []:ZJ
16
Locality Name (eg, city) [Default City]:HZ
17
Organization Name (eg, company) [Default Company Ltd]:JU
18
Organizational Unit Name (eg, section) []:TE
19
Common Name (eg, your name or your server's hostname) []:docker.jusene.com
20
Email Address []:docker@1234.com
21
22
Please enter the following 'extra' attributes
23
to be sent with your certificate request
24
  challenge password []:
25
▽n optional company name []:
26
[root@node2 ssl]# openssl ca -in docker.csr -out docker.crt -days 365
27
Using configuration from /etc/pki/tls/openssl.cnf
28
Check that the request matches the signature
29
Signature ok
30
Certificate Details:
31
        Serial Number: 1 (0x1)
32
        Validity
33
            Not Before: Aug  6 00:10:43 2017 GMT
34
            Not After : Aug  6 00:10:43 2018 GMT
35
        Subject:
36
            countryName               = CN
37
            stateOrProvinceName       = ZJ
38
            organizationName          = JU
39
            organizationalUnitName    = TE
40
            commonName                = docker.jusene.com
41
            emailAddress              = docker@1234.com
42
        X509v3 extensions:
43
            X509v3 Basic Constraints: 
44
                CA:FALSE
45
            Netscape Comment: 
46
                OpenSSL Generated Certificate
47
            X509v3 Subject Key Identifier: 
48
                68:93:09:8A:21:AD:44:38:3E:2E:AA:95:45:26:AA:3B:F8:0D:BF:7D
49
            X509v3 Authority Key Identifier: 
50
                keyid:B4:5E:B1:F9:B0:6D:78:53:90:1B:FB:CB:BF:D1:2E:8A:FB:82:58:EC
51
52
Certificate is to be certified until Aug  6 00:10:43 2018 GMT (365 days)
53
Sign the certificate? [y/n]:y
54
55
56
1 out of 1 certificate requests certified, commit? [y/n]y
57
Write out database with 1 new entries
58
Data Base Updated

修改配置:

1
~]# vim /etc/docker-distribution/registry/config.yml 
2
version: 0.1
3
log:
4
  fields:
5
    service: registry
6
storage:
7
    cache:
8
        layerinfo: inmemory
9
    filesystem:
10
        rootdirectory: /var/lib/registry
11
http:
12
    addr: :5000
13
    tls:
14
          certificate: /tmp/ssl/docker.crt
15
          key: /tmp/ssl/docker.key
16
~]# systemctl restart docker-distribution

将ca的证书安装在docker client上

1
~]# scp cacert.pem 10.211.55.6:/root
1
~]# mkdir /etc/docker/certs.d/docker.jusene.com:5000
2
~]# mv cacert.pem /etc/docker/certs.d/docker.jusene.com:5000/ca.crt
3
~]# systemctl restart docker
4
~]# docker tag busybox docker.jusene.com:5000/busybox/v1
5
~]# docker push docker.jusene.com:5000/busybox/v1       
6
The push refers to a repository [docker.jusene.com:5000/busybox/v1]
7
6a749002dd6a: Pushed 
8
latest: digest: sha256:b82b5740006c1ab823596d2c07f081084ecdb32fd258072707b99f52a3cb8692 size: 527

容器配置证书:

1
~]# docker run -d -p 5000:5000 --restart=always 
2
       -v /data/registry/conf/config.yml:/etc/docker/registry/config.yml \
3
       -v /data/registry/data:/var/lib/registry \
4
       -v `pwd`/certs:/certs \
5
       -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/docker.crt \
6
       -e REGISTRY_HTTP_TLS_KEY=/certs/docker.key \
7
       --name registry registry

管理访问权限

docker-distribution本身并没有实现认证访问的功能,但是我们可以使用nginx的反向代理实现:

1
~]# vim /etc/nginx/nginx.conf
2
upstream docker-registry {
3
    server localhost:5000;
4
5
}
6
server {
7
    listen 15000 ssl;
8
    server_name docker.jusene.com;
9
10
    ssl on;
11
    ssl_certificate /tmp/ssl/docker.crt;
12
    ssl_certificate_key /tmp/ssl/docker.key;
13
    
14
    client_max_body_size 0;    #disable any limits to avoid HTTP 413 for large image uploads
15
    chunked_transfer_encoding on;  #requied to avoid HTTP 411
16
17
    location /v2/ {
18
    auth_basic "Docker Registry Auth";
19
    auth_basic_user_file /tmp/.htpasswd;
20
    add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
21
    proxy_pass http://docker-registry;
22
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
23
    proxy_redirect off;
24
    proxy_buffering off;
25
    proxy_set_header        Host            $host;
26
    proxy_set_header        X-Real-IP       $remote_addr;
27
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
28
    }
29
    
30
}
31
~]# htpasswd -c -m /tmp/.htpasswd zgx
32
New password: 
33
Re-type new password: 
34
Adding password for user zgx
35
36
37
#测试
38
~]# docker login docker.jusene.me:15000
39
Username: zgx
40
Password: 
41
Login Succeeded
42
~]# docker push docker.jusene.me:15000/alpine
43
The push refers to a repository [docker.jusene.me:15000/alpine]
44
2aebd096e0e2: Layer already exists 
45
latest: digest: sha256:4b8ffaaa896d40622ac10dc6662204f429f1c8c5714be62a6493a7895f664098 size: 528

配置registry

以下是一份详细的docker-distribution配置文件示例:

1
version: 0.1
2
log:
3
    level: debug                              #日志级别
4
    formatter: text                           #日志输出格式,包括text,json,logstash等                                       
5
    fields:                                   #增加到日志输出的键值对,可以用来过滤日志
6
        service: registry
7
        environment: development
8
hooks:                                        #钩子,当仓库发生异常通过邮件发送
9
    - type: mail
10
        disable: true
11
        levels:
12
            - panic
13
        options:
14
            smtp:
15
                addr: mail.example.com:25
16
                username: mailuser
17
                password: password
18
                insecure: true
19
            from: sender@example.com
20
            to:
21
                - errors@example.com
22
storage:                                       #存储选项,默认为本地文件系统
23
    delete:                                    #是否开启允许删除镜像功能,默认关闭
24
        enabled: true
25
    cache:                                     #开启对镜像层元数据的缓存功能,默认开启
26
        layerinfo: inmemory 
27
        blobdescriptor: redis                  #缓存文件块
28
    filesystem:
29
        rootdirectory: /var/lib/registry
30
    maintenance:                               #配置维护相关的功能,包括对孤立旧文件的清理
31
        uploadpurging:
32
            enabled: enable
33
            age: 168h
34
            interval: 24h
35
            dryrun: false
36
37
http:
38
    addr: 5000
39
    secret: admin                                # 必选项,跟安全相关的随机字符串
40
    debug:
41
        addr: localhost:5001
42
    headers:
43
        X-Content-Type-Options: [nosniff]
44
    tls:                                          #证书路径相关
45
        certificate: /path/to/crt
46
        key: /path/to/key
47
    http2:                                        #http2是否开启
48
        disabled: false              
49
redis:                                            #缓存文件块
50
    addr: localhost:6379
51
    password: password
52
    db: 0
53
    pool:
54
        maxidle: 16
55
        maxactive: 64
56
        idletimeout: 300s
57
    dialtimeout: 10ms
58
    readtimeout: 10ms
59
    writetimeout: 10ms
60
notifications:                                     # 事件的通知机制
61
    endpoints:
62
        - name: local-5003
63
            url: http://localhost:5003/callback
64
            headers:
65
                Authorization: [Bearer <an example token>]
66
            timeout: 1s
67
            threshold: 10
68
            backoff: 1s
69
            disabled: true
70
        - name: local-8083
71
            url: http://localhost:8083/callback
72
            timeout: 1s
73
            threshold: 10
74
            backoff: 1s
75
            disabled: true
76
health:                                               # 健康状态监控
77
    storagedriver:
78
        enabled: true
79
        interval: 10s
80
        threshold: 3
81
    file:
82
        - file: /path/to/check/file
83
            interval: 10s
84
    http:
85
        - uri: http://server.to.check/must/return/200
86
            headers:
87
                Authorization: [Basic password]
88
            statuscode: 200
89
            timeout: 3s
90
            interval: 10s
91
            threshold: 3
92
    tcp:
93
        - addr: localhost:6379
94
            timeout: 3s
95
            interval: 10s
96
            threshold: 3
97
proxy:                                               #pull时的代理设置
98
    remoteurl: https://registry-1.docker.io
99
    username: [username]
100
    password: [password]                             #docker --registry-mirror=https://myrepo.com:5000 daemon
101
102
validation:                                          #限定指定的url地址才可以push
103
    enabled: true
104
    manifests;
105
        urls:
106
            allow:
107
                - ^https?://([^/]+\.)*example\.com
108
            deny:
109
                - ^https?://www\.example\.com

参考资料:http://www.cnblogs.com/xcloudbiz/articles/5526262.html

CATALOG
  1. 1. Docker仓库
  2. 2. Docker Hub
  3. 3. Docker registory
    1. 3.1. 基于容器安装运行
    2. 3.2. 本地安装运行
    3. 3.3. 管理访问权限
    4. 3.4. 配置registry