zoukankan      html  css  js  c++  java
  • Docker 私有仓库

    Docker 私有仓库

    前言

    a. 本文主要为 Docker的视频教程 笔记。
    b. 环境为 CentOS 7.0 云服务器
    c. 上一篇:Docker 容器间的单向连接

    1. 安装与启动

    Docker 的仓库软件也被打包在了镜像中,可以使用 docker pull registry 命令获取创建 Docker 仓库的软件 registry

    启动命令:

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

    registry 中存储的路径为 /var/lib/registry,映射到本地的 /opt/myregistry

    2. 向私有仓库上传镜像

    提前基于 centos:7 做好一个容器,里面有 httpd 和一个自定义的主页,id 为 ff88077f841d,起的名称为 centos_httpd_customindex 。

    (1)为镜像打标签

    命令为:

    docker tag <IMAGE_ID> <ADDRESS_AND_PORT>/<CUSTOM_NAME>:<VERSION>
    

    如:

    [root@VM_0_2_centos ~]# docker tag ff88077f841d 127.0.0.1:5000/httpd:v1

    (2)上传:

    命令为:

    docker push <IMAGE_TAG>
    

    如:

    [root@VM_0_2_centos ~]# docker push 127.0.0.1:5000/httpd:v1

    TIPS: Docker 私有镜像前面有用户名的,如 abc/centos:7, 而 Docker 官方镜像前面没有域名;类似的,Docker 私有仓库前面有域名或 ip 地址,而 Docker 的官方仓库则没有。这些私有仓库镜像的前面的地址就是作为上传地址来使用的

    如果不打标签直接上传,则意味上传到 Docker 的官方仓库中,结果为

    [root@VM_0_2_centos ~]# docker push centos_httpd_customindex
    The push refers to repository [docker.io/library/centos_httpd_customindex]
    d5b7ae674584: Preparing
    c88ae10680b3: Preparing
    16311dc4d3e8: Preparing
    ad136decc5d0: Preparing
    77b174a6a187: Preparing
    denied: requested access to the resource is denied

    (3)意料外的情况

    在视频教程中,会提示无法使用https访问,此时修改 /etc/docker/daemon.json ,加入私有仓库的ip地址和端口号

    {
    	"insecure-registries":["<PRIVATE_REGISTRY_ADDRESS_AND_PORT>"]
    }
    

    并使用 systemctl restart docker 重启docker服务,但在本地实验时并未出现这种情况。

    (4)多种方法查看上传

    A. 从文件系统查看

    由于映射了目录,因此可以查看到已经上传了的镜像(此处的 v2 的含义是 registry 软件的版本,应该是区别于最开始的 registry 软件版本)

    [root@VM_0_2_centos ~]# ls /opt/myregistry/docker/registry/v2/repositories/httpd/_manifests/tags/
    v1

    由于该镜像是基于 centos:7 做的,如果此时再上传 centos:7 的镜像,由于镜像是分层的,则实际并不会上传,如:

    [root@VM_0_2_centos ~]# docker tag centos:7 127.0.0.1:5000/centos:v1
    [root@VM_0_2_centos ~]# docker push 127.0.0.1:5000/centos:v1
    The push refers to repository [127.0.0.1:5000/centos]
    77b174a6a187: Mounted from httpd
    v1: digest: sha256:285bc3161133ec01d8ca8680cd746eecbfdbc1faa6313bd863151c4b26d7e5a5 size: 529

    可以看到镜像已经通过之前的 httpd 镜像层取得了。

    B. 使用 registry 提供的接口查看

    使用 http 协议访问(在浏览器中或使用 Postman ) 仓库地址加 /v2/_catalog

    如:

    [root@VM_0_2_centos ~]# curl localhost:5000/v2/_catalog
    {"repositories":["centos","httpd"]}

    查看具体某个镜像有哪些版本,可以访问 仓库地址加/v2/镜像名/tags/list

    如:

    [root@VM_0_2_centos ~]# curl localhost:5000/v2/centos/tags/list
    {"name":"centos","tags":["v1"]}

    可以看到之前上传的 centos 有 v1 的版本

    3. 为私有仓库加入basic认证

    (1)安装密钥工具及生成密钥

    安装 apache 的 http 密钥生成工具:

    yum install httpd-tools -y
    

    使用 htpasswd 生成密钥

    htpasswd -Bbn <USER_NAME> <PASSWORD> >> <PATH_TO_FILE>
    

    其中 htpasswd 的 -B 表示使用某种安全的加密(原文为:“ -B Force bcrypt aencryption of the password (very secure)”, 翻译软件似乎也不能很好地翻译);-b 表示在命令行中输入密码即可,而不是使用交互;-n 表示直接显示在标准输出中(在本例利用 “>>” 从标准输出写入文件);

    如:

    [root@VM_0_2_centos ~]# mkdir /opt/registry-var/auth -p
    [root@VM_0_2_centos ~]# htpasswd -Bbn test 123456 >> /opt/registry-var/auth/htpasswd
    [root@VM_0_2_centos ~]# cat /opt/registry-var/auth/htpasswd
    test:$2y$05$OB9RRrL2nZTjH5KGYsrqsO4yDE2JIu55URCLP8tvYAD5TnfYWRbw6

    (2)启动镜像及效果

    删除原有镜像后,使用下面的命令重新启动镜像:

    docker run -d -p 5000:5000 --restart=always 
    	-v /opt/registry-var/auth/:/auth/ 
    	-v /opt/myregistry/:/var/lib/registry 
    	-e "REGISTRY_AUTH=htpasswd" 
    	-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" 
    	-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" 
    	registry
    

    此时再直接使用 http 访问时就会显示 UNAUTHORIZED,如:

    [root@VM_0_2_centos ~]# curl localhost:5000/v2/centos/tags/list
    {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"centos","Action":"pull"}]}]}

    应该使用 curl 的命令的参数,发送时加入用户名和密码等验证信息

    curl -u '<USER_NAME>:<PASSWORD>' <URL>
    或
    curl -u '<USER_NAME>' <URL>	# 需要交互输入密码
    

    如:

    [root@VM_0_2_centos ~]# curl -u 'test:123456' localhost:5000/v2/centos/tags/list
    {"name":"centos","tags":["v1"]}

    [root@VM_0_2_centos ~]# curl -u 'test' localhost:5000/v2/centos/tags/list
    Enter host password for user 'test':
    {"name":"centos","tags":["v1"]}

    直接上传镜像和拉取镜像也需要先登陆,如:

    [root@VM_0_2_centos ~]# docker push 127.0.0.1:5000/httpd:v2
    The push refers to repository [127.0.0.1:5000/httpd]
    d5b7ae674584: Preparing
    c88ae10680b3: Preparing
    16311dc4d3e8: Preparing
    ad136decc5d0: Preparing
    77b174a6a187: Preparing
    no basic auth credentials

    使用 docker login 登陆:

    [root@VM_0_2_centos ~]# docker login 127.0.0.1:5000
    Username: test
    Password:
    Login Succeeded

    再次上传:

    [root@VM_0_2_centos ~]# docker push 127.0.0.1:5000/httpd:v2
    The push refers to repository [127.0.0.1:5000/httpd]
    d5b7ae674584: Layer already exists c88ae10680b3: Layer already exists
    16311dc4d3e8: Layer already exists
    ad136decc5d0: Layer already exists
    77b174a6a187: Layer already exists
    v2: digest: sha256:2c8b4238f32e7ad4e670f7bc14619ad670bb0dd472b64f761fbbca24ae53d506 size: 1363

    4. 删除私有仓库的镜像

    视频教程里的方法时直接进入文件系统删除标签,之后 registry 的 garbage-collect 命令让系统自动判断和删除镜像。在搜索后,发现使用 http 请求访问 api 删除标签的方式比较优雅,但同样也需要利用到容器的 garbage-collect。

    先查看现在的镜像情况:

    [root@VM_0_2_centos ~]# curl -u 'test:123456' localhost:5000/v2/centos/tags/list
    {"name":"centos","tags":["v2","v1"]}

    可以看到 centos 的镜像有 v1、v2 两个版本。进入 docker registry 容器,查看占用空间情况:

    [root@VM_0_2_centos ~]# docker exec -it 28ca1493ba01 /bin/sh

    / # du -smh /var/lib/registry/docker/registry/
    623.9M /var/lib/registry/docker/registry/

    TIPS: du 的 -s 表示只显示作为参数的目录的总体情况(而不显示子目录的情况),-h 表示以人类可读的方式(以 KB、MB 等单位显示),-m 表示单位是 MB

    (1)使用 api 查看容器 id

    命令为:

    curl -u '<USER_NAME>:<PASSWORD>' 
    	--header "Accept: application/vnd.docker.distribution.manifest.v2+json" 
    	-I <ADDRESS_AND_PORT>/v2/<IMAGE_NAME>/manifests/<VERSION>
    

    -I 表示只显示头部信息

    注意,名为 Accept 的头一定要加上,否则返回值都会不同,接下来的步骤无法继续操作

    如:

    [root@VM_0_2_centos ~]# curl -u 'test:123456' --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I localhost:5000/v2/centos/manifests/v2
    HTTP/1.1 200 OK
    Content-Length: 742
    Content-Type: application/vnd.docker.distribution.manifest.v2+json
    Docker-Content-Digest: sha256:41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d
    Docker-Distribution-Api-Version: registry/2.0
    Etag: "sha256:41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d"
    X-Content-Type-Options: nosniff
    Date: Mon, 15 Jun 2020 14:09:47 GMT

    取其中的 Etag 的 sha256 值。

    (2)使用 api 删除容器标签

    命令为:

    curl -u '<USER_NAME>:<PASSWORD>' 
    	 -I -X DELETE <ADDRESS_AND_PORT>/v2/<IMAGE_NAME>/manifests/sha256:<SHA256_ID>
    

    如:

    [root@VM_0_2_centos ~]# curl -u 'test:123456' -I -X DELETE localhost:5000/v2/centos/manifests/sha256:41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d
    HTTP/1.1 405 Method Not Allowed
    Content-Type: application/json; charset=utf-8
    Docker-Distribution-Api-Version: registry/2.0
    X-Content-Type-Options: nosniff
    Date: Mon, 15 Jun 2020 14:00:31 GMT
    Content-Length: 78

    此时提示: Method Not Allowed,需要进入容器,修改 registry 的配置,使其可以允许修改

    / # vi /etc/docker/registry/config.yml
    / # cat /etc/docker/registry/config.yml
    version: 0.1
    log:
      fields:
        service: registry
    storage:
      cache:
        blobdescriptor: inmemory
      filesystem:
        rootdirectory: /var/lib/registry
      delete:	#加入此处的配置
        enabled: true
    http:
      addr: :5000
      headers:
        X-Content-Type-Options: [nosniff]
    health:
      storagedriver:
        enabled: true
        interval: 10s
        threshold: 3
    

    宿主机重启服务后,再次执行:

    d[root@VM_0_2_centos ~]# curl -u 'test:123456' -I -X DELETE localhost:5000/v2/centos/manifests/sha256:41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d
    HTTP/1.1 202 Accepted
    Docker-Distribution-Api-Version: registry/2.0
    X-Content-Type-Options: nosniff
    Date: Mon, 15 Jun 2020 14:10:49 GMT
    Content-Length: 0

    返回成功!

    (3)进入容器删除实际文件

    此时再次查看虽然标签删除了但空间未释放:

    [root@VM_0_2_centos ~]# curl -u 'test:123456' localhost:5000/v2/centos/tags/list
    {"name":"centos","tags":["v1"]}
    [root@VM_0_2_centos ~]# docker exec -it 28ca1493ba01 /bin/sh
    / # du -smh /var/lib/registry/docker/registry/
    623.9M /var/lib/registry/docker/registry/

    在容器使用 registry 的 garbage-collect 进行垃圾回收,命令为:

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

    如:

    / # registry garbage-collect /etc/docker/registry/config.yml
    centos
    centos: marking manifest sha256:285bc3161133ec01d8ca8680cd746eecbfdbc1faa6313bd863151c4b26d7e5a5
    centos: marking blob sha256:5e35e350aded98340bc8fcb0ba392d809c807bc3eb5c618d4a0674d98d88bccd
    centos: marking blob sha256:ab5ef0e5819490abe86106fd9f4381123e37a03e80e650be39f7938d30ecb530
    3 blobs marked, 4 blobs and 0 manifests eligible for deletion
    blob eligible for deletion: sha256:41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/41/41080ebfb60511cfb6c737b1e83bde6f74acbe51992efab6720e0bdfa856e81d go.version=go1.11.2 instance.id=f5f44c4e-5078-4547-9311-150697d0a9d4 service=registry
    blob eligible for deletion: sha256:4c21c94fbbc522156e0fe9534360ac6ce4dd0ff5b2a41fbf9671d1568e0c7a62
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/4c/4c21c94fbbc522156e0fe9534360ac6ce4dd0ff5b2a41fbf9671d1568e0c7a62 go.version=go1.11.2 instance.id=f5f44c4e-5078-4547-9311-150697d0a9d4 service=registry
    blob eligible for deletion: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/a3/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 go.version=go1.11.2 instance.id=f5f44c4e-5078-4547-9311-150697d0a9d4 service=registry
    blob eligible for deletion: sha256:e60b4e126932ec4b65ce79c5b06198f0bee0eccfefff86e33ab9b5aad6292372
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/e6/e60b4e126932ec4b65ce79c5b06198f0bee0eccfefff86e33ab9b5aad6292372 go.version=go1.11.2 instance.id=f5f44c4e-5078-4547-9311-150697d0a9d4 service=registry

    再次查看空间发现占用确实减少了:

    / # du -smh /var/lib/registry/docker/registry/
    72.6M /var/lib/registry/docker/registry/

    PS:视频教程中的做法为进入容器中删除镜像的标签: rm -rf /var/lib/registry/docker/registry/v2/repositories/centos,之后再进入容器执行垃圾回收。

    参考

    htpasswd 的使用:

    https://www.jianshu.com/p/f4120aa561cc

    删除本地仓库中的 Docker 镜像:

    https://blog.csdn.net/weixin_43905458/article/details/104947884

  • 相关阅读:
    程序员的 59 条搞笑但却真实无比的编程语录
    Github最流行的10,000个Java项目使用的类库
    10大怪异的编程语言
    如何写一篇好的技术博客
    四件在我步入职业软件开发生涯那天起就该知道的事情
    程序员最艰巨的十大任务
    10 个理由让你继续干 IT
    被诅咒的程序员的七宗罪
    顶级程序员的 10 条最佳实践
    谷歌如何管理世界上最聪明的工程师?
  • 原文地址:https://www.cnblogs.com/battor/p/docker_private_registry.html
Copyright © 2011-2022 走看看