Como criar clusters privados do GKE usando proxies de rede para acesso ao controlador

Last reviewed 2019-07-02 UTC

Ao criar um cluster privado do GKE com um endpoint de controlador de cluster particular, o nó do controlador do cluster fica inacessível na Internet pública, mas precisa estar acessível para administração.

Por padrão, os clusters podem acessar o controlador por meio do endpoint particular e é possível definir redes autorizadas na VPC.

No entanto, para acessar o controlador a partir da rede local ou de outra rede VPC, é necessário realizar outras etapas. Isso ocorre porque a rede VPC que hospeda o controlador é de propriedade do Google e não pode ser acessada de recursos conectados por meio de outra conexão de peering de rede VPC, Cloud VPN ou Cloud Interconnect.

Para acessar o controlador no local ou em outra rede VPC conectada pelo Cloud VPN ou pelo Cloud Interconnect, ative a exportação de rota da sua rede VPC para a VPC do Google.

Para permitir o acesso ao controlador a partir de outra rede VPC ou de uma rede local conectada por outro peering de rede VPC, como projetos hub e spoke, crie um proxy hospedado no espaço de endereços IP autorizados, já que o peering de rede VPC é intransitivo.

Neste tutorial, você aprenderá a configurar esse proxy no cluster privado do GKE.

Objetivos

  • Criar um cluster privado do GKE sem acesso externo.
  • Criar e implantar uma imagem do Docker para executar o proxy.
  • Criar um serviço Kubernetes para acessar o proxy.
  • Testar o acesso ao proxy.

Custos

Neste tutorial, há componentes faturáveis do Google Cloud Platform, entre eles:

Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  4. Ative as APIs Compute Engine and Google Kubernetes Engine.

    Ative as APIs

  5. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  6. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  7. Ative as APIs Compute Engine and Google Kubernetes Engine.

    Ative as APIs

Como configurar o ambiente

Neste tutorial, use o Cloud Shell para inserir comandos. O Cloud Shell fornece acesso à linha de comando no Console do Cloud e inclui a Google Cloud CLI e outras ferramentas que precisam ser desenvolvidas no Google Cloud. O Cloud Shell aparece como uma janela na parte inferior do Console do Google Cloud. A inicialização leva vários minutos, mas a janela aparece imediatamente.

Siga estes passos para configurar o ambiente usando o Cloud Shell:

  1. No Console do Google Cloud, abra o Cloud Shell.

    ABRIR o Cloud Shell

  2. Verifique se você está trabalhando no projeto criado ou selecionado. Substitua o [YOUR_PROJECT_ID] pelo projeto do Google Cloud.

    gcloud config set project [YOUR_PROJECT_ID]
    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  3. Defina a zona do Compute padrão. Para os fins deste tutorial, use us-central1-c. Se você estiver implantando em um ambiente de produção, faça isso em uma região de sua escolha.

    gcloud config set compute/region us-central1
    gcloud config set compute/zone us-central1-c
    export REGION=us-central1
    export ZONE=us-central1-c
    
    

Como criar uma rede VPC e uma VM cliente

Crie uma rede e uma sub-rede VPC para hospedar os recursos.

  1. Crie uma rede VPC:

    gcloud compute networks create k8s-proxy --subnet-mode=custom
    
  2. Crie uma sub-rede personalizada na rede VPC recém-criada:

    gcloud compute networks subnets create subnet-cluster \
        --network=k8s-proxy --range=10.50.0.0/16
    
  3. Crie uma VM cliente que você usará para implantar recursos no cluster do Kubernetes:

    gcloud compute instances create --subnet=subnet-cluster \
        --scopes cloud-platform proxy-temp
    
  4. Salve o endereço IP interno da instância recém-criada em uma variável de ambiente:

    export CLIENT_IP=`gcloud compute instances describe proxy-temp \
        --format="value(networkInterfaces[0].networkIP)"`
    
  5. Crie uma regra de firewall para permitir o acesso SSH à rede VPC:

    gcloud compute firewall-rules create k8s-proxy-ssh --network k8s-proxy \
        --allow tcp:22
    

Como criar um cluster particular

Agora, crie um cluster particular para usar neste tutorial.

Se você já tiver um cluster de sua preferência, poderá ignorar a etapa de criação, mas terá que configurar alguma maneira inicial de acesso na máquina cliente.

  • No Cloud Shell, crie um cluster:

    gcloud container clusters create frobnitz  \
        --master-ipv4-cidr=172.16.0.64/28 \
        --network k8s-proxy \
        --subnetwork=subnet-cluster \
        --enable-ip-alias \
        --enable-private-nodes \
        --enable-private-endpoint \
        --master-authorized-networks $CLIENT_IP/32 \
        --enable-master-authorized-networks
    

    O comando cria um cluster particular do GKE chamado frobnitz com master-authorized-networks definido para permitir que apenas a máquina do cliente tenha acesso.

Como criar a imagem do Docker

Use os passos a seguir para criar uma imagem de proxy chamada k8s-api-proxy, da API do Kubernetes. A imagem atua como um proxy de encaminhamento para o servidor dessa API.

  1. No Cloud Shell, crie um diretório e mude para ele:

    mkdir k8s-api-proxy && cd k8s-api-proxy
  2. Crie o Dockerfile. A configuração a seguir cria um contêiner do Alpine (em inglês), que é uma distribuição de contêineres leve com um proxy Privoxy. O Dockerfile também instala curl e jq para a inicialização do contêiner, adiciona os arquivos de configuração necessários, expõe a porta 8118 para o GKE internamente e acrescenta um script de inicialização.

    FROM alpine
    RUN apk add -U curl privoxy jq && \ mv /etc/privoxy/templates /etc/privoxy-templates && \ rm -rf /var/cache/apk/* /etc/privoxy/* && \ mv /etc/privoxy-templates /etc/privoxy/templates ADD --chown=privoxy:privoxy config \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-only.action \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-rewrite-internal.filter \ /etc/privoxy/ ADD k8s-api-proxy.sh /
    EXPOSE 8118/tcp
    ENTRYPOINT ["./k8s-api-proxy.sh"]
  3. No diretório k8s-api-proxy, crie o arquivo config e adicione o seguinte conteúdo a ele:

    #config directory
    confdir /etc/privoxy
    # Allow Kubernetes API access only
    actionsfile /etc/privoxy/k8s-only.action
    # Rewrite https://CLUSTER_IP to https://kubernetes.default
    filterfile /etc/privoxy/k8s-rewrite-internal.filter
    # Don't show the pod name in errors
    hostname k8s-privoxy
    # Bind to all interfaces, port :8118
    listen-address  :8118
    # User cannot click-through a block
    enforce-blocks 1
    # Allow more than one outbound connection
    tolerate-pipelining 1
    
  4. No mesmo diretório, crie o arquivo k8s-only.action e adicione o seguinte conteúdo a ele. Observe que CLUSTER_IP será substituído quando k8s-api-proxy.sh for executado.

    # Block everything...
    {+block{Not Kubernetes}}
    /
    # ... except the internal k8s endpoint, which you rewrite (see # k8s-rewrite-internal.filter). {+client-header-filter{k8s-rewrite-internal} -block{Kubernetes}} CLUSTER_IP/
  5. Crie o arquivo k8s-rewrite-internal.filter e adicione o seguinte conteúdo a ele. Observe que CLUSTER_IP será substituído quando k8s-api-proxy.sh for executado.

    CLIENT-HEADER-FILTER: k8s-rewrite-internal\
     Rewrite https://CLUSTER_IP/ to https://kubernetes.default/
    s@(CONNECT) CLUSTER_IP:443\
     (HTTP/\d\.\d)@$1 kubernetes.default:443 $2@ig
    
  6. Crie o arquivo k8s-api-proxy.sh e adicione o seguinte conteúdo a ele.

    #!/bin/sh
    
    set -o errexit
    set -o pipefail
    set -o nounset
    
    # Get the internal cluster IP
    export TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
    INTERNAL_IP=$(curl -H "Authorization: Bearer $TOKEN" -k -SsL https://kubernetes.default/api |
    jq -r '.serverAddressByClientCIDRs[0].serverAddress')
    
    # Replace CLUSTER_IP in the rewrite filter and action file
    sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\
     /etc/privoxy/k8s-rewrite-internal.filter
    sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\
     /etc/privoxy/k8s-only.action
    
    # Start Privoxy un-daemonized
    privoxy --no-daemon /etc/privoxy/config
    
  7. Torne o k8s-api-proxy.sh executável:

    chmod +x k8s-api-proxy.sh
  8. Crie e envie o contêiner para o projeto.

    docker build -t gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 .
    docker push gcr.io/$PROJECT_ID/k8s-api-proxy:0.1
    

Como implantar a imagem e o serviço

  1. No Cloud Shell, faça login na VM cliente criada anteriormente:

    gcloud compute ssh proxy-temp
    
  2. Instale a ferramenta kubectl:

    sudo apt-get install kubectl
    
  3. Salve o ID do projeto como uma variável de ambiente:

    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  4. Consiga as credenciais do cluster:

    gcloud container clusters get-credentials frobnitz \
    --zone us-central1-c --internal-ip
    
  5. Crie uma implantação do Kubernetes que exponha o contêiner recém-criado:

    kubectl run k8s-api-proxy \
        --image=gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 \
        --port=8118
    
  6. Crie o arquivo ilb.yaml para o balanceador de carga interno e copie o seguinte nele:

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        run: k8s-api-proxy
      name: k8s-api-proxy
      namespace: default
      annotations:
        cloud.google.com/load-balancer-type: "Internal"
    spec:
      ports:
      - port: 8118
        protocol: TCP
        targetPort: 8118
      selector:
        run: k8s-api-proxy
      type: LoadBalancer
    
  7. Implante o balanceador de carga interno:

    kubectl create -f ilb.yaml
  8. Verifique o serviço e aguarde um endereço IP:

    kubectl get service/k8s-api-proxy

    A saída será semelhante à exibida a seguir. Quando você vê um IP externo, o proxy está pronto.

    NAME            TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    k8s-api-proxy   LoadBalancer   10.24.13.129   10.24.24.3    8118:30282/TCP   2m
    

    O endereço IP externo desta etapa é o endereço do proxy.

  9. Salve o endereço IP do ILB como uma variável de ambiente:

    export LB_IP=`kubectl get  service/k8s-api-proxy \
    -o jsonpath='{.status.loadBalancer.ingress[].ip}'`
    
  10. Salve o endereço IP do controlador do cluster em uma variável de ambiente:

    export CONTROLLER_IP=`gcloud container clusters describe frobnitz \
    --zone=us-central1-c \
    --format="get(privateClusterConfig.privateEndpoint)"`
    
  11. Acesse a API Kubernetes por meio proxy para verificar se ele é utilizável:

    curl -k -x $LB_IP:8118 https://$CONTROLLER_IP/version
    
    A saída será semelhante a esta (sua saída pode ser diferente):
    {
      "major": "1",
      "minor": "15+",
      "gitVersion": "v1.15.11-gke.5",
      "gitCommit": "a5bf731ea129336a3cf32c3375317b3a626919d7",
      "gitTreeState": "clean",
      "buildDate": "2020-03-31T02:49:49Z",
      "goVersion": "go1.12.17b4",
      "compiler": "gc",
      "platform": "linux/amd64"
    }
    
  12. Defina a variável de ambiente https_proxy como o proxy HTTP(S) para que o comando kubectl possa alcançar o balanceador de carga interno a partir de qualquer lugar:

    export https_proxy=$LB_IP:8118
  13. Para testar o proxy e a variável https_proxy, execute o comando kubectl:

    kubectl get pods

    Você terá um resultado parecido com o seguinte, o que significa que você se conectou com êxito à API do Kubernetes por meio do proxy:

    NAME                             READY   STATUS    RESTARTS   AGE
    k8s-api-proxy-766c69dd45-mfqf4   1/1     Running   0          6m15s
    
  14. Saia da VM cliente:

    exit

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Exclua o projeto

  1. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir o cluster do GKE

Se você não quiser excluir o projeto, exclua o cluster do GKE:

gcloud container clusters delete frobnitz

A seguir