本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
移轉至 Amazon ECR 儲存庫時,自動識別重複的容器映像
由里沙巴亞達夫(AWS)和里希辛格拉(AWS)創建
代碼存儲庫:automated-solution-to-identify--容identical-images-between-various器 | 環境:生產 | 技術:容器與微服務;遷移 DevOps;現代化 |
AWS 服務:AWS CodeBuild; AWS CodePipeline; Amazon ECR; AWS CodeCommit |
Summary
該模式提供了一種自動化的解決方案,以識別存儲在不同容器存儲庫中的映像是否重複。當您計劃將映像從其他容器儲存庫遷移到 Amazon 彈性容器登錄 (Amazon ECR) 時,此檢查非常有用。
如需基礎資訊,此模式也會描述容器映像檔的元件,例如映像摘要、資訊清單和標籤。當您計劃遷移至 Amazon ECR 時,您可能會決定透過比較映像的摘要,在容器登錄之間同步容器映像。在遷移容器映像之前,您需要檢查這些映像是否已存在於 Amazon ECR 儲存庫中,以防止重複。不過,比較影像摘要可能很難偵測重複資料,這可能會導致初始移轉階段發生問題。 此模式會比較儲存在不同容器登錄中的兩個相似影像的摘要,並說明摘要為何不同,以協助您準確比較影像。
先決條件和限制
一個活躍的 AWS 帳戶
訪問 Amazon ECR 公共註冊
表 熟悉以下內容: AWS 服務
設定的 CodeCommit 認證 (請參閱指示)
架構
容器映像元件
下圖說明一些容器映像檔的元件。這些組件在圖之後進行描述。
![資訊清單、組態、檔案系統層和摘要。](images/pattern-img/7db5020c-6f5b-4e91-b91a-5b8ae844be1b/images/71b99c67-a934-4f94-8af8-2a8431fb91f5.png)
術語和定義
下列術語定義於「開放容器倡議 (OCI) 影像規格
登錄:用於影像儲存和管理的服務。
用戶端:與登錄通訊並與本機映像搭配使用的工具。
推送:將影像上傳至登錄的程序。
拉:從註冊表下載圖像的過程。
Blob:登錄所儲存的二進位內容格式,可透過摘要加以處理。
索引:識別不同電腦平台 (例如 x86-64 或 ARM 64 位元) 或媒體類型的多重影像資訊清單的建構。如需詳細資訊,請參閱 OCI 影像索引規格
。 資訊清單:定義透過資訊清單端點上傳的影像或成品的 JSON 文件。清單可以通過使用描述符引用存儲庫中的其他斑點。如需詳細資訊,請參閱 OCI 映像資訊清單規格
。 文件系統層:系統庫和圖像的其他依賴項。
組態:包含成品中繼資料且在資訊清單中參照的 Blob。如需詳細資訊,請參閱 OCI 映像組態規格
。 物件或成品:儲存為 blob 並與配置的隨附資訊清單相關聯的概念性內容項目。
摘要:從資訊清單內容的加密雜湊建立的唯一識別碼。圖像摘要有助於唯一識別不可變的容器映像。使用摘要提取映像檔時,每次在任何作業系統或架構上都會下載相同的映像檔。如需詳細資訊,請參閱 OCI 影像規格
。 標籤:一個人類可讀的清單標識符。與不可變的圖像摘要相比,標籤是動態的。雖然底層影像摘要保持不變,但指向影像的標記可能會從一個影像變更並移動到另一個影像。
目標架構
下圖顯示此模式提供的解決方案的高階架構,可透過比較儲存在 Amazon ECR 和私有存放庫中的映像來識別重複的容器映像。
![使用 CodePipeline 和自動偵測重複項目 CodeBuild。](images/pattern-img/7db5020c-6f5b-4e91-b91a-5b8ae844be1b/images/5ee62bc8-db8d-48a3-9e79-f3392b6e9bf7.png)
工具
AWS 服務
AWS CloudFormation協助您設定 AWS 資源、快速且一致地佈建資源,以及跨區域的整個生命週期進 AWS 帳戶 行管理。
AWS CodeBuild是完全受控的建置服務,可協助您編譯原始程式碼、執行單元測試,以及產生準備好部署的成品。
AWS CodeCommit是一項版本控制服務,可協助您私下儲存和管理 Git 儲存庫,而無需管理您自己的原始檔控制系統。
AWS CodePipeline協助您快速建模和設定軟體發行版本的不同階段,並自動執行持續發行軟體變更所需的步驟。
Amazon Elastic Container Registry (Amazon ECR) 是安全、可擴展且可靠的受管容器映像登錄服務。
代碼
此模式的程式碼可在儲 GitHub 存庫自動化解決方案中找到,以識別儲存庫之間的重複容器映像
最佳實務
史诗
任務 | 描述 | 所需技能 |
---|---|---|
從 Amazon ECR 公共存儲庫提取映像。 | 從終端機執行下列命令,
當圖像被拉到你的本地機器,你會看到下面的 pull 摘要,它代表圖像索引。
| 應用程式開發人員、AWS DevOps、AWS 管理員 |
將映像推送至 Amazon ECR 私有儲存庫。 |
| AWS 管理員、AWS DevOps、應用程式開發人員 |
從 Amazon ECR 私有存儲庫中提取相同的映像。 |
| 應用程式開發人員、AWS DevOps、AWS 管理員 |
任務 | 描述 | 所需技能 |
---|---|---|
尋找儲存在 Amazon ECR 公用儲存庫中的映像資訊清單。 | 從終端機執行下列命令,從 Amazon ECR 公用存放庫提
| AWS 管理員、AWS DevOps、應用程式開發人員 |
尋找儲存在 Amazon ECR 私有儲存庫中的映像資訊清單。 | 從終端機執行下列命令,從 Amazon ECR 私有存放庫提
| AWS DevOps、AWS 系統管理員、應用程式開發人員 |
將 Docker 提取的摘要與 Amazon ECR 私有儲存庫中映像的資訊清單摘要進行比較。 | 另一個問題是為什麼 docker pull 命令提供的摘要與圖像 用於 docker 拉的摘要表示存儲在註冊表中的圖像清單的摘要。此摘要被視為雜湊鏈的根目錄,因為資訊清單包含將下載並匯入到 Docker 的內容的雜湊。 在 Docker 中使用的圖像 ID 可以在此清單中找到。 若要確認此資訊,您可以比較 Amazon ECR 公有和私有儲存庫上的泊塢視窗檢查命令的輸出: 結果會驗證兩個影像具有相同的影像 ID 摘要和圖層摘要。 識別碼: 圖層: 此外,摘要是根據本機管理的物件位元組 (本機檔案是容器映像層的 tar),或是推送至登錄伺服器的 blob。但是,當您將 blob 推送到註冊表時,tar 會壓縮並在壓縮的 tar 文件中計算摘要。因此,docker 提取摘要值的差異來自於在登錄 (Amazon ECR 私有或公用) 層級套用的壓縮。 注意:此解釋特定於使用 Docker 客戶端。您不會在 nerdctl 或 Fch 等其他用戶端上看到這種行為,因為它們不會在推送和拉取作業期間自動壓縮影像。 | AWS DevOps、AWS 系統管理員、應用程式開發人員 |
任務 | 描述 | 所需技能 |
---|---|---|
複製儲存庫。 | 將此模式的 Github 存儲庫克隆到本地文件夾中:
| AWS 管理員,AWS DevOps |
設定 CI/CD 管線。 | GitHub 存放庫包含一個
管道將設定為兩個階段 (CodeCommit 和 CodeBuild,如架構圖所示),以識別私有存放庫中也存在於公用存放庫中的映像檔。管線配置為下列資源:
| AWS 管理員,AWS DevOps |
填入存 CodeCommit 放庫。 | 若要填入 CodeCommit 存放庫,請執行下列步驟:
| AWS 管理員,AWS DevOps |
清除。 | 若要避免 future 產生費用,請依照下列步驟刪除資源:
| AWS 管理員 |
故障診斷
問題 | 解決方案 |
---|---|
當您嘗試從終端機或命令列推送、提取或與 CodeCommit 儲存庫互動時,系統會提示您提供使用者名稱和密碼,而且您必須提供 IAM 使用者的 Git 認證。 | 此錯誤的最常見原因如下:
根據作業系統和本機環境,您可能需要安裝登入資料管理工具、設定作業系統中包含的登入資料管理工具,或自訂本機環境以使用登入資料儲存體。例如,如果您的電腦執行 macOS,您可以使用「鑰匙圈存取」公用程式來儲存您的認證。如果您的電腦執行 Windows,您可以使用隨著適用於 Windows 的 Git 安裝的 Credential Manager。如需詳細資訊,請參閱 CodeCommit 說明文件中的使用 Git 認證的 HTTPS 使用者設定和 Git 說明文件中的認證儲存 |
將映像推送到 Amazon ECR 存放庫時,您遇到 HTTP 403 或「沒有基本身份驗證登入資料」錯誤。 | 即使您已經使用 aws ecr 命令成功對 docker 進行身份驗證,您也可能會遇到來自泊塢窗推送或碼頭提取命令的這些錯誤消息。 get-login-password已知的原因是: |
相關資源
Amazon ECR 中的私人映像檔 (Amazon ECR 文件)
AWS::CodePipeline::Pipeline 資源 (AWS CloudFormation 文件)
其他資訊
在 Amazon ECR 公共存儲庫中輸出圖像的碼頭檢查
[ { "Id": "sha256:f7cee5e1af28ad4e147589c474d399b12d9b551ef4c3e11e02d982fce5eebc68", "RepoTags": [ "<account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest", "public.ecr.aws/amazonlinux/amazonlinux:2018.03" ], "RepoDigests": [ "<account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository@sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02", "public.ecr.aws/amazonlinux/amazonlinux@sha256:f972d24199508c52de7ad37a298bda35d8a1bd7df158149b381c03f6c6e363b5" ], "Parent": "", "Comment": "", "Created": "2023-02-23T06:20:11.575053226Z", "Container": "ec7f2fc7d2b6a382384061247ef603e7d647d65f5cd4fa397a3ccbba9278367c", "ContainerConfig": { "Hostname": "ec7f2fc7d2b6", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/bash\"]" ], "Image": "sha256:c1bced1b5a65681e1e0e52d0a6ad17aaf76606149492ca0bf519a466ecb21e51", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": {} }, "DockerVersion": "20.10.17", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "sha256:c1bced1b5a65681e1e0e52d0a6ad17aaf76606149492ca0bf519a466ecb21e51", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": null }, "Architecture": "amd64", "Os": "linux", "Size": 167436755, "VirtualSize": 167436755, "GraphDriver": { "Data": { "MergedDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/merged", "UpperDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/diff", "WorkDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:d5655967c2c4e8d68f8ec7cf753218938669e6c16ac1324303c073c736a2e2a2" ] }, "Metadata": { "LastTagTime": "2023-03-02T10:28:47.142155987Z" } } ]
在 Amazon ECR 私有存儲庫中輸出圖像的碼頭檢查
[ { "Id": "sha256:f7cee5e1af28ad4e147589c474d399b12d9b551ef4c3e11e02d982fce5eebc68", "RepoTags": [ "<account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest", "public.ecr.aws/amazonlinux/amazonlinux:2018.03" ], "RepoDigests": [ "<account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository@sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02", "public.ecr.aws/amazonlinux/amazonlinux@sha256:f972d24199508c52de7ad37a298bda35d8a1bd7df158149b381c03f6c6e363b5" ], "Parent": "", "Comment": "", "Created": "2023-02-23T06:20:11.575053226Z", "Container": "ec7f2fc7d2b6a382384061247ef603e7d647d65f5cd4fa397a3ccbba9278367c", "ContainerConfig": { "Hostname": "ec7f2fc7d2b6", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/bash\"]" ], "Image": "sha256:c1bced1b5a65681e1e0e52d0a6ad17aaf76606149492ca0bf519a466ecb21e51", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": {} }, "DockerVersion": "20.10.17", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "sha256:c1bced1b5a65681e1e0e52d0a6ad17aaf76606149492ca0bf519a466ecb21e51", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": null }, "Architecture": "amd64", "Os": "linux", "Size": 167436755, "VirtualSize": 167436755, "GraphDriver": { "Data": { "MergedDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/merged", "UpperDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/diff", "WorkDir": "/var/lib/docker/overlay2/c2c2351a82b26cbdf7782507500e5adb5c2b3a2875bdbba79788a4b27cd6a913/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:d5655967c2c4e8d68f8ec7cf753218938669e6c16ac1324303c073c736a2e2a2" ] }, "Metadata": { "LastTagTime": "2023-03-02T10:28:47.142155987Z" } } ]