docker鏡像管理分析以及retag的實現

在容器化部署的場景下,鏡像管理是一個很重要的部分,畢竟所有的程序都是以鏡像的方式來交付和運行的。

一個標準的鏡像名稱分爲三個部分:鏡像倉庫地址/鏡像存儲庫:鏡像版本,比如http://hub.docker.io/library/redis:1.0

鏡像倉庫地址:鏡像倉庫服務器的域名,比如docker官方鏡像倉庫http://hub.docker.io

鏡像存儲庫:鏡像的存儲名稱,官方名稱repository,比如library/redis

鏡像版本:鏡像的版本,官方名稱tag,比如1.0

衆所周知,docker鏡像是以分層來存儲鏡像的,而這個層是分倉庫管理的,比如library/redis下的層和private/redis下的層是分開管理的,通過docker registry的api獲取到的library/redis下的層在private/redis下是不存在的。

再介紹一下鏡像的pull和push過程:

pull操作:

  1. 先拉取清單文件
  2. 再拉取鏡像層

push操作:

  1. 先上傳所有層到倉庫
  2. 最後上傳清單文件

鏡像retag功能實現的原理就是利用了pull的拉取清單文件和push的上傳清單文件

通過上面的分析,在做鏡像的retag時,就需要考慮retag後的鏡像是否是同一個倉庫下的,如果是同一個repository下的retag操作,比如library/redis:1.0,在retag後成library/redis:1.1,那麼就表示是在同一個repository下,就不需要使用掛載操作,官方稱爲Cross Repository Blob Mount(交叉掛載層),如果library/redis:1.0在retag後變爲private/redis:1.0,由於不在同一個repository下,因此必須要進行mount操作纔行,不然在push清單文件的時候會報錯,具體步驟如下:

  1. 拉取library/redis:1.0的清單文件,相關的API:
    GET /v2/<name>/manifests/<reference>
    
     
  2. 檢查清單文件中的層,如果retag的目標repository與第一步拉取的清單文件的repository不是同一個,進行mount層操作: 
    POST /v2/<name>/blobs/uploads/?mount=<digest>&from=<repository name>

     

  3. 上傳清單文件到目標repository中,完成retag
    PUT /v2/<name>/manifests/<reference>

     

整個retag的過程就是這樣了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章