Configurar o acesso restrito para clusters particulares do GKE

Neste documento, descrevemos como configurar entradas DNS para encaminhar solicitações aos domínios pkg.dev e gcr.io usando um IP virtual restrito (VIP, na sigla em inglês) ao usar clusters particulares do Google Kubernetes Engine em um perímetro de serviço do VPC Service Controls.

Esses domínios de registro normalmente são resolvidos para um endereço IP público na Internet. Em clusters particulares do GKE, os nós são isolados da Internet por padrão. Isso significa que as solicitações para os registros falharão se você não tiver configurado o roteamento de DNS para o VIP restrito.

Os clusters particulares sempre precisam acessar o Artifact Registry ou o Container Registry com o VIP restrito para evitar a exfiltração de dados de um serviço compatível para um sem suporte.

Essas etapas só serão necessárias se:

  • Você está usando clusters particulares do GKE.
  • Você ainda não configurou o roteamento dos domínios de registro pkg.dev ou gcr.io para restricted.googleapis.com.

Antes de começar

Antes de criar um perímetro de serviço, configure um novo cluster privado ou identifique os clusters particulares atuais que você quer proteger.

Além disso, é preciso permitir a saída para 199.36.153.4/30 na porta 443. Normalmente, uma rede VPC tem uma regra implícita que permite todo o tráfego de saída para qualquer destino. No entanto, se você tiver uma regra que negue esse tráfego, será necessário criar uma regra de firewall de saída para permitir o tráfego TCP na porta 443 para 199.36.153.4/30.

Como configurar DNS

Configure o servidor DNS para que as solicitações aos endereços de registro sejam resolvidas como restricted.googleapis.com, o VIP restrito. É possível fazer isso usando zonas de DNS particular do Cloud DNS.

  1. Criar uma zona particular gerenciada

    gcloud dns managed-zones create ZONE_NAME \
        --visibility=private \
        --networks=https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/NETWORK \
        --description=DESCRIPTION \
        --dns-name=REGISTRY_DOMAIN \
        --project=PROJECT_ID
    

    Em que:

    • ZONE_NAME é um nome para a zona que você está criando. Por exemplo, registry; Esse nome será usado em cada uma das etapas a seguir.

    • PROJECT_ID é o código do projeto que hospeda seu cluster particular do GKE.

    • NETWORK é uma lista opcional de nomes da rede de clusters de que você quer redirecionar solicitações.

    • DESCRIPTION é uma descrição legível da zona gerenciada.

    • REGISTRY_DOMAIN é o domínio do registro:

      • pkg.dev para o Artifact Registry
      • gcr.io para Container Registry ou repositórios gcr.io hospedados no Artifact Registry
  2. Inicie uma transação.

    gcloud dns record-sets transaction start \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    Em que:

    • ZONE_NAME é o nome da zona que você criou na primeira etapa.

    • PROJECT_ID é o código do projeto que hospeda seu cluster particular do GKE.

  3. Adicione um registro CNAME ao seu registro.

    gcloud dns record-sets transaction add \
      --name=*.REGISTRY_DOMAIN. \
      --type=CNAME REGISTRY_DOMAIN. \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    Em que:

    • ZONE_NAME é o nome da zona que você criou na primeira etapa.

    • PROJECT_ID é o código do projeto que hospeda seu cluster particular do GKE.

    • REGISTRY_DOMAIN é o domínio do registro:

      • pkg.dev para o Artifact Registry
      • gcr.io para Container Registry ou repositórios gcr.io hospedados no Artifact Registry
  4. Adicione um registro A ao VIP restrito.

    gcloud dns record-sets transaction add \
      --name=REGISTRY_DOMAIN. \
      --type=A 199.36.153.4 199.36.153.5 199.36.153.6 199.36.153.7 \
      --zone=ZONE_NAME \
      --ttl=300 \
      --project=PROJECT_ID
    

    Em que:

    • ZONE_NAME é o nome da zona que você criou na primeira etapa.

    • PROJECT_ID é o código do projeto que hospeda seu cluster particular do GKE.

    • REGISTRY_DOMAIN é o domínio do registro:

      • pkg.dev para o Artifact Registry
      • gcr.io para Container Registry ou repositórios gcr.io hospedados no Artifact Registry
  5. Execute a transação.

    gcloud dns record-sets transaction execute \
      --zone=ZONE_NAME \
      --project=PROJECT_ID
    

    Em que:

    • ZONE_NAME é o nome da zona que você criou na primeira etapa.

    • PROJECT_ID é o código do projeto que hospeda seu cluster particular do GKE.

Depois de configurar o roteamento de DNS, verifique se o GKE, o registro e outros serviços necessários estão dentro do perímetro de serviço do VPC Service Controls. Para configurar o perímetro de serviço, consulte a seção a seguir.

Como configurar o perímetro de serviço

Depois de configurar os registros DNS, crie um novo perímetro de serviço ou atualize um perímetro atual e adicione o serviço Container Registry ou Artifact Registry à lista de serviços que você quer proteger usando o perímetro de serviço.

Além disso:

  • Adicione outros serviços compatíveis usados com o registro ao perímetro de serviço, como Cloud Build, Artifact Analysis e autorização binária.
  • Para o Container Registry, também é preciso adicionar o Cloud Storage ao perímetro de serviço.

Como verificar se o perímetro funciona

Depois de configurar o perímetro de serviço, os nós nos clusters particulares do GKE poderão acessar imagens de contêiner no Artifact Registry e no Container Registry se as imagens estiverem armazenadas em projetos que estejam no perímetro de serviço.

As imagens de contêiner em projetos fora do perímetro permanecem inacessíveis, exceto em alguns repositórios públicos somente leitura específicos.

Por exemplo, se o projeto google-samples não estiver no perímetro de serviço, a execução do comando para criar uma implantação do contêiner hello-app falhará:

Domínio pkg.dev

kubectl create deployment hello-server --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

Domínio gcr.io

kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0

Verifique o status do pod com o comando:

kubectl get pods

O comando retorna uma tabela semelhante ao exemplo a seguir. O status do pod ErrImagePull indica que o pull falhou.

NAME                            READY   STATUS         RESTARTS   AGE
hello-server-dbd86c8c4-h5wsf    1/1     ErrImagePull   0          45s

Use o comando kubectl describe pod para ver mais detalhes sobre a implantação. Para o pod no exemplo anterior, o comando é:

kubectl describe pod hello-server-dbd86c8c4-h5wsf