Docker仓库实际上提供两方面的功能,一个是镜像管理,一个是认证。前者主要由docker-registry项目来实现,通过http服务来上传下载;后者可以通过docker-index(闭源)项目或者利用现成认证方案(如nginx)实现http请求管理。
一、基本命令:
[root@localhost ~]# docker pull registry
配置启动端口、启动自动化、存储挂载目录mnt/registry
[root@localhost ~]docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
[root@localhost ~]# docker tag centos 192.168.22.153:5000/my-centos
[root@localhost ~]# docker push 192.168.22.153:5000/my-centos
The push refers to a repository [192.168.22.153:5000/centos
Get https://192.168.22.153:5000/v1/_ping: http: server gave HTTP response to HTTPS client
[root@localhost ~]# docker image remove centos:latest
*注意:http: server gave HTTP response to HTTPS client & Get https://192.168.22.153/v2/: dial tcp 192.168. 22.153:443: getsockopt: connection refused
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.22.152:5000
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
在ExecStart=/usr/bin/dockerd后面增加 --insecure-registry ip:5000
修改好后重启docker 服务
systemctl daemon-reload
systemctl restart docker
二、Registry认证方案(Secure Registry HTTPS协议支持)
1、证书制作
[root@localhost ~] mkdir -p cert
[root@localhost ~] openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
2、重启注册:
[root@localhost ~] docker container stop registry
3、Restart the registry, directing it to use the TLS certificate. This command bind-mounts the certs/ directory into the container at /certs/, and sets environment variables that tell the container where to find the domain.crt and domain.key file. The registry runs on port 443, the default HTTPS port.
[root@localhost ~] docker run -d \
--restart=always \
--name registry \
-v `pwd`/registry:/var/lib/registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:2
上述端口没有使用,测试使用下面命令:
[root@localhost ~]docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/registry:/var/lib/registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
4、由于证书的CN是myregistrydomain.com,我们需要修改一下/etc/hosts文件:
vi /etc/hosts #在最后面加入下面内容
192.168.22.152 myregistrydomain.com
三、 Linux 客户端配置与连接
1、本机测试
[root@localhost ~]# docker pull centos
[root@localhost ~]# docker tag centos:latest myregistrydomain.com/my-centos
[root@localhost ~]# docker push myregistrydomain.com/my-centos
The push refers to a repository [myregistrydomain.com/my-centos]
Get https://myregistrydomain.com/v1/_ping: x509: certificate signed by unknown authority
push失败了!从错误日志来看,docker client认为server传输过来的证书的签署方是一个unknown authority(未知的CA),因此验证失败。我们需要让docker client安装我们的CA证书:
[root@localhost ~]# mkdir -p /etc/docker/certs.d/myregistrydomain.com:5000
[root@localhost ~]#cp certs/domain.crt /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
[root@localhost ~]# systemctl restart docker.service
再次上传,出现下列错误
[root@localhost ~]# docker push myregistrydomain.com/my-centos
The push refers to a repository [myregistrydomain.com/my-centos]
Get https://myregistrydomain.com/v1/_ping: dial tcp 192.168.22.152:443: getsockopt: connection refused
原因:没有指定镜像要上传的地址,站点。默认的是docker.io
解决方法:docker tag <imagesname> <ip:port/image>
docker push ip:port/image
[root@localhost ~]# docker tag centos:latest myregistrydomain.com:5000/my-centos
[root@localhost ~]# docker push myregistrydomain.com:5000/my-centos
The push refers to a repository [myregistrydomain.com:5000/my-centos]
34e7b85d83e4: Pushed
latest: digest: sha256:f271819dacd9bc9ea710298054c5beb2ee7ef9b46391aae778c061ed439378b6 size: 529
[root@localhost ~]# docker rmi myregistrydomain.com:5000/my-centos
[root@localhost ~]# docker pull myregistrydomain.com:5000/my-centos
Using default tag: latest
latest: Pulling from my-centos
Digest: sha256:f271819dacd9bc9ea710298054c5beb2ee7ef9b46391aae778c061ed439378b6
Status: Downloaded newer image for myregistrydomain.com:5000/my-centos:latest
2、其他Linux机器测试
[root@localhost ~]# mkdir certs
[root@localhost ~]# scp certs/domain.crt [email protected]:/root/certs
[root@localhost ~]# cp certs/domain.crt /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
[root@localhost ~]# systemctl restart docker.service
需要修改一下/etc/hosts文件:
vi /etc/hosts #在最后面加入下面内容
192.168.22.152 myregistrydomain.com
[root@localhost ~]# docker pull myregistrydomain.com:5000/my-centos #下载
Using default tag: latest
Trying to pull repository myregistrydomain.com:5000/my-centos ...
latest: Pulling from myregistrydomain.com:5000/my-centos
17385548ba54: Pull complete
Digest: sha256:f271819dacd9bc9ea710298054c5beb2ee7ef9b46391aae778c061ed439378b6
Status: Downloaded newer image for myregistrydomain.com:5000/my-centos:latest
[root@localhost ~]# docker tag redis:latest myregistrydomain.com:5000/my-redis
[root@localhost ~]# docker push myregistrydomain.com:5000/my-redis #上传
The push refers to a repository [myregistrydomain.com:5000/my-redis]
685379d1594c: Pushed
21497520b817: Pushed
a3514b4102be: Pushed
714e32c05337: Pushed
d98fb630fb3b: Pushed
8b15606a9e3e: Pushed
latest: digest: sha256:8b5e24dd14cff03e0db8f372e6fd5a9a0f29af771122ef8e94917317db8c39f9 size: 1571
四、Registry的鉴权管理
[root@localhost ~]# mkdir auth
[root@localhost ~]# docker run --entrypoint htpasswd registry:2 -Bbn lb lb123 > auth/htpasswd # 用户名:lb,密码:lb123
[root@localhost ~]# ls auth/
htpasswd
[root@localhost ~]# cat auth/htpasswd
lb:$2y$05$gmpNiFZPj47CaIDb9iDKRevq7cmemIRM6uyRKPEEU74IiCoF/5BaK
[root@localhost ~]# docker run -d -p 5000:5000 --restart=always --name registry \
> -v `pwd`/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> -v `pwd`/registry:/var/lib/registry \
> -v `pwd`/certs:/certs \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
> registry:2
2423da409e42f96207c915a2f0087c0f4edf7f006224c870a26082d6ec4d3619
[root@localhost ~]# docker push myregistrydomain.com:5000/my-centos
The push refers to a repository [myregistrydomain.com:5000/my-centos]
34e7b85d83e4: Preparing
no basic auth credentials
错误信息提示:鉴权失败。
[root@localhost ~]# docker login myregistrydomain.com:5000
Username: lb
Password:
Login Succeeded
再执行push操作,先删除registry目录下的文件,rm -rf registry/*
[root@localhost ~]# docker push myregistrydomain.com:5000/my-centos
The push refers to a repository [myregistrydomain.com:5000/my-centos]
34e7b85d83e4: Pushed
latest: digest: sha256:f271819dacd9bc9ea710298054c5beb2ee7ef9b46391aae778c061ed439378b6 size: 529
在其他机器操作跟上面一致,先登录,后操作。
五、使用配置文件
[root@localhost ~]# mkdir docker-registry
[root@localhost ~]# touch config.yml
[root@localhost ~]# vi config.yml #下面选项,根据需要进行删减,说明参考:https://docs.docker.com/registry/configuration/
version: 0.1
log:
accesslog:
disabled: true
level: debug
formatter: text
fields:
service: registry
environment: staging
hooks:
- type: mail
disabled: true
levels:
- panic
options:
smtp:
addr: mail.example.com:25
username: mailuser
password: password
insecure: true
from: [email protected]
to:
- [email protected]
loglevel: debug # deprecated: use "log"
storage:
filesystem:
rootdirectory: /var/lib/registry
maxthreads: 100
azure:
accountname: accountname
accountkey: base64encodedaccountkey
container: containername
gcs:
bucket: bucketname
keyfile: /path/to/keyfile
rootdirectory: /gcs/object/name/prefix
chunksize: 5242880
s3:
accesskey: awsaccesskey
secretkey: awssecretkey
region: us-west-1
regionendpoint: http://myobjects.local
bucket: bucketname
encrypt: true
keyid: mykeyid
secure: true
v4auth: true
chunksize: 5242880
multipartcopychunksize: 33554432
multipartcopymaxconcurrency: 100
multipartcopythresholdsize: 33554432
rootdirectory: /s3/object/name/prefix
swift:
username: username
password: password
authurl: https://storage.myprovider.com/auth/v1.0 or https://storage.myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth
tenant: tenantname
tenantid: tenantid
domain: domain name for Openstack Identity v3 API
domainid: domain id for Openstack Identity v3 API
insecureskipverify: true
region: fr
container: containername
rootdirectory: /swift/object/name/prefix
oss:
accesskeyid: accesskeyid
accesskeysecret: accesskeysecret
region: OSS region name
endpoint: optional endpoints
internal: optional internal endpoint
bucket: OSS bucket
encrypt: optional data encryption setting
secure: optional ssl setting
chunksize: optional size valye
rootdirectory: optional root directory
inmemory: # This driver takes no parameters
delete:
enabled: false
redirect:
disable: false
cache:
blobdescriptor: redis
maintenance:
uploadpurging:
enabled: true
age: 168h
interval: 24h
dryrun: false
readonly:
enabled: false
auth:
silly:
realm: silly-realm
service: silly-service
token:
realm: token-realm
service: token-service
issuer: registry-token-issuer
rootcertbundle: /root/certs/bundle
htpasswd:
realm: basic-realm
path: /path/to/htpasswd
middleware:
registry:
- name: ARegistryMiddleware
options:
foo: bar
repository:
- name: ARepositoryMiddleware
options:
foo: bar
storage:
- name: cloudfront
options:
baseurl: https://my.cloudfronted.domain.com/
privatekey: /path/to/pem
keypairid: cloudfrontkeypairid
duration: 3000s
storage:
- name: redirect
options:
baseurl: https://example.com/
reporting:
bugsnag:
apikey: bugsnagapikey
releasestage: bugsnagreleasestage
endpoint: bugsnagendpoint
newrelic:
licensekey: newreliclicensekey
name: newrelicname
verbose: true
http:
addr: localhost:5000
prefix: /my/nested/registry/
host: https://myregistryaddress.org:5000
secret: asecretforlocaldevelopment
relativeurls: false
tls:
certificate: /path/to/x509/public
key: /path/to/x509/private
clientcas:
- /path/to/ca.pem
- /path/to/another/ca.pem
letsencrypt:
cachefile: /path/to/cache-file
email: [email protected]
debug:
addr: localhost:5001
headers:
X-Content-Type-Options: [nosniff]
http2:
disabled: false
notifications:
endpoints:
- name: alistener
disabled: false
url: https://my.listener.com/event
headers: <http.Header>
timeout: 500
threshold: 5
backoff: 1000
ignoredmediatypes:
- application/octet-stream
redis:
addr: localhost:6379
password: asecret
db: 0
dialtimeout: 10ms
readtimeout: 10ms
writetimeout: 10ms
pool:
maxidle: 16
maxactive: 64
idletimeout: 300s
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
file:
- file: /path/to/checked/file
interval: 10s
http:
- uri: http://server.to.check/must/return/200
headers:
Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==]
statuscode: 200
timeout: 3s
interval: 10s
threshold: 3
tcp:
- addr: redis-server.domain.com:6379
timeout: 3s
interval: 10s
threshold: 3
proxy:
remoteurl: https://registry-1.docker.io
username: [username]
password: [password]
compatibility:
schema1:
signingkeyfile: /etc/registry/key.json
validation:
enabled: true
manifests:
urls:
allow:
- ^https?://([^/]+\.)*example\.com/
deny:
- ^https?://www\.example\.com/
[root@localhost ~]# docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/config.yml:/etc/docker/registry/config.yml \
registry:2
六、Registry中images的查询
[root@localhost ~]# curl --cacert certs/domain.crt --basic --user lb:lb123 https://myregistrydomain.com:5000/v2/_catalog
{"repositories":["my-centos"]}
参考:
官方文档:https://docs.docker.com/registry/
官方公开的GitHub集中仓库:https://hub.docker.com/_/registry