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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM