Crea clústeres privados de GKE con proxies de red para acceder a los controladores

Cuando creas un clúster privado de GKE con un extremo de controlador de clúster privado, no se puede acceder al nodo del controlador del clúster desde la Internet pública, pero debe ser accesible para la administración.

De forma predeterminada, los clústeres pueden acceder al controlador a través de su extremo privado, y las redes autorizadas pueden definirse dentro de la red de VPC.

Sin embargo, para acceder al controlador de manera local o desde otra red de VPC, se requieren pasos adicionales. Esto se debe a que la red de VPC que aloja el controlador pertenece a 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 ni Cloud Interconnect.

Para acceder al controlador de manera local o desde otra red de VPC conectada mediante Cloud VPN o Cloud Interconnect, habilita la exportación de rutas de tu red de VPC a la red de VPC de Google.

Para habilitar el acceso al controlador desde otra red de VPC o desde una conexión local mediante otro intercambio de tráfico entre redes de VPC (como diseños de concentrador y radio), crea un proxy alojado en un espacio de direcciones IP autorizado. Esto se debe a 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 realizar 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 Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyecto

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  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
    

    El comando crea un clúster privado de GKE, llamado frobnitz y master-authorized-networks, configurado con el fin de permitir que solo la máquina cliente tenga acceso.

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 de entorno:

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

    export CONTROLLER_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://$CONTROLLER_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

Realice una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

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

    Ir a Administrar recursos

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

Borra el clúster de GKE

Si no quieres borrar el proyecto, borra el clúster de GKE:

gcloud container clusters delete frobnitz

¿Qué sigue?