亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

容器鏡像拉取API接口請求過程解析

2025-07-03 09:49:55
11
0

鏡像(或制品)拉取過程具體細節在不同客戶端會有差異,但整體而言都會遵循v2接口的規范分為下面幾個步驟

1. 去獲取bearer token,這個token在后續的中都需要使用

2. 獲取制品的manifest,

3. 根據獲取到的manifest信息獲取制品元數據config

4. 根據獲取到的manifest信息并行拉取各個層

對于鏡像的客戶端而言,無論他怎么變,都要經過上面幾個過程去完成鏡像拉取。而其他制品的客戶端,差異在第3,第4點。

不同的客戶端,或者同一個類型,不同版本的客戶端,在怎么樣獲取到bearer token的URL,也會有差異,因此這里就用docker作為例子,介紹拉取一個鏡像,會調用什么接口,各個接口的作用是什么。

第一個接口

當通過docker客戶端拉取一個鏡像 docker pull registry-crs-huadong1.daliqc.cn/hg-ns1/redis:cl-throttle。dockerd首先會往鏡像服務發送一個請求

registry-crs-huadong1.daliqc.cn/v2/

這個請求都會得到有一個固定的響應碼 401,同時響應頭里面會包含有一個 

Www-Authenticate: Bearer realm="{協議}://registry-crs-huadong1.daliqc.cn/service/token",service="ctyun-container-registry"

第二個接口——service token

通過這個響應頭,就能構造下一個請求,用來獲取bearer token

{協議}://registry-crs-huadong1.daliqc.cn/service/token?service=ctyun-container-registry&scope=repository%3Ahg-ns1%2Fredis%3Apull

這個請求的URL是從v2的響應頭Www-Authenticate獲取到service/token接口的URL,對于queryString部分service=ctyun-container-registry也是在這個頭里面獲取,scope則是docker自己構造,這里做了URL編碼,解開則是

repository:hg-ns1\redis:pull

這三段參數中,repository是固定的,中間hg-ns1\redis是拉取命令中的命名空間和鏡像倉庫,最后一個行為,這里是拉取,是pull,假設是要推送鏡像時,這里就是push。

特別地,如果遇到是往私有倉庫中拉取時,獲取service token需要帶上拉取憑證。這是請求頭會帶上-H"Authorization: Basic xxxxxx",否則得到的響應會說不能匿名拉取。而至于這個Basic Token,就要通過下面命令求出

echo -n "userName:password"|base64

這個得出的basic token就是docker login后,保存到~/.docker/config.json里面的憑證。

拿到的響應體是

{"token":"eyJhbGciOiJSUxxxxxxxxor8bRZjSOW8qRkg","access_token":"","expires_in":43200,"issued_at":"2025-05-11T08:35:17Z"}

其中token這個就是后續請求都要用到的bearer token

第三個接口——manifest

接著按照拿到service token接口拿到的bearer token,會請求manifest接口

registry-crs-huadong1.daliqc.cn/v2/hg-ns1/redis/manifests/cl-throttle

這個接口中/v2/一段是固定的,后面緊跟hg-ns1/redis,是鏡像的命名空間和倉庫名,manifests一段是固定的,最后一段cl-throttle,就是所拉鏡像的tag

請求這個接口時需要帶上bearer token請求頭 -H"Authorization: Bearer xxxx"

然而第一次請求這個接口用的HTTP 方法不是GET,而是HEAD。通過這個HEAD請求的響應頭 Docker-Content-Digest: sha256:ec784d649462697aabf712826fc7b237e0237728d66499adf636520f31aa61ba,dockerd會與本地的倉庫中現存的manifest進行比對,如果已經存在了,就證明這個鏡像已經早就拉取下來,那拉取過程就會結束。當然一般情況下本地沒有的,就會再次請求上面的接口,這次就是用GET請求,而不是用HEAD了,獲取到的響應就是manifest的內容了

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 8189,
      "digest": "sha256:8022c4c620a219fcc91298d084b57cde2b4e37ddd2275e4d94cded74ea51397a"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 27093851,
         "digest": "sha256:b2f14fd03aa1067f4854fa4c791fd5f2550e57085e2b75935bdb538168ff6038"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 1739,
         "digest": "sha256:ee57bca4d6329839cb0c1192b79ff660513c043b0848d35f14ccb8520816a296"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 1357426,
         "digest": "sha256:62a26204ddc975218a0fbe59d8e7531c5f9e585382d902e6739fdcaf25a6ef70"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 7334485,
         "digest": "sha256:e5853dc9148600cfe92484c1a335eac3a472cef69440d27447c98a43f27b3adf"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 97,
         "digest": "sha256:2b69cfbcbf2775f250ef208c2739c2e6ad64392885f89fbde8d67fc4f911dd31"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 409,
         "digest": "sha256:af42f1f6d0f18564ff4c740b11c093482e028a3e2a983fe2a33e674145113610"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 142,
         "digest": "sha256:25a104246c957df5633e68ba9b3b2bb0204e75d9d0de5f1c4abb917f80abe31e"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 18268809,
         "digest": "sha256:dfcf0c5bfc766cc80f6ef5ff3876df4969831c3be122933f8b218300680db6a6"
      }
   ]
}

在這里能得到鏡像config各個層的的信息,這些信息包括mediaType,大小和digest。后面拉取層和config,都是用同一個接口拉取

話說回頭,對于不同客戶端。獲取并構造service/token URL的方式會有不同,像本例子中的docker,就是從/v2/接口開始。而有些客戶端,就是從這個manifest接口開始請求,用這個接口不帶Bearer token請求時,也是得到一個401的響應,而響應頭Www-Authenticate會多了一個scope,此時的service token的scope參數就是按照響應頭生成

Www-Authenticate: Bearer realm="registry-crs-huadong1.daliqc.cn/service/token",service="ctyun-container-registry",scope="repository:hg-ns1/redis:pull"

第四個接口——blob

最后就是獲取各個層和config了,請求的接口都是一個,因為都是把他們當作一個塊進行處理,例如其中一個層的接口如下

registry-crs-huadong1.daliqc.cn/v2/hg-ns1/redis/blobs/sha256:dfcf0c5bfc766cc80f6ef5ff3876df4969831c3be122933f8b218300680db6a6

接口前面幾段與manifest的相似,blobs代表這個是blob接口,最后一段是塊的digest。

與上面的manifest接口請求的時候相似,他先會調用一個HEAD請求,然后才調用GET獲取

這時如果是開啟了對象存儲重定向的,GET請求會收到一個307的響應,響應頭里面會有個Location,這個是一個對象存儲的URL,拉取塊直接從對象存儲拉取,會給拉取過程提速

當然最普通情況下沒開啟對象存儲重定向時,獲取的則是這個塊的內容。有可能是文本,有可能是壓縮的二進制流

各個層就是被這樣一個一個拉下來,直到拉完位置,這個鏡像拉取過程就此結束

0條評論
0 / 1000
h****n
3文章數
0粉絲數
h****n
3 文章 | 0 粉絲
h****n
3文章數
0粉絲數
h****n
3 文章 | 0 粉絲
原創

容器鏡像拉取API接口請求過程解析

2025-07-03 09:49:55
11
0

鏡像(或制品)拉取過程具體細節在不同客戶端會有差異,但整體而言都會遵循v2接口的規范分為下面幾個步驟

1. 去獲取bearer token,這個token在后續的中都需要使用

2. 獲取制品的manifest,

3. 根據獲取到的manifest信息獲取制品元數據config

4. 根據獲取到的manifest信息并行拉取各個層

對于鏡像的客戶端而言,無論他怎么變,都要經過上面幾個過程去完成鏡像拉取。而其他制品的客戶端,差異在第3,第4點。

不同的客戶端,或者同一個類型,不同版本的客戶端,在怎么樣獲取到bearer token的URL,也會有差異,因此這里就用docker作為例子,介紹拉取一個鏡像,會調用什么接口,各個接口的作用是什么。

第一個接口

當通過docker客戶端拉取一個鏡像 docker pull registry-crs-huadong1.daliqc.cn/hg-ns1/redis:cl-throttle。dockerd首先會往鏡像服務發送一個請求

registry-crs-huadong1.daliqc.cn/v2/

這個請求都會得到有一個固定的響應碼 401,同時響應頭里面會包含有一個 

Www-Authenticate: Bearer realm="{協議}://registry-crs-huadong1.daliqc.cn/service/token",service="ctyun-container-registry"

第二個接口——service token

通過這個響應頭,就能構造下一個請求,用來獲取bearer token

{協議}://registry-crs-huadong1.daliqc.cn/service/token?service=ctyun-container-registry&scope=repository%3Ahg-ns1%2Fredis%3Apull

這個請求的URL是從v2的響應頭Www-Authenticate獲取到service/token接口的URL,對于queryString部分service=ctyun-container-registry也是在這個頭里面獲取,scope則是docker自己構造,這里做了URL編碼,解開則是

repository:hg-ns1\redis:pull

這三段參數中,repository是固定的,中間hg-ns1\redis是拉取命令中的命名空間和鏡像倉庫,最后一個行為,這里是拉取,是pull,假設是要推送鏡像時,這里就是push。

特別地,如果遇到是往私有倉庫中拉取時,獲取service token需要帶上拉取憑證。這是請求頭會帶上-H"Authorization: Basic xxxxxx",否則得到的響應會說不能匿名拉取。而至于這個Basic Token,就要通過下面命令求出

echo -n "userName:password"|base64

這個得出的basic token就是docker login后,保存到~/.docker/config.json里面的憑證。

拿到的響應體是

{"token":"eyJhbGciOiJSUxxxxxxxxor8bRZjSOW8qRkg","access_token":"","expires_in":43200,"issued_at":"2025-05-11T08:35:17Z"}

其中token這個就是后續請求都要用到的bearer token

第三個接口——manifest

接著按照拿到service token接口拿到的bearer token,會請求manifest接口

registry-crs-huadong1.daliqc.cn/v2/hg-ns1/redis/manifests/cl-throttle

這個接口中/v2/一段是固定的,后面緊跟hg-ns1/redis,是鏡像的命名空間和倉庫名,manifests一段是固定的,最后一段cl-throttle,就是所拉鏡像的tag

請求這個接口時需要帶上bearer token請求頭 -H"Authorization: Bearer xxxx"

然而第一次請求這個接口用的HTTP 方法不是GET,而是HEAD。通過這個HEAD請求的響應頭 Docker-Content-Digest: sha256:ec784d649462697aabf712826fc7b237e0237728d66499adf636520f31aa61ba,dockerd會與本地的倉庫中現存的manifest進行比對,如果已經存在了,就證明這個鏡像已經早就拉取下來,那拉取過程就會結束。當然一般情況下本地沒有的,就會再次請求上面的接口,這次就是用GET請求,而不是用HEAD了,獲取到的響應就是manifest的內容了

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 8189,
      "digest": "sha256:8022c4c620a219fcc91298d084b57cde2b4e37ddd2275e4d94cded74ea51397a"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 27093851,
         "digest": "sha256:b2f14fd03aa1067f4854fa4c791fd5f2550e57085e2b75935bdb538168ff6038"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 1739,
         "digest": "sha256:ee57bca4d6329839cb0c1192b79ff660513c043b0848d35f14ccb8520816a296"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 1357426,
         "digest": "sha256:62a26204ddc975218a0fbe59d8e7531c5f9e585382d902e6739fdcaf25a6ef70"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 7334485,
         "digest": "sha256:e5853dc9148600cfe92484c1a335eac3a472cef69440d27447c98a43f27b3adf"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 97,
         "digest": "sha256:2b69cfbcbf2775f250ef208c2739c2e6ad64392885f89fbde8d67fc4f911dd31"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 409,
         "digest": "sha256:af42f1f6d0f18564ff4c740b11c093482e028a3e2a983fe2a33e674145113610"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 142,
         "digest": "sha256:25a104246c957df5633e68ba9b3b2bb0204e75d9d0de5f1c4abb917f80abe31e"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 18268809,
         "digest": "sha256:dfcf0c5bfc766cc80f6ef5ff3876df4969831c3be122933f8b218300680db6a6"
      }
   ]
}

在這里能得到鏡像config各個層的的信息,這些信息包括mediaType,大小和digest。后面拉取層和config,都是用同一個接口拉取

話說回頭,對于不同客戶端。獲取并構造service/token URL的方式會有不同,像本例子中的docker,就是從/v2/接口開始。而有些客戶端,就是從這個manifest接口開始請求,用這個接口不帶Bearer token請求時,也是得到一個401的響應,而響應頭Www-Authenticate會多了一個scope,此時的service token的scope參數就是按照響應頭生成

Www-Authenticate: Bearer realm="registry-crs-huadong1.daliqc.cn/service/token",service="ctyun-container-registry",scope="repository:hg-ns1/redis:pull"

第四個接口——blob

最后就是獲取各個層和config了,請求的接口都是一個,因為都是把他們當作一個塊進行處理,例如其中一個層的接口如下

registry-crs-huadong1.daliqc.cn/v2/hg-ns1/redis/blobs/sha256:dfcf0c5bfc766cc80f6ef5ff3876df4969831c3be122933f8b218300680db6a6

接口前面幾段與manifest的相似,blobs代表這個是blob接口,最后一段是塊的digest。

與上面的manifest接口請求的時候相似,他先會調用一個HEAD請求,然后才調用GET獲取

這時如果是開啟了對象存儲重定向的,GET請求會收到一個307的響應,響應頭里面會有個Location,這個是一個對象存儲的URL,拉取塊直接從對象存儲拉取,會給拉取過程提速

當然最普通情況下沒開啟對象存儲重定向時,獲取的則是這個塊的內容。有可能是文本,有可能是壓縮的二進制流

各個層就是被這樣一個一個拉下來,直到拉完位置,這個鏡像拉取過程就此結束

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0