Migrar contentores de um registo de terceiros

Se extrair algumas imagens de contentores diretamente de registos de terceiros para implementar em Google Cloud ambientes como o Google Kubernetes Engine ou o Cloud Run, os limites de taxa nas extrações de imagens ou as indisponibilidades de terceiros podem interromper as suas compilações e implementações. Esta página descreve como identificar e copiar essas imagens para um registo no Google Cloud para uma gestão consolidada e consistente de imagens de contentores.

Além disso, pode tirar partido de outras capacidades, incluindo a proteção da sua cadeia de fornecimento de software com a análise de vulnerabilidades e a aplicação de políticas de implementação com a autorização binária.

Escolher um registo

O Artifact Registry é o serviço recomendado para armazenar e gerir imagens de contentores e outros artefactos de compilação no Google Cloud.

Vista geral da migração

A migração das suas imagens de contentores inclui os seguintes passos:

  1. Configure os pré-requisitos.
  2. Identifique as imagens a migrar.
    • Pesquise referências a registos de terceiros nos seus ficheiros Dockerfile e manifestos de implementação
    • Determine a frequência de obtenção de imagens de registos de terceiros através do Cloud Logging e do BigQuery.
  3. Copie as imagens identificadas para o Container Registry.
  4. Verifique se as autorizações para o registo estão configuradas corretamente, especialmente se o Container Registry e o seu ambiente de implementação estiverem em projetos diferentes. Google Cloud
  5. Atualize os manifestos para as suas implementações.
  6. Volte a implementar as suas cargas de trabalho.
  7. (Opcional) Bloqueie implementações de imagens de origens de terceiros.

O Container Registry não monitoriza registos de terceiros para atualizações de imagens que copia para o Container Registry. Se quiser incorporar uma versão mais recente de uma imagem no seu pipeline, tem de a enviar para o Container Registry.

Antes de começar

  1. Valide as suas autorizações. Tem de ter a função do IAM Proprietário ou Editor nos projetos onde está a migrar imagens para o Container Registry.
  2. Aceda à página do seletor de projetos

    1. Selecione o Google Cloud projeto onde quer usar o Container Registry
    2. Na Google Cloud consola, aceda ao Cloud Shell
    3. Encontre o ID do projeto e defina-o no Cloud Shell. Substitua YOUR_PROJECT_ID pelo ID do seu projeto.

      gcloud config set project YOUR_PROJECT_ID
      
  3. Exporte as seguintes variáveis de ambiente:

      export PROJECT=$(gcloud config get-value project)
    
  4. Ative as APIs BigQuery, Container Registry e Cloud Monitoring com o seguinte comando:

    gcloud services enable \
    containerregistry.googleapis.com \
    stackdriver.googleapis.com \
    logging.googleapis.com \
    monitoring.googleapis.com
    
  5. Verifique se tem a versão 1.13 ou mais recente do Go instalada.

    • Verifique a versão de uma instalação do Go existente com o comando:

      go version
      
    • Se precisar de instalar ou atualizar o Go, consulte a documentação de instalação do Go.

Custos

Este guia usa os seguintes componentes faturáveis do Google Cloud:

Identifique imagens a migrar

Pesquise nos ficheiros que usa para criar e implementar as suas imagens de contentores referências a registos de terceiros e, em seguida, verifique a frequência com que extrai as imagens.

Identifique referências em Dockerfiles

Execute este passo numa localização onde os seus Dockerfiles estão armazenados. É possível que seja aqui que o seu código é verificado localmente ou no Cloud Shell se os ficheiros estiverem disponíveis numa VM.

No diretório com os seus Dockerfiles, execute o comando:

grep -inr -H --include Dockerfile\* "FROM" . | grep -i -v -E 'docker.pkg.dev|gcr.io'

O resultado tem o seguinte aspeto:

./code/build/baseimage/Dockerfile:1:FROM debian:stretch
./code/build/ubuntubase/Dockerfile:1:FROM ubuntu:latest
./code/build/pythonbase/Dockerfile:1:FROM python:3.5-buster

Este comando pesquisa todos os Dockerfiles no seu diretório e identifica a linha "FROM". Ajuste o comando conforme necessário para corresponder à forma como armazena os seus Dockerfiles.

Identifique referências em manifestos

Execute este passo numa localização onde os seus manifestos do GKE ou do Cloud Run estão armazenados. É possível que seja aqui que o código é verificado localmente ou no Cloud Shell se os ficheiros estiverem disponíveis numa VM.

  1. No diretório com os seus manifestos do GKE ou do Cloud Run, execute o comando:

    grep -inr -H --include \*.yaml "image:" . | grep -i -v -E 'docker.pkg.dev|gcr.io'
    

    Exemplo de resultado:

    ./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31.1-uclibc
    ./code/deploy/k8s/master.yaml:26:      image: kubernetes/redis:v1
    

    Este comando analisa todos os ficheiros YAML no seu diretório e identifica a linha image:. Ajuste conforme necessário para funcionar com a forma como os manifestos são armazenados

  2. Para apresentar uma lista de imagens atualmente em execução num cluster, execute o comando:

      kubectl get all --all-namespaces -o yaml | grep image: | grep -i -v -E 'docker.pkg.dev|gcr.io'
    

    Este comando devolve todos os objetos em execução no cluster do Kubernetes atualmente selecionado e obtém os respetivos nomes de imagens.

    Exemplo de resultado:

    - image: nginx
      image: nginx:latest
        - image: nginx
        - image: nginx
    

Execute este comando para todos os clusters do GKE em todos os Google Cloud projetos para uma cobertura total.

Identifique a frequência de obtenção de dados de um registo de terceiros

Em projetos que extraem de registos de terceiros, use informações sobre a frequência de extração de imagens para determinar se a sua utilização está perto ou acima de quaisquer limites de taxa que o registo de terceiros aplique.

Recolha dados de registo

Crie um destino de registos para exportar dados para o BigQuery. Um destino de registos inclui um destino e uma consulta que seleciona as entradas de registo a exportar. Pode criar um destino consultando projetos individuais ou usar um script para recolher dados em vários projetos.

Para criar um destino para um único projeto:

Estas instruções destinam-se à interface de pré-visualização de registo.

  1. Aceda ao Explorador de registos

  2. Escolha um Google Cloud projeto.

  3. No separador Criador de consultas, introduza a seguinte consulta:

      resource.type="k8s_pod"
      jsonPayload.reason="Pulling"
    
  4. Altere o filtro do histórico de alterações de Última hora para Últimos 7 dias.

    imagem

  5. Clique em Executar consulta.

  6. Depois de verificar que os resultados são apresentados corretamente, clique em Ações > Criar destino.

  7. Na lista de destinos, selecione Conjunto de dados do BigQuery e, de seguida, clique em Seguinte.

  8. No painel Editar destino, execute os seguintes passos:

    • No campo Nome do destino, introduza image_pull_logs.
    • No campo Destino de sincronização, crie um novo conjunto de dados ou escolha um conjunto de dados de destino noutro projeto.
  9. Clique em Criar destino.

Para criar um destino para vários projetos:

  1. Abra o Cloud Shell.

  2. Execute os seguintes comandos no Cloud Shell:

    PROJECTS="PROJECT-LIST"
    DESTINATION_PROJECT="DATASET-PROJECT"
    DATASET="DATASET-NAME"
    
    for source_project in $PROJECTS
    do
      gcloud logging --project="${source_project}" sinks create image_pull_logs bigquery.googleapis.com/projects/${DESTINATION_PROJECT}/datasets/${DATASET} --log-filter='resource.type="k8s_pod" jsonPayload.reason="Pulling"'
    done
    

    onde

    • PROJECT-LIST é uma lista de Google Cloud IDs de projetos, separados por espaços. Por exemplo, project1 project2 project3.
    • DATASET-PROJECT é o projeto onde quer armazenar o seu conjunto de dados.
    • DATASET-NAME é o nome do conjunto de dados, por exemplo, image_pull_logs.

Depois de criar um destino, os dados demoram algum tempo a fluir para as tabelas do BigQuery, consoante a frequência com que as imagens são extraídas.

Consulta para a frequência de extração

Assim que tiver uma amostra representativa de obtenções de imagens que as suas compilações fazem, execute uma consulta para a frequência de obtenção.

  1. Aceda à consola do BigQuery.

  2. Execute a seguinte consulta:

    SELECT
      REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
      COUNT(*) AS numberOfPulls
    FROM
          `DATASET-PROJECT.DATASET-NAME.events_*`
    GROUP BY
          imageName
    ORDER BY
          numberOfPulls DESC
    

    onde

    • DATASET-PROJECT é o projeto que contém o seu conjunto de dados.
    • DATASET-NAME é o nome do conjunto de dados.

O exemplo seguinte mostra a saída da consulta. Na coluna imageName, pode rever a frequência de obtenção de imagens que não estão armazenadas no Container Registry nem no Artifact Registry.

imagem

Copie imagens para o Container Registry

Depois de identificar as imagens de registos de terceiros, pode copiá-las para o Container Registry. A ferramenta gcrane ajuda no processo de cópia.

  1. Crie um ficheiro de texto images.txt no Cloud Shell com os nomes das imagens que identificou. Por exemplo:

    ubuntu:18.04
    debian:buster
    hello-world:latest
    redis:buster
    jupyter/tensorflow-notebook
    
  2. Transfira gcrane.

      GO111MODULE=on go get github.com/google/go-containerregistry/cmd/gcrane
    
  3. Crie um script com o nome copy_images.sh para copiar a sua lista de ficheiros.

    #!/bin/bash
    
    images=$(cat images.txt)
    
    if [ -z "${GCR_PROJECT}" ]
    then
        echo ERROR: GCR_PROJECT must be set before running this
        exit 1
    fi
    
    for img in ${images}
    do
        gcrane cp ${img} gcr.io/${GCR_PROJECT}/${img}
    done
    

    Torne o script executável:

      chmod +x copy_images.sh
    
  4. Execute o script para copiar os ficheiros:

    GCR_PROJECT=${PROJECT}
    ./copy_images.sh
    

Valide as autorizações

Por predefinição, Google Cloud os serviços de CI/CD têm acesso ao Container Registry no mesmo Google Cloud projeto.

  • O Cloud Build pode enviar e extrair imagens
  • Os ambientes de tempo de execução, como o GKE, o Cloud Run, o ambiente flexível do App Engine e o Compute Engine, podem extrair imagens.

Se precisar de enviar ou extrair imagens entre projetos, ou se estiver a usar ferramentas de terceiros no seu pipeline que precisam de aceder ao Container Registry, certifique-se de que as autorizações estão configuradas corretamente antes de atualizar e reimplantar as suas cargas de trabalho.

Para mais informações, consulte a documentação sobre o controlo de acesso.

Atualize os manifestos para fazer referência ao Container Registry

Atualize os seus Dockerfiles e manifestos para fazer referência ao Container Registry em vez do registo de terceiros.

O exemplo seguinte mostra um manifesto que faz referência a um registo de terceiros:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Esta versão atualizada do manifesto aponta para a imagem no Container Registry:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: gcr.io/<GCR_PROJECT>/nginx:1.14.2
        ports:
        - containerPort: 80

Para um grande número de manifestos, use o comando sed ou outra ferramenta que possa processar atualizações em vários ficheiros de texto.

Volte a implementar cargas de trabalho

Volte a implementar cargas de trabalho com os manifestos atualizados.

Acompanhe as novas obtenções de imagens executando a seguinte consulta na consola do BigQuery:

SELECT`

FORMAT_TIMESTAMP("%D %R", timestamp) as timeOfImagePull,
REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
COUNT(*) AS numberOfPulls
FROM
  `image_pull_logs.events_*`
GROUP BY
  timeOfImagePull,
  imageName
ORDER BY
  timeOfImagePull DESC,
  numberOfPulls DESC

Todas as novas obtenções de imagens devem ser do Container Registry e conter a string gcr.io.

(Opcional) Bloqueie a obtenção de imagens de registos de terceiros

Para clusters do GKE que usam a autorização binária, a política que define bloqueia automaticamente as obtenções de origens não fidedignas. Certifique-se de que as imagens migradas não são bloqueadas pela política adicionando-as à lista de isenções. Estas instruções descrevem como especificar uma isenção para todas as imagens armazenadas no Container Registry no seu projeto.

Quando atualizar inicialmente a política, considere ativar o modo de teste. Em vez de bloquear imagens, a autorização binária cria entradas de registo de auditoria para que possa identificar imagens pendentes de registos de terceiros que tem de migrar para o Container Registry.

Para mais informações sobre a configuração de políticas de implementação, consulte a documentação da autorização binária.

  1. Aceda à página de autorização binária
  2. Clique em Editar política.
  3. Em Regra predefinida do projeto, ative o Modo de teste.
  4. Em Imagens isentas de regras de implementação, deixe a opção Confiar em todas as imagens do sistema fornecidas pela Google selecionada.
  5. Expanda Caminhos de imagens.
  6. Adicione o caminho para as suas imagens como uma exceção à regra do projeto predefinida:
    1. Na parte inferior da lista de imagens, clique em Adicionar imagens.
    2. Introduza o caminho da imagem para o seu projeto Google Cloud . Por exemplo, gcr.io/my-project/* isenta todas as imagens no projetomy-project.
  7. Repita o passo anterior para outros projetos que contenham imagens que quer implementar.

Reveja os eventos de teste de execução no registo para as suas implementações. Migre as imagens restantes que extrai regularmente de registos de terceiros. Quando todas as imagens forem migradas, pode editar a política para desativar o modo de teste e bloquear imagens de origens não fidedignas.