1.Registry
官方文档:https://docs.docker.com/registry/
https://docs.docker.com/registry/spec/api/
* 有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。
* docker-registry是官方提供的工具,可以用于构建私有的镜像仓库。
* 有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。
* docker-registry是官方提供的工具,可以用于构建私有的镜像仓库。
注:
* 随着docker使用的镜像越来越多,就需要有一个保存镜像的地方,这就是仓库。
* 目前常用的两种仓库:
公共仓库和私有仓库。最方便的就是使用公共仓库上传和下载,
下载公共仓库的镜像是不需要注册的,但是上传时,是需要注册的。
* 私有仓库最常用的就是registry、Harbor两种,那接下来详细介绍如何创建私有仓库。
* 今天说的Registry仓库,是通过一个容器给我们提供的服务,是比较简
易的私有仓库,以后在企业中还会有功能更加完善的Harbor仓库。
* 随着docker使用的镜像越来越多,就需要有一个保存镜像的地方,这就是仓库。
* 目前常用的两种仓库:
公共仓库和私有仓库。最方便的就是使用公共仓库上传和下载,
下载公共仓库的镜像是不需要注册的,但是上传时,是需要注册的。
* 私有仓库最常用的就是registry、Harbor两种,那接下来详细介绍如何创建私有仓库。
* 今天说的Registry仓库,是通过一个容器给我们提供的服务,是比较简
易的私有仓库,以后在企业中还会有功能更加完善的Harbor仓库。
环境:
ip | info |
---|---|
k8s1(192.168.49.143) | server |
k8s2() | client |
2.下载
[root@k8s1 ~]# docker pull registry:2
启动
bash
#启动
[root@k8s1 ~]#docker run -itd --name registry --restart=always -p 5000:5000 -v /registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2
//创建一个registry容器来运行registry服务;
//-p:端口映射(前面是宿主机端口:后面是容器暴露的端口);
//-v:挂载目录(前面是宿主机的目录:后面的是容器的目录)自动创建宿主机的目录;
//--restart=always:随docker服务的启动而启动
#查看
[root@k8s1 ~]# netstat -anlp|grep 5000
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 3762/docker-proxy
#启动
[root@k8s1 ~]#docker run -itd --name registry --restart=always -p 5000:5000 -v /registry:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2
//创建一个registry容器来运行registry服务;
//-p:端口映射(前面是宿主机端口:后面是容器暴露的端口);
//-v:挂载目录(前面是宿主机的目录:后面的是容器的目录)自动创建宿主机的目录;
//--restart=always:随docker服务的启动而启动
#查看
[root@k8s1 ~]# netstat -anlp|grep 5000
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 3762/docker-proxy
tag
命名:registry_url/css/name:version
bash
[root@k8s1 ~]# docker tag hello-world:latest 192.168.49.143:5000/hello-world
//更改镜像名称
注:私有仓库镜像的命名规则:ip:5000/XXX(宿主机的IP:5000端口/镜像名称)
//相当于是cp一份镜像
[root@k8s1 ~]# docker tag hello-world:latest 192.168.49.143:5000/hello-world
//更改镜像名称
注:私有仓库镜像的命名规则:ip:5000/XXX(宿主机的IP:5000端口/镜像名称)
//相当于是cp一份镜像
修改启动
bash
[root@k8s1 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=ip:5000
[root@k8s1 ~]# systemctl daemon-reload
[root@k8s1 ~]# systemctl restart docker
[root@k8s1 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=ip:5000
[root@k8s1 ~]# systemctl daemon-reload
[root@k8s1 ~]# systemctl restart docker
查看仓库中镜像
bash
[root@k8s1 ~]# curl 192.168.49.143:5000/v2/_catalog
{"repositories":[]}
[root@k8s1 ~]# curl 192.168.49.143:5000/v2/_catalog
{"repositories":[]}
上传
bash
[root@k8s1 ~]# docker push 192.168.49.143:5000/hello-world:latest
The push refers to repository [192.168.49.143:5000/hello-world]
f22b99068db9: Pushed
latest: digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792 size: 525
#查看
[root@k8s1 ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["hello-world"]}
#查看镜像的详细信息
方法:GET /v2/<name>/tags/list
-- name 为镜像名字
[root@k8s1 ~]# curl 127.0.0.1:5000/v2/hello-world/tags/list
{"name":"hello-world","tags":["latest"]}
#获取镜像信息
方法:GET /v2/<name>/manifests/<reference>
其中<name>为镜像名,<reference>可以是"tag"或"digest"
#删除镜像
方法:DELETE /v2/<name>/manifests/<reference>
其中<name>为镜像名,<reference>只能是"digest"
-- 获取digest
[root@k8s1 ~]# curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I 127.0.0.1:5000/v2/hello-world/manifests/latest
HTTP/1.1 200 OK
Content-Length: 525
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792"
X-Content-Type-Options: nosniff
Date: Sun, 25 Apr 2021 07:16:34 GMT
#或者通过
[root@k8s1 ~]# docker images --digests
#执行删除
[root@k8s1 ~]# curl -X DELETE http://192.168.49.143:5000/v2/hello-world/manifests/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
[root@k8s1 ~]# curl http://192.168.49.143:5000/v2/_catalog
{"repositories":["hello-world"]}
#这里说明虽然删除了manifests,但是image依然可以看到;并没有被删除;
[root@k8s1 ~]# curl -X DELETE http://192.168.49.143:5000/v2/hello-world/manifests/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}
#查看是否存在
[root@k8s1 ~]# curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -X HEAD http://192.168.49.143:5000/v2/hello-world/manifests/latest
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Sun, 25 Apr 2021 07:37:20 GMT
Content-Length: 96
#尝试pull
[root@k8s2 ~]# docker pull 192.168.49.143:5000/hello-world
Using default tag: latest
Error response from daemon: manifest for 192.168.49.143:5000/hello-world:latest not found: manifest unknown: manifest unknown
[root@k8s1 ~]# docker push 192.168.49.143:5000/hello-world:latest
The push refers to repository [192.168.49.143:5000/hello-world]
f22b99068db9: Pushed
latest: digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792 size: 525
#查看
[root@k8s1 ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["hello-world"]}
#查看镜像的详细信息
方法:GET /v2/<name>/tags/list
-- name 为镜像名字
[root@k8s1 ~]# curl 127.0.0.1:5000/v2/hello-world/tags/list
{"name":"hello-world","tags":["latest"]}
#获取镜像信息
方法:GET /v2/<name>/manifests/<reference>
其中<name>为镜像名,<reference>可以是"tag"或"digest"
#删除镜像
方法:DELETE /v2/<name>/manifests/<reference>
其中<name>为镜像名,<reference>只能是"digest"
-- 获取digest
[root@k8s1 ~]# curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I 127.0.0.1:5000/v2/hello-world/manifests/latest
HTTP/1.1 200 OK
Content-Length: 525
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792"
X-Content-Type-Options: nosniff
Date: Sun, 25 Apr 2021 07:16:34 GMT
#或者通过
[root@k8s1 ~]# docker images --digests
#执行删除
[root@k8s1 ~]# curl -X DELETE http://192.168.49.143:5000/v2/hello-world/manifests/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
[root@k8s1 ~]# curl http://192.168.49.143:5000/v2/_catalog
{"repositories":["hello-world"]}
#这里说明虽然删除了manifests,但是image依然可以看到;并没有被删除;
[root@k8s1 ~]# curl -X DELETE http://192.168.49.143:5000/v2/hello-world/manifests/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}
#查看是否存在
[root@k8s1 ~]# curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -X HEAD http://192.168.49.143:5000/v2/hello-world/manifests/latest
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Sun, 25 Apr 2021 07:37:20 GMT
Content-Length: 96
#尝试pull
[root@k8s2 ~]# docker pull 192.168.49.143:5000/hello-world
Using default tag: latest
Error response from daemon: manifest for 192.168.49.143:5000/hello-world:latest not found: manifest unknown: manifest unknown
从这个过程中,可以知道: A. 删除manifests文件并不会删除image 的各个layer层;所以不会释放layer占用的空间
B. 删除manifests会导致pull操作失效,因为pull操作需要manifests这个文件;
C. 通过REST API的方式依然可以看到丢失了manifests文件的image
释放空间
bash
[root@k8s1 v2]# pwd
/registry/docker/registry/v2
#删除registry之后的空间大小,此时并没有释放空间
[root@k8s1 v2]# du -hsx *
16K blobs
12K repositories
#进入容器
[root@k8s1 v2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f1ebb04a807 registry:2 "/entrypoint.sh /etc…" 23 minutes ago Up 23 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
[root@k8s1 v2]# docker exec -it 9f1ebb04a807 /bin/sh
#执行registry garbage-collect 命令
/ # registry garbage-collect
configuration error: configuration path unspecified
Usage:
registry garbage-collect <config> [flags]
Flags:
-m, --delete-untagged=false: delete manifests that are not currently referenced via tag
-d, --dry-run=false: do everything except remove the blobs
-h, --help=false: help for garbage-collect
Additional help topics:
/ # cat /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
/ #registry garbage-collect /etc/docker/registry/config.yml
hello-world
0 blobs marked, 4 blobs and 0 manifests eligible for deletion
blob eligible for deletion: sha256:d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726
。。。。
[root@k8s1 v2]# du -hxs *
0 blobs
12K repositories
#至此结束
[root@k8s1 v2]# pwd
/registry/docker/registry/v2
#删除registry之后的空间大小,此时并没有释放空间
[root@k8s1 v2]# du -hsx *
16K blobs
12K repositories
#进入容器
[root@k8s1 v2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f1ebb04a807 registry:2 "/entrypoint.sh /etc…" 23 minutes ago Up 23 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
[root@k8s1 v2]# docker exec -it 9f1ebb04a807 /bin/sh
#执行registry garbage-collect 命令
/ # registry garbage-collect
configuration error: configuration path unspecified
Usage:
registry garbage-collect <config> [flags]
Flags:
-m, --delete-untagged=false: delete manifests that are not currently referenced via tag
-d, --dry-run=false: do everything except remove the blobs
-h, --help=false: help for garbage-collect
Additional help topics:
/ # cat /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
/ #registry garbage-collect /etc/docker/registry/config.yml
hello-world
0 blobs marked, 4 blobs and 0 manifests eligible for deletion
blob eligible for deletion: sha256:d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726
。。。。
[root@k8s1 v2]# du -hxs *
0 blobs
12K repositories
#至此结束
[!TIP]
1.首先删除image的manifests文件,这个过程需要获得image的digests ID, 而要正确获得该ID, 需要添加特殊的请求头: --header "Accept: application/vnd.docker.distribution.manifest.v2+json" , 该步骤可以导致pull 操作失效;
2.需要删除对应的blobs, 这个可以通过: registry garbage-collect CONFIG-FILE 来完成;可以清理掉layer占用的空间问题;
3.需要删除对应的repository, 这个必须手动删除才可以
client
bash
[root@k8s2 ~]# curl 192.168.49.143:5000/v2/_catalog
{"repositories":["hello-world"]}
[root@k8s2 ~]# docker pull 192.168.49.143:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
b8dfde127a29: Pull complete
Digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
Status: Downloaded newer image for 192.168.49.143:5000/hello-world:latest
192.168.49.143:5000/hello-world:latest
[root@k8s2 ~]# docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.49.143:5000/hello-world latest d1165f221234 7 weeks ago 13.3kB
[root@k8s2 ~]# curl 192.168.49.143:5000/v2/_catalog
{"repositories":["hello-world"]}
[root@k8s2 ~]# docker pull 192.168.49.143:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
b8dfde127a29: Pull complete
Digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
Status: Downloaded newer image for 192.168.49.143:5000/hello-world:latest
192.168.49.143:5000/hello-world:latest
[root@k8s2 ~]# docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.49.143:5000/hello-world latest d1165f221234 7 weeks ago 13.3kB
3.用户认证
bash
对用户名和密码,进行base64编码。
格式:echo -n "用户名:密码" | base64
(1)携带认证信息发起请求
格式:curl -v -H "Authorization: Basic 认证信息" -X GET https://docker.[yun.ccb.com/v2/](https://docker.yun.ccb.com/v2/)<name>/tags/list
https://blog.51cto.com/u_14306186/2514802
对用户名和密码,进行base64编码。
格式:echo -n "用户名:密码" | base64
(1)携带认证信息发起请求
格式:curl -v -H "Authorization: Basic 认证信息" -X GET https://docker.[yun.ccb.com/v2/](https://docker.yun.ccb.com/v2/)<name>/tags/list
https://blog.51cto.com/u_14306186/2514802