docker registry搭建私有镜像仓库

发布时间 2023-07-15 17:57:53作者: 彦承

大神实践

https://www.cnblogs.com/gcgc/p/10489385.html

推送到私有镜像仓示例

1、拉取并运行registry镜像:

拉取:docker pull registry

注:下载到的版本默认为 docker.io/registry:latest

2、运行regsitry镜像:

docker run -d -v /home/docker/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest

注:

-v /home/docker/registry:/var/lib/registry,Registry服务默认会将上传的镜像保存在容器里面的/var/lib/registry目录,将主机的/home/docker/registry目录挂载到该目录,即可实现将镜像保存到主机的/home/docker/registry目录了。

-p 5000:5000,将registry服务默认的5000端口映射到宿主机的5000端口上。

—name,运行起来的容器名称为registry 。

3、拉取一个用于测试的镜像:

docker pull hello-world:latest

4、给测试镜像重新打上tag:

docker tag hello-world:latest 127.0.0.1:5000/hello-world:1.0

注:将hello-world:latest镜像打上127.0.0.1:5000/hello-world:1.0标签,此时查看镜像列表可以看到两个镜像。

docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 4 months ago 13.26 kB

127.0.0.1:5000/hello-world 1.0 feb5d9fea6a5 4 months ago 13.26 kB

5、将打上tag的镜像推送到私有仓库:

docker push 127.0.0.1:5000/hello-world1.0

6、查看推送成功的镜像:

此时可以通过调用regsitry的v2接口查看镜像信息:curl http://127.0.0.1:5000/v2/_catalog

{
  "repositories": [
    "hello-world"
  ]
}

常见问题解决

问题1:解决推送过程中出现的getsocket:connection refused.
现象:

docker push 127.0.0.1:5000/registry:1.0
The push refers to repository [7.220.62.96:5000/registry]
Get https://7.220.62.96:5000/v2/: http: server gave HTTP response to HTTPS client
解决:vim /etc/docker/daemon.json
增加:

{
    "insecure-registries": [
        "7.220.62.96:5000"
    ]
}

重启docker服务:systemctl restart docker
再次推送,成功。

问题2:

registry的启动上传任务接口,不支持大写的name,否则会404。

开启外部2375访问

背景:集成了docker-java.jar第三方开源插件,封装docker命名远程执行操作,需要开启2375端口。

1、编辑docker文件:/usr/lib/systemd/system/docker.service

vim /usr/lib/systemd/system/docker.service

2、修改ExecStart行为下面内容:

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \

注:原始的内容如下,只需要在前面补充即可。

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash

ExecStart=/usr/bin/dockerd $OPTIONS \
                           $DOCKER_STORAGE_OPTIONS \
                           $DOCKER_NETWORK_OPTIONS \
                           $INSECURE_REGISTRY
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

3、重新加载docker配置:

systemctl daemon-reload  // 1,加载docker守护线程
systemctl restart docker // 2,重启docker

registry启动用户认证

链接:https://mojo-zd.github.io/2018/04/12/Docker-Registry-V2认证机制,以及如何构建自己的Registy-Auth-Server/

默认情况下docker registry将会从/etc/docker/registry/config.yml读取所有的配置信息。

auth鉴权部分的配置:

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

注:registry默认不开启auth配置。用户可以自定义其中一种实现来完成registry的认证配置。

完整的registry配置信息如下:

version: 0.1
log:
  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
    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]
notifications:
  endpoints:
    - name: alistener
      disabled: false
      url: https://my.listener.com/event
      headers: <http.Header>
      timeout: 500
      threshold: 5
      backoff: 1000
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

docker登录镜像仓

#docker login
[root@HN01 ~]# docker login 7.220.62.96:5000
Username: root
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
[https://docs.docker.com/engine/reference/commandline/login/#credentials-store](https://docs.docker.com/engine/reference/commandline/login/#credentials-store)
Login Succeeded
# 查看密码保存位置及格式
[root@HN01 ~]# cat /root/.docker/config.json
{
        "auths": {
                "7.220.62.96:5000": {
                        "auth": "cm9vdDpodWF3ZWlAMTIz"
                }
        },
        "HttpHeaders": {
                "User-Agent": "Docker-Client/18.09.0 (linux)"
        }
}
#docker logout
[root@HN01 ~]# docker logout 7.220.62.96:5000
Removing login credentials for 7.220.62.96:5000

注:cm9vdDpodWF3ZWlAMTIz,base64解码之后为:
root:huawei@123
即是以“用户名:密码”使用base64加密进行存储的。

注:如果是使用http请求访问,则需要在请求头中添加鉴权字段,key为:Authorization,value为:Basic cm9vdDpodWF3ZWlAMTIz。
注:使用curl命令时,可以使用下面两种方式
1、curl -H "Authorization: Basic cm9vdDpodWF3ZWlAMTIz" http://localhost:5000/v2/_catalog -v
2、curl -u root:huawei@123 http://localhost:5000/v2/_catalog -v

regsitry的垃圾回收

1、regisrty gc时会中断push服务,链接:https://blog.csdn.net/xts_huangxin/article/details/51693890

原因:gc是非事务性操作。删除前最好置为read-only,而此时registry将暂时不能提供push服务。

2、垃圾回收的方式:

docker exec registry1 registry garbage-collect /etc/docker/registry/config.yml

3、垃圾回收的耗时:

gc时间待确认,使用blobs 5.2G + repositries 28M的数据测试需要花2-3秒的扫描和清理时间

docker pull镜像

curl -k -s --header "Accept: application/vnd.docker.distribution.manifest.v2+json" https://krm.registry.com:5000/v2/docker_auth/manifests/1.0

registry默认是1.0的,如果要获取2.0的manifest,需要在请求头中增加“Accept: application/vnd.docker.distribution.manifest.v2+json”。