Identificação automática de imagens de contêineres duplicadas ao migrar para um repositório do Amazon ECR
Rishabh Yadav e Rishi Singla, Amazon Web Services
Resumo
Aviso: o AWS CodeCommit não está mais disponível para novos clientes. Os clientes atuais do AWS CodeCommit podem continuar usando o serviço normalmente. Saiba mais
O padrão fornece uma solução automatizada para identificar se as imagens armazenadas em diferentes repositórios de contêineres são duplicadas. Essa verificação é útil quando você planeja migrar imagens de outros repositórios de contêiner para o Amazon Elastic Container Registry (Amazon ECR).
Para obter informações básicas, o padrão também descreve os componentes de uma imagem de contêiner, como o resumo da imagem, o manifesto e as marcações. Ao planejar uma migração para o Amazon ECR, você pode decidir sincronizar suas imagens de contêiner em todos os registros de contêineres comparando os resumos das imagens. Antes de migrar suas imagens de contêiner, você precisa verificar se essas imagens já existem no repositório do Amazon ECR para evitar duplicações. No entanto, pode ser difícil detectar duplicações comparando resumos de imagens, o que pode causar problemas na fase inicial de migração. Este padrão compara os resumos de duas imagens semelhantes que estão armazenadas em diferentes registros de contêineres e explica por que os resumos variam, para ajudar você a comparar imagens com precisão.
Pré-requisitos e limitações
Uma Conta da AWS ativa
Acesso ao registro público do Amazon ECR
Familiaridade com o seguinte Serviços da AWS:
Credenciais do CodeCommit configuradas (consulte as instruções)
Arquitetura
Componentes de imagem de contêiner
O diagrama a seguir ilustra alguns dos componentes de uma imagem de contêiner. Esses componentes são descritos após o diagrama.

Termos e definições
Os termos a seguir são definidos na Open Container Initiative (OCI) Image Specification
Registro: um serviço para armazenamento e gerenciamento de imagens.
Cliente: uma ferramenta que se comunica com registros e trabalha com imagens locais.
Push: o processo de upload de imagens para um registro.
Pull: o processo para baixar imagens de um registro.
Blob: a forma binária de conteúdo que é armazenada por um registro e pode ser tratada por um resumo.
Índice: um constructo que identifica vários manifestos de imagem para diferentes plataformas de computador (como x86-64 ou ARM de 64 bits) ou tipos de mídia. Para obter mais informações, consulte a OCI Image Index Specification
. Manifesto: um documento JSON que define uma imagem ou artefato que é carregado por meio do endpoint do manifesto. Um manifesto pode fazer referência a outros blobs em um repositório usando descritores. Para obter mais informações, consulte a OCI Image Manifest Specification
. Camada do sistema de arquivos: bibliotecas do sistema e outras dependências de uma imagem.
Configuração: um blob que contém metadados de artefatos e é referenciado no manifesto. Para obter mais informações, consulte a OCI Image Configuration Specification
. Objeto ou artefato: um item de conteúdo conceitual armazenado como um blob e associado a um manifesto anexo com uma configuração.
Digest: um identificador exclusivo criado com base em um hash criptográfico do conteúdo de um manifesto. O resumo da imagem ajuda a identificar de forma exclusiva uma imagem de contêiner imutável. Ao extrair uma imagem usando seu resumo, você baixará a mesma imagem todas as vezes em qualquer sistema operacional ou arquitetura. Para obter mais informações, consulte a OCI Image Specification
. Tag: um identificador de manifesto legível por humanos. Em comparação com os resumos de imagens, que são imutáveis, as marcações são dinâmicas. Uma marcação que aponta para uma imagem pode mudar e passar de uma imagem para outra, embora o resumo da imagem subjacente permaneça o mesmo.
Arquitetura de destino
O diagrama a seguir mostra a arquitetura de alto nível da solução fornecida por esse padrão para identificar imagens de contêineres duplicadas comparando imagens armazenadas no Amazon ECR e em repositórios privados.

Ferramentas
Serviços da AWS
O CloudFormation ajuda a configurar recursos da AWS, provisioná-los de forma rápida e consistente e gerenciá-los durante todo o ciclo de vida em todas as regiões e Contas da AWS.
O AWS CodeBuild é um serviço de compilação totalmente gerenciado que permite compilar o código-fonte, realizar testes de unidade e produzir artefatos preparados para a implantação.
O AWS CodeCommit é um serviço de controle de versão que ajuda no armazenamento e no gerenciamento de repositórios Git de forma privada, sem a necessidade de administrar o próprio sistema de controle de origem.
O AWS CodePipeline ajuda você a modelar e configurar rapidamente os diferentes estágios de uma versão de software, além de automatizar as etapas necessárias para a implantação contínua de alterações.
O Amazon Elastic Container Registry (Amazon ECR) é um serviço gerenciado de registro de imagens de contêineres seguro, escalável e confiável.
Código da
O código para este padrão está disponível no repositório Automated solution to identify duplicate container images between repositories
Práticas recomendadas
Épicos
| Tarefa | Descrição | Habilidades necessárias |
|---|---|---|
Extrai uma imagem do repositório público do Amazon ECR. | No terminal, execute o seguinte comando para extrair a imagem
Quando a imagem for transferida para sua máquina local, você verá o seguinte resumo, que representa o índice da imagem.
| Desenvolvedor de aplicativos, AWS DevOps, administrador da AWS |
Envie a imagem para um repositório privado do Amazon ECR. |
| Administrador da AWS, profissional de DevOps da AWS, desenvolvedor de aplicações |
Extraia a mesma imagem do repositório privado do Amazon ECR. |
| Desenvolvedor de aplicativos, AWS DevOps, administrador da AWS |
| Tarefa | Descrição | Habilidades necessárias |
|---|---|---|
Encontre o manifesto da imagem armazenada no repositório público do Amazon ECR. | No terminal, execute o seguinte comando para extrair o manifesto da imagem
| Administrador da AWS, profissional de DevOps da AWS, desenvolvedor de aplicações |
Encontre o manifesto da imagem armazenada no repositório privado do Amazon ECR. | No terminal, execute o seguinte comando para extrair o manifesto da imagem
| AWS DevOps, administrador de sistemas da AWS, desenvolvedor de aplicativos |
Compare o resumo obtido pelo Docker com o resumo do manifesto da imagem no repositório privado do Amazon ECR. | Outra questão é por que o resumo fornecido pelo comando docker pull difere do resumo do manifesto para a imagem O resumo usado para docker pull representa o resumo do manifesto da imagem, que é armazenado em um registro. Esse resumo é considerado a raiz de uma cadeia de hash, porque o manifesto contém o hash do conteúdo que será baixado e importado para o Docker. O ID da imagem usado no Docker pode ser encontrado neste manifesto como Para confirmar essas informações, você pode comparar a saída do comando docker inspect nos repositórios públicos e privados do Amazon ECR:
Os resultados verificam se as duas imagens têm o mesmo resumo de ID de imagem e resumo de camada. ID: Camadas: Além disso, os resumos são baseados nos bytes do objeto gerenciado localmente (o arquivo local é um tar da camada de imagem do contêiner) ou no blob enviado ao servidor de registro. No entanto, quando você envia o blob para um registro, o tar é compactado e o resumo é computado no arquivo tar compactado. Portanto, a diferença no valor do resumo do docker pull surge da compactação aplicada no nível do registro (Amazon ECR privado ou público). notaEssa explicação é específica para o uso de um cliente Docker. Você não verá esse comportamento com outros clientes, como nerdctl ou Finch, porque eles não compactam automaticamente a imagem durante as operações de push e pull. | AWS DevOps, administrador de sistemas da AWS, desenvolvedor de aplicativos |
| Tarefa | Descrição | Habilidades necessárias |
|---|---|---|
Clonar o repositório. | Clone o repositório do Github desse padrão em uma pasta local:
| Administrador da AWS, AWS DevOps |
Configure um pipeline de CI/CD. | O repositório do GitHub inclui um arquivo
O pipeline será configurado com dois estágios (CodeCommit e CodeBuild, conforme mostrado no diagrama da arquitetura) para identificar imagens no repositório privado que também existem no repositório público. O pipeline é configurado com os seguintes recursos:
| Administrador da AWS, AWS DevOps |
Preencha o repositório do CodeCommit. | Para preencher o repositório do CodeCommit, execute estas etapas:
| Administrador da AWS, AWS DevOps |
Limpar. | Para evitar cobranças futuras, exclua os recursos seguindo estas etapas:
| Administrador da AWS |
Solução de problemas
| Problema | Solução |
|---|---|
Quando você tenta enviar, extrair ou interagir de qualquer modo com o repositório do CodeCommit de um terminal ou uma linha de comando, um nome de usuário e senha são solicitados, além das credenciais do Git do seu usuário do IAM. | As causas comuns para esse erro são as seguintes:
Dependendo de seu sistema operacional e ambiente local, talvez seja necessário instalar um gerenciador de credenciais, configurar o gerenciador de credenciais incluído no sistema operacional ou personalizar o ambiente local para usar o armazenamento de credenciais. Por exemplo, se seu computador estiver executando o macOS, você pode usar o utilitário Acesso às Chaves para armazenar suas credenciais. Se seu computador for Windows, você pode usar o Git Credential Manager que é instalado com o Git para Windows. Para obter mais informações, consulte Setup for HTTPS users using Git credentials na documentação do CodeCommit e Credential Storage |
Você encontra erros de HTTP 403 ou “sem credenciais básicas de autenticação” ao enviar uma imagem para o repositório do Amazon ECR. | Você pode encontrar essas mensagens de erro do comando docker push ou docker pull, mesmo que tenha se autenticado com sucesso no Docker usando o comando aws ecr get-login-password. As causas conhecidas são:
|
Recursos relacionados
Automated solution to identify duplicate container images between repositories
(repositório do GitHub) Private images in Amazon ECR (documentação do Amazon ECR)
AWS::CodePipeline::Pipeline resource (documentação do CloudFormation)
Mais informações
Saída da inspeção Docker para imagem no repositório público do 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" } } ]
Saída da inspeção do Docker para imagem no repositório privado do 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" } } ]