該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
以及這個 30 天的 Docker 教學有出書喔!如果喜歡這個系列可以支持一下,天瓏書局
昨天我們把映像檔推上了 DockerHub,今天我將介紹映像檔的全名,但在介紹全名之前,我們可以替映像檔重新貼上標籤,試試看 DockerHub 的快取,順便介紹如何在本機運行映像檔的儲存庫。
既然前面有提過映像層是利用每一層的獨特 ID 來辨識存不存在,並加以利用這個機制來避免重複建置映像層。
那我們就把剛剛的 robeeerto/nginx:latest 這個映像檔換一個標籤推上去看看,會發生什麼事吧!
$ docker image tag robeeerto/nginx:latest robeeerto/nginx:v2
# 無反應為正常情況
$ docker image push robeeerto/nginx:v2
The push refers to repository [docker.io/robeeerto/nginx]
b539cf60d7bb: Layer already exists
bdc7a32279cc: Layer already exists
f91d0987b144: Layer already exists
3a89c8160a43: Layer already exists
e3257a399753: Layer already exists
92a4e8a3140f: Layer already exists
v2: digest: sha256:f26fbadb0acab4a21ecb4e337a32690... size: 1570
不論是體感的速度,還是 Docker 給予我們的回應都可以驗證先前所提到的快取機制。
接著回到 DockerHub 也確實可以看到兩個不同的標籤有著相同的映像檔 ID。
在推送映像檔的時候,會注意到有一行寫著:
The push refers to repository [docker.io/robeeerto/nginx]
後面的 robeeerto/nginx 都是已經解釋過的部分,那前面的 docker.io 又是什麼呢?
這其實是 Docker 本身預設儲存庫的網域名稱,所以以下這段才是映像檔的全名: docker.io/robeeerto/nginx:latest
。
而 Docker 也有提供官方的儲存庫映像檔,意味著我們可以建立屬於自己的儲存庫,若成功部署至網際網路後,推送映像檔的全名會像這樣:robeeerto.com/robeeerto/nginx:latest
。
對於私人的專案除了付費使用 DockerHub 的 Private Registry 外,自己架設一個屬於自己的儲存庫也是一件很值得的事情,在後面的章節將會帶領大家部署一個屬於自己的儲存庫。
雖然後面的章節會帶領大家把儲存庫部署至網路上,但我們還是要先在本地先嘗試一下儲存庫的容器執行起來是什麼樣子,以及如何在沒有畫面的情況下和儲存庫做溝通呢?
輸入以下指令:
$ docker run -d -p 5000:5000 --name registry --env REGISTRY_STORAGE_DELETE_ENABLED=true registry:2 # 不換行
53efa11dfca5342c348f71e417302969180c4db5a046cca....
這時候我們的本地端就已經運行了一個映像檔的儲存庫了,讓我們試著把剛才重新貼標籤的映像檔再換一個新的標籤吧。
$ docker image tag robeeerto/nginx:latest localhost:5000/robeeerto/nginx:latest # 不換行
接著把它推進去我們本地運行起來的儲存庫內:
$ docker image push localhost:5000/robeeerto/nginx:latest
The push refers to repository [localhost:5000/robeeerto/nginx]
b539cf60d7bb: Pushed
bdc7a32279cc: Pushed
f91d0987b144: Pushed
3a89c8160a43: Pushed
e3257a399753: Pushed
92a4e8a3140f: Pushed
latest: digest: sha256:f26fbadb0acab4a21e25669d99ed1261 size: 1570
但因為本地的儲存庫不像 DockerHub 有做了漂亮的使用者介面來讓我們清楚的看到自己推上去的映像檔,所以需要透過官方提供的 API 來確認我們是不是有正確的把映像檔送進去。
這邊可以透過 curl 這個套件,簡單的做確認:
$ curl http://localhost:5000/v2/robeeerto/nginx/tags/list
{"name":"robeeerto/nginx","tags":["latest"]}
可以看到我們推進去的 robeeerto/nginx:latest 確實已經存在本地的儲存庫之中,接著我們嘗試使用官方提供的 API 來刪除掉儲存庫內的映像檔,可以看到刪除映像檔的參數還需要映像檔本身的 digest 這個值。
所以我們需要找到另一個可以得到 digest 的 API 才能回來刪除掉這個映像檔,透過閱讀官方的文件可以得知下面這個 API 能夠得到映像檔的 manifest。
仔細閱讀發現可以透過 HEAD 的方式取得這個映像檔的 digest 值,所以我們一樣利用 curl 這個工具來取得資料。
$ curl --head http://localhost:5000/v2/robeeerto/nginx/manifests/latest -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'
# 不換行
HTTP/1.1 200 OK
Content-Length: 1570
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261"
X-Content-Type-Options: nosniff
Date: Sun, 04 Sep 2022 10:26:59 GMT
最重要的資訊就是這行:
Docker-Content-Digest: sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261
接著我們拿著得到的 digest 去請求刪除的 API。
$ curl -X DELETE http://localhost:5000/v2/robeeerto/nginx/manifests/sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261 # 不換行
# 沒有反應是正常的
接著我們可以再次透過 API 來確認目前儲存庫內的映像檔列表:
$ curl http://localhost:5000/v2/robeeerto/nginx/tags/list
{"name":"robeeerto/nginx","tags":null}
可以看到原本擁有 latest 的標籤現在變成了 null;或許這樣子的方式會讓人覺得自己建立儲存庫很麻煩,但其實可以搭配開源的儲存庫 UI 介面一起部署,就可以像操作 DokcerHub 的方式來管理自己的儲存庫。
經過今天介紹後,大家應該可以在本機運行一個映像檔的儲存庫了,而明天我們將會拿一個 Dockerfile 作為範例開始介紹如何撰寫 Dockerfile。