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

[root@localhost ~]# docker image remove 192.168.22.153 :5000/my-centos
[root@localhost ~]# docker pull 192.168.22.153: 5000/my-centos
[root@localhost ~]# docker container stop registry
[root@localhost ~]# docker container stop registry && docker container rm -v registry

*注意: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

解决办法是:在 docker server 启动的时候,增加启动参数,默认使用 HTTP 访问:
vi / usr /lib/ systemd /system/ docker.service
[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

Docker 私有仓库配置(registry)-LMLPHP

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
Docker 私有仓库配置(registry)-LMLPHP

三、 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 root@192.168.22.153:/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

在其他机器操作跟上面一致,先登录,后操作。
Docker 私有仓库配置(registry)-LMLPHP

五、使用配置文件

[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: sender@example.com
        to:
          - errors@example.com
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: emailused@letsencrypt.com
  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

12-20 17:29