Identificação automática de imagens de contêineres duplicadas ao migrar para um repositório do Amazon ECR - Recomendações da AWS

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

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.

Manifesto, configuração, camadas do sistema de arquivos e resumos.

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.

Detecção automática de duplicatas com o CodePipeline e o CodeBuild.

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 do GitHub.

Práticas recomendadas

Épicos

TarefaDescriçãoHabilidades necessárias

Extrai uma imagem do repositório público do Amazon ECR.

No terminal, execute o seguinte comando para extrair a imagem amazonlinux do repositório público do Amazon ECR.

$~ % docker pull public.ecr.aws/amazonlinux/amazonlinux:2018.03

Quando a imagem for transferida para sua máquina local, você verá o seguinte resumo, que representa o índice da imagem.

2018.03: Pulling from amazonlinux/amazonlinux 4ddc0f8d367f: Pull complete Digest: sha256:f972d24199508c52de7ad37a298bda35d8a1bd7df158149b381c03f6c6e363b5 Status: Downloaded newer image for public.ecr.aws/amazonlinux/amazonlinux:2018.03 public.ecr.aws/amazonlinux/amazonlinux:2018.03
Desenvolvedor de aplicativos, AWS DevOps, administrador da AWS

Envie a imagem para um repositório privado do Amazon ECR.

  1. Crie um repositório privado do Amazon ECR com o nome test_ecr_repository da região Leste dos EUA (Norte da Virgínia) (us-east-1).

    $~ % aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com Login Succeeded

    onde <account-id> se refere à sua Conta da AWS.

  2. Marque a imagem local que você extraiu anteriormente. Use o valor public.ecr.aws/amazonlinux/amazonlinux:2018.03 e envie-o para o repositório privado do Amazon ECR.

    $~ % docker tag public.ecr.aws/amazonlinux/amazonlinux:2018.03 <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest $~ % docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest

    Quando você envia a imagem para o repositório do Amazon ECR, o Docker envia a imagem subjacente e não o índice da imagem.

    The push refers to repository [<account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository] d5655967c2c4: Pushed latest: digest: sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02 size: 529
Administrador da AWS, profissional de DevOps da AWS, desenvolvedor de aplicações

Extraia a mesma imagem do repositório privado do Amazon ECR.

  1. No terminal, execute o seguinte comando para extrair a imagem que você enviou anteriormente para o repositório privado do Amazon ECR.

    $~ % docker pull <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest latest: Pulling from test_ecr_repository Digest: sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02 Status: Image is up to date for <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest

    O resumo dessa imagem corresponde ao resumo da imagem que você enviou para o repositório privado do Amazon ECR e representa a imagem subjacente. Esse valor não corresponde ao índice de imagens que você extraiu do repositório público.

  2. Para verificar, recupere o índice da imagem por resumo. 

    curl -k -H "Authorization: Bearer $TOKEN" https://public.ecr.aws/v2/amazonlinux/amazonlinux/manifests/sha256:f972d24199508c52de7ad37a298bda35d8a1bd7df158149b381c03f6c6e363b55 { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 529, "digest": "sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02", "platform": { "architecture": "amd64", "os": "linux" } } ] }
Desenvolvedor de aplicativos, AWS DevOps, administrador da AWS
TarefaDescriçãoHabilidades 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 public.ecr.aws/amazonlinux/amazonlinux:2018.03 do repositório público do Amazon ECR.

$~ % docker manifest inspect public.ecr.aws/amazonlinux/amazonlinux:2018.03 { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 529, "digest": "sha256:52db9000073d93b9bdee6a7246a68c35a741aaade05a8f4febba0bf795cdac02", "platform": { "architecture": "amd64", "os": "linux" } } ] }
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 <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest do repositório privado do Amazon ECR.

$~ % docker manifest inspect <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 1477, "digest": "sha256:f7cee5e1af28ad4e147589c474d399b12d9b551ef4c3e11e02d982fce5eebc68" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 62267075, "digest": "sha256:4ddc0f8d367f424871a060e2067749f32bd36a91085e714dcb159952f2d71453" } ] }
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 <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest.

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 config.digest. Isso representa a configuração de imagem que o Docker usa. Então, você poderia dizer que o manifesto é o envelope e a imagem é o conteúdo do envelope. O resumo do manifesto é sempre diferente do ID da imagem. No entanto, um manifesto específico deve sempre produzir o mesmo ID de imagem. Como o resumo do manifesto é uma cadeia de hash, não podemos garantir que sempre será o mesmo para um determinado ID de imagem. Na maioria dos casos, ele produz o mesmo resumo, embora o Docker não possa garantir isso. A possível diferença no resumo do manifesto decorre do fato de o Docker não armazenar localmente os blobs que são compactados com o gzip. Portanto, a exportação de camadas pode produzir um resumo diferente, embora o conteúdo não compactado permaneça o mesmo. O ID da imagem verifica se o conteúdo não compactado é o mesmo; ou seja, o ID da imagem agora é um identificador de conteúdo endereçável (chainID).

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:

  1. Execute o seguinte comando em seu terminal para a imagem armazenada no repositório público do Amazon ECR.

    $~ % docker inspect public.ecr.aws/amazonlinux/amazonlinux:2018.03

    Para obter a saído do comando, consulte a seção Informações adicionais.

  2. Execute o seguinte comando em seu terminal para a imagem armazenada no repositório privado do Amazon ECR.

    $~ % docker inspect <account-id>.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository:latest

    Para obter a saído do comando, consulte a seção Informações adicionais.

Os resultados verificam se as duas imagens têm o mesmo resumo de ID de imagem e resumo de camada.

ID: f7cee5e1af28ad4e147589c474d399b12d9b551ef4c3e11e02d982fce5eebc68

Camadas: d5655967c2c4e8d68f8ec7cf753218938669e6c16ac1324303c073c736a2e2a2

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).

nota

Essa 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
TarefaDescriçãoHabilidades necessárias

Clonar o repositório.

Clone o repositório do Github desse padrão em uma pasta local:

$git clone https://github.com/aws-samples/automated-solution-to-identify-duplicate-container-images-between-repositories
Administrador da AWS, AWS DevOps

Configure um pipeline de CI/CD.

O repositório do GitHub inclui um arquivo .yaml que cria uma pilha CloudFormation para configurar um pipeline AWS CodePipeline.

  1. Faça login no Console de gerenciamento da AWS e abra o console do CloudFormation.

  2. Crie uma pilha usando o pipeline.yaml arquivo de modelo, que está na pasta code no repositório clonado.

  3. Aceite ou altere os valores padrão dos parâmetros. Especifique valores para os seguintes campos:

    • Nome da pilha

    • ArtifactStoreBucketName: um bucket do S3 existente que será usado para armazenar artefatos AWS CodePipeline

    • OutputBucket: um bucket do S3 existente que será usado para armazenar os URIs das imagens duplicadas

    • SourceImageFile: um arquivo de texto existente chamado input.txt que contém os URIs de imagem do repositório público que serão verificados no repositório privado do Amazon ECR para detectar duplicações

  4. Revise e ajuste as opções de pilha e, em seguida, escolha Enviar para executar o modelo.

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:

  • CodePipeline para a orquestração do pipeline de implantação.

  • Um repositório do CodeCommit para armazenar o script bash e o arquivo de entrada. O script bash é usado para comparar os IDs das imagens do contêiner nos repositórios público e privado para encontrar duplicações. Essa verificação é realizada em todos os repositórios na Conta da AWS especificada em uma única Região da AWS.

  • Um projeto do CodeBuild para invocar o script bash para identificar imagens que já estão presentes no repositório do Amazon ECR.

  • Perfils do IAM necessários para permitir o acesso.

  • Um bucket do S3 para armazenar o arquivo de saída que contém URIs de imagem.

  • Outro bucket do S3 para armazenar artefatos do CodePipeline. 

Administrador da AWS, AWS DevOps

Preencha o repositório do CodeCommit.

Para preencher o repositório do CodeCommit, execute estas etapas:

  1. Abra o console do CodeCommit e navegue até Região da AWS onde você criou a pilha do CloudFormation.

  2. Encontre o repositório que você provisionou usando o script do CloudFormation da lista, escolha Clonear URL e copie o protocolo URL HTTPS para se conectar ao repositório.

  3. Abra um prompt de comando e execute o comando git clone com o URL HTTPS que você copiou na etapa anterior.

  4. Navegue até o diretório-raiz. Crie um arquivo chamado input.txt e preencha esse arquivo com os URIs do registro público de imagens do Amazon ECR que você gostaria de pesquisar no repositório privado do Amazon ECR.

  5. Copie os arquivos script.sh, buildspec.yml e input.txt da sua cópia local do repositório do GitHub Automated solution to identify duplicate container images between repositories no repositório clonado do CodeCommit.

  6. Faça upload dos arquivos para o CodeCommit usando estes comandos:

    git add . git commit -m "added input files" git push
Administrador da AWS, AWS DevOps

Limpar.

Para evitar cobranças futuras, exclua os recursos seguindo estas etapas:

  1. Navegue até o bucket do S3 que armazena os artefatos do CodePipeline e esvazie o bucket.

  2. Navegue até o bucket do S3 que armazena os URIs de imagens duplicadas e esvazie o bucket.

  3. Navegue até o console do CloudFormation e exclua a pilha que você criou para configurar o pipeline.

Administrador da AWS

Solução de problemas

ProblemaSoluçã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:

  • Seu computador local está executando um sistema operacional que não oferece suporte ao gerenciamento de credenciais ou não tem um utilitário de gerenciamento de credenciais instalado.

  • As credenciais do Git para seu usuário do IAM não foram salvas em um desses sistemas de gerenciamento de credenciais.

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 na documentação do Git.

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:

  • Você fez a autenticação em outra região. Para obter mais informações, consulte Private registry authentication na documentação do Amazon ECR.

  • Você realizou uma autenticação para enviar por push para um repositório ao qual não tem permissões. Para obter mais informações, consulte Private repository policies na documentação do Amazon ECR.

  • Seu token expirou. O período de expiração padrão dos tokens obtidos com a operação GetAuthorizationToken é de 12 horas.

Recursos relacionados

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" } } ]