Crea clústeres privados de GKE con proxies de red para acceder a la instancia principal

Cuando creas un clúster privado de GKE con un extremo de instancia principal del clúster privado, el nodo de instancia principal del clúster es inaccesible desde la Internet pública, pero debe ser accesible para la administración.

De forma predeterminada, los clústeres pueden acceder a la instancia principal a través de su extremo privado y se pueden definir las redes autorizadas dentro de la red de VPC.

Sin embargo, para acceder a la instancia principal desde una red local o alguna otra red de VPC, se requieren pasos adicionales. Esto se debe a que la red de VPC que aloja la instancia principal es propiedad de Google y no se puede acceder a ella desde recursos conectados mediante otra conexión de intercambio de tráfico entre redes de VPC, Cloud VPN o Cloud Interconnect.

Para acceder a la instancia principal desde las instalaciones locales o desde otra red de VPC conectada por Cloud VPN o Cloud Interconnect, habilita la exportación de rutas desde tu red de VPC a la red de VPC de Google.

Para habilitar el acceso a la instancia principal desde otra red de VPC o desde una conexión local mediante otro intercambio de tráfico entre redes de VPC (como los diseños de concentrador y radio), crea un proxy alojado en un espacio de direcciones IP autorizado, ya que el intercambio de tráfico entre redes de VPC no es transitivo.

En este instructivo, se muestra cómo configurar un proxy en tu clúster privado de GKE.

Objetivos

  • Crear un clúster privado de GKE sin acceso externo
  • Crear y, luego, implementar una imagen de Docker para ejecutar el proxy
  • Crear un servicio de Kubernetes para acceder al proxy
  • Probar el acceso al proxy

Costos

En este instructivo, se usan componentes facturables de Google Cloud Platform, incluidos los siguientes:

Puedes usar la calculadora de precios para generar una estimación de costos según el uso previsto.

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Antes de comenzar

  1. Accede a tu Cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. En la página de selección de proyectos de Cloud Console, selecciona o crea un proyecto de Cloud.

    Ir a la página Selector de proyectos

  3. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  4. Habilita las API de Compute Engine and Google Kubernetes Engine.

    Habilita las API

Configura tu entorno

En este instructivo, usarás Cloud Shell para ingresar comandos. Cloud Shell te brinda acceso a la línea de comandos en Cloud Console y, además, incluye el SDK de Cloud y otras herramientas que necesitas para el desarrollo en Google Cloud. Cloud Shell se abre en una ventana en la parte inferior de Cloud Console. Es posible que la inicialización tome unos minutos, pero la ventana aparecerá de inmediato.

Sigue estos pasos para configurar tu entorno con Cloud Shell:

  1. En Cloud Console, abre Cloud Shell.

    Abrir Cloud Shell

  2. Asegúrate de que estés trabajando en el proyecto que creaste o seleccionaste. Reemplaza [YOUR_PROJECT_ID] por tu proyecto de Google Cloud.

    gcloud config set project [YOUR_PROJECT_ID]
    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  3. Configura la zona de procesamiento predeterminada. Para los fines de este instructivo, es us-central1-c. Si realizas la implementación en un entorno de producción, elige la región en la que deseas hacerlo.

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

Crea una red de VPC y una VM cliente

Crea una red y subred de VPC que alojarán los recursos.

  1. Crea una red de VPC:

    gcloud compute networks create k8s-proxy --subnet-mode=custom
    
  2. Crea una subred personalizada en la red de VPC recién creada:

    gcloud compute networks subnets create subnet-cluster \
        --network=k8s-proxy --range=10.50.0.0/16
    
  3. Crea una VM cliente que utilizarás para implementar recursos en el clúster de Kubernetes:

    gcloud compute instances create --subnet=subnet-cluster \
        --scopes cloud-platform proxy-temp
    
  4. Guarda la dirección IP interna de la instancia recién creada en una variable de entorno:

    export CLIENT_IP=`gcloud compute instances describe proxy-temp \
        --format="value(networkInterfaces[0].networkIP)"`
    
  5. Crea una regla de firewall para permitir el acceso de SSH a la red de VPC:

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

Crea un clúster privado

Ahora crea un clúster privado para usar en este instructivo.

Si ya tienes un clúster que prefieras usar, puedes omitir el paso de creación del clúster, pero debes configurar alguna forma de acceso inicial en la máquina cliente.

  • En Cloud Shell, crea un clúster:

    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
    

    Mediante el comando, se crea un clúster privado de GKE, llamado frobnitz, con un conjunto de redes autorizadas por la instancia principal a fin de permitir que solo tenga acceso la máquina cliente.

Crea la imagen de Docker

Sigue estos pasos para compilar una imagen de proxy de la API de Kubernetes llamada k8s-api-proxy, que actúa como un proxy de reenvío en el servidor de la API de Kubernetes.

  1. En Cloud Shell, crea un directorio y cambia a ese directorio:

    mkdir k8s-api-proxy && cd k8s-api-proxy
  2. Crea el Dockerfile: Mediante la siguiente configuración, se crea un contenedor de Alpine, que es una distribución de contenedores livianos que tiene un proxy Privoxy. El Dockerfile también instala curl y jq para la inicialización de contenedores, agrega los archivos de configuración necesarios, expone de forma interna el puerto 8118 a GKE y agrega una secuencia de comandos de inicio.

    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. En el directorio k8s-api-proxy, crea el archivo de config y agrégale el siguiente contenido:

    #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. En el mismo directorio, crea el archivo k8s-only.action y agrégale el siguiente contenido. Ten en cuenta que CLUSTER_IP se reemplazará cuando se ejecute k8s-api-proxy.sh.

    # 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. Crea el archivo k8s-rewrite-internal.filter y agrégale el siguiente contenido. Ten en cuenta que CLUSTER_IP se reemplazará cuando se ejecute k8s-api-proxy.sh.

    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. Crea el archivo k8s-api-proxy.sh y agrégale el siguiente contenido.

    #!/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. Haz que k8s-api-proxy.sh sea ejecutable:

    chmod +x k8s-api-proxy.sh
  8. Compila y envía el contenedor a tu proyecto.

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

Implementa la imagen y el servicio

  1. En Cloud Shell, accede a la VM cliente que creaste antes:

    gcloud compute ssh proxy-temp
    
  2. Instala la herramienta de kubectl:

    sudo apt-get install kubectl
    
  3. Guarda el ID del proyecto como una variable de entorno:

    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  4. Obtén las credenciales del clúster:

    gcloud container clusters get-credentials frobnitz \
    --zone us-central1-c --internal-ip
    
  5. Crea una implementación de Kubernetes que exponga el contenedor que acabas de crear:

    kubectl run k8s-api-proxy \
        --image=gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 \
        --port=8118
    
  6. Crea el archivo ilb.yaml para el balanceador de cargas interno y copia lo siguiente en él:

    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. Implementa el balanceador de cargas interno:

    kubectl create -f ilb.yaml
  8. Marca el servicio y espera una dirección IP:

    kubectl get service/k8s-api-proxy

    El resultado se verá de la siguiente manera. Cuando veas una IP externa, significa que el proxy ya está listo.

    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
    

    La dirección IP externa de este paso es tu dirección de proxy.

  9. Guarda la dirección IP del ILB como una variable del entorno:

    export LB_IP=`kubectl get  service/k8s-api-proxy \
    -o jsonpath='{.status.loadBalancer.ingress[].ip}'`
    
  10. Guarda la dirección IP de la instancia principal del clúster en una variable de entorno:

    export MASTER_IP=`gcloud container clusters describe frobnitz \
    --zone=us-central1-c \
    --format="get(privateClusterConfig.privateEndpoint)"`
    
  11. Verifica que el proxy se pueda usar. Para ello, accede a la API de Kubernetes a través de él:

    curl -k -x $LB_IP:8118 https://$MASTER_IP/version
    
    El resultado se verá de la siguiente manera (puede que tu resultado sea 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. Configura la variable de entorno https_proxy en el proxy HTTP(S) para que el comando kubectl pueda alcanzar el balanceador de cargas interno desde cualquier lugar:

    export https_proxy=$LB_IP:8118
  13. Prueba el proxy y la variable https_proxy; para ello, ejecuta el comando de kubectl:

    kubectl get pods

    Obtendrás un resultado similar al siguiente, lo que significa que te conectaste de manera correcta a la API de Kubernetes a través del proxy:

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

    exit

Limpia

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Borra el proyecto

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a la página Administrar recursos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar .
  3. En el cuadro de diálogo, escribe el ID del proyecto y haz clic en Cerrar para borrar el proyecto.

Próximos pasos