Desplegar aplicaciones de Windows en Kubernetes gestionado

Last reviewed 2024-08-14 UTC

En este documento se describe cómo desplegar la arquitectura de referencia en Gestionar y escalar la red de aplicaciones Windows que se ejecutan en Kubernetes gestionado.

Estas instrucciones están dirigidas a arquitectos de la nube, administradores de redes y profesionales de TI que se encargan del diseño y la gestión de aplicaciones de Windows que se ejecutan en clústeres de Google Kubernetes Engine (GKE).

Arquitectura

En el siguiente diagrama se muestra la arquitectura de referencia que se usa al implementar aplicaciones de Windows que se ejecutan en clústeres de GKE gestionados.

Los datos fluyen a través de un balanceador de carga de aplicación interno y una pasarela Envoy.

Como se muestra en el diagrama anterior, una flecha representa el flujo de trabajo para gestionar la red de las aplicaciones de Windows que se ejecutan en GKE mediante Cloud Service Mesh y las pasarelas de Envoy. El clúster de GKE regional incluye grupos de nodos de Windows y Linux. Cloud Service Mesh crea y gestiona rutas de tráfico a los pods de Windows.

Objetivos

  • Crea y configura un clúster de GKE para ejecutar aplicaciones de Windows y proxies de Envoy.
  • Despliega y verifica las aplicaciones de Windows.
  • Configura Cloud Service Mesh como plano de control de las pasarelas de Envoy.
  • Usa la API de Kubernetes Gateway para aprovisionar el balanceador de carga de aplicaciones interno y exponer las pasarelas de Envoy.
  • Consulta las operaciones de implementación continua que has creado.

Costes

La implementación de esta arquitectura usa los siguientes componentes facturables de Google Cloud:

Cuando finalices esta implementación, puedes evitar que se te siga facturando eliminando los recursos que hayas creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Enable the Cloud Shell, and Cloud Service Mesh APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    Si se ejecuta en un entorno de nube privada virtual (VPC) compartida, también debe seguir las instrucciones para crear manualmente la subred de solo proxy y la regla de cortafuegos para las comprobaciones de respuesta de Cloud Load Balancing.

    Crear un clúster de GKE

    Sigue estos pasos para crear un clúster de GKE. En esta implementación, el clúster de GKE se usa para contener y ejecutar las aplicaciones de Windows y los proxies de Envoy.

    1. En Cloud Shell, ejecuta el siguiente comando de la CLI de Google Cloud para crear un clúster de GKE regional con un nodo en cada una de las tres regiones:

      gcloud container clusters create my-cluster
          --enable-ip-alias \
          --num-nodes=1 \
          --release-channel stable \
          --enable-dataplane-v2 \
          --region us-central1 \
          --scopes=cloud-platform \
          --gateway-api=standard
      
    2. Añade el grupo de nodos de Windows al clúster de GKE:

      gcloud container node-pools create win-pool \
          --cluster=my-cluster \
          --image-type=windows_ltsc_containerd \
          --no-enable-autoupgrade \
          --region=us-central1 \
          --num-nodes=1 \
          --machine-type=n1-standard-2 \
          --windows-os-version=ltsc2019
      

      Esta operación puede tardar unos 20 minutos en completarse.

    3. Almacena el ID de tu proyecto Google Cloud en una variable de entorno:

      export PROJECT_ID=$(gcloud config get project)
      
    4. Conéctate al clúster de GKE:

      gcloud container clusters get-credentials my-cluster --region us-central1
      
    5. Lista todos los nodos del clúster de GKE:

      kubectl get nodes
      

      La salida debería mostrar tres nodos de Linux y tres nodos de Windows.

      Cuando el clúster de GKE esté listo, podrás desplegar dos aplicaciones de prueba basadas en Windows.

    Desplegar dos aplicaciones de prueba

    En esta sección, implementarás dos aplicaciones de prueba basadas en Windows. Ambas aplicaciones de prueba imprimen el nombre de host en el que se ejecutan. También creará un servicio de Kubernetes para exponer la aplicación a través de grupos de endpoints de red (NEGs) independientes.

    Cuando despliegas una aplicación basada en Windows y un servicio de Kubernetes en un clúster regional, se crea un NEG para cada zona en la que se ejecuta la aplicación. Más adelante, en esta guía de implementación se explica cómo puedes configurar estos NEGs como back-ends de los servicios de Cloud Service Mesh.

    1. En Cloud Shell, aplica el siguiente archivo YAML con kubectl para desplegar la primera aplicación de prueba. Este comando despliega tres instancias de la aplicación de prueba, una en cada zona regional.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          app: win-webserver-1
        name: win-webserver-1
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: win-webserver-1
        template:
          metadata:
            labels:
              app: win-webserver-1
            name: win-webserver-1
          spec:
           containers:
            - name: windowswebserver
              image: k8s.gcr.io/e2e-test-images/agnhost:2.36
              command: ["/agnhost"]
              args: ["netexec", "--http-port", "80"]
           topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: kubernetes.io/hostname
              whenUnsatisfiable: DoNotSchedule
              labelSelector:
                matchLabels:
                  app: win-webserver-1
           nodeSelector:
            kubernetes.io/os: windows
      
    2. Aplica el servicio de Kubernetes correspondiente y exponlo con un NEG:

      apiVersion: v1
      kind: Service
      metadata:
        name: win-webserver-1
        annotations:
          cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "win-webserver-1"}}}'
      spec:
        type: ClusterIP
        selector:
          app: win-webserver-1
        ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80
      
    3. Verifica la implementación:

      kubectl get pods
      

      El resultado muestra que la aplicación tiene tres pods de Windows en ejecución.

      NAME                               READY   STATUS    RESTARTS   AGE
      win-webserver-1-7bb4c57f6d-hnpgd   1/1     Running   0          5m58s
      win-webserver-1-7bb4c57f6d-rgqsb   1/1     Running   0          5m58s
      win-webserver-1-7bb4c57f6d-xp7ww   1/1     Running   0          5m58s
      
    4. Comprueba que se haya creado el servicio de Kubernetes:

      $ kubectl get svc
      

      La salida es similar a la siguiente:

      NAME              TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
      kubernetes        ClusterIP   10.64.0.1            443/TCP   58m
      win-webserver-1   ClusterIP   10.64.6.20           80/TCP    3m35s
      
    5. Ejecuta el comando describe para kubectl para verificar que se han creado NEGs correspondientes para el servicio de Kubernetes en cada una de las zonas en las que se ejecuta la aplicación:

      $ kubectl describe service win-webserver-1
      

      La salida es similar a la siguiente:

      Name:              win-webserver-1
      Namespace:         default
      Labels:            
      Annotations:       cloud.google.com/neg: {"exposed_ports": {"80":{"name": "win-webserver-1"}}}
                         cloud.google.com/neg-status: {"network_endpoint_groups":{"80":"win-webserver-1"},"zones":["us-central1-a","us-central1-b","us-central1-c"]}
      Selector:          app=win-webserver-1
      Type:              ClusterIP
      IP Family Policy:  SingleStack
      IP Families:       IPv4
      IP:                10.64.6.20
      IPs:               10.64.6.20
      Port:              http  80/TCP
      TargetPort:        80/TCP
      Endpoints:         10.60.3.5:80,10.60.4.5:80,10.60.5.5:80
      Session Affinity:  None
      Events:
        Type    Reason  Age    From            Message
        ----    ------  ----   ----            -------
        Normal  Create  4m25s  neg-controller  Created NEG "win-webserver-1" for default/win-webserver-1-win-webserver-1-http/80-80-GCE_VM_IP_PORT-L7 in "us-central1-a".
        Normal  Create  4m18s  neg-controller  Created NEG "win-webserver-1" for default/win-webserver-1-win-webserver-1-http/80-80-GCE_VM_IP_PORT-L7 in "us-central1-b".
        Normal  Create  4m11s  neg-controller  Created NEG "win-webserver-1" for default/win-webserver-1-win-webserver-1-http/80-80-GCE_VM_IP_PORT-L7 in "us-central1-c".
        Normal  Attach  4m9s   neg-controller  Attach 1 network endpoint(s) (NEG "win-webserver-1" in zone "us-central1-a")
        Normal  Attach  4m8s   neg-controller  Attach 1 network endpoint(s) (NEG "win-webserver-1" in zone "us-central1-c")
        Normal  Attach  4m8s   neg-controller  Attach 1 network endpoint(s) (NEG "win-webserver-1" in zone "us-central1-b")
      

      La salida del comando anterior muestra que se ha creado un NEG para cada zona.

    6. Opcional: Usa la CLI de gcloud para verificar que se han creado los NEG:

      gcloud compute network-endpoint-groups list
      

      El resultado es el siguiente:

      NAME                                                        LOCATION            ENDPOINT_TYPE     SIZE
      win-webserver-1                                us-central1-a  GCE_VM_IP_PORT  1
      win-webserver-1                                us-central1-b  GCE_VM_IP_PORT  1
      win-webserver-1                                us-central1-c  GCE_VM_IP_PORT  1
      
    7. Para implementar la segunda aplicación de prueba, aplica el siguiente archivo YAML:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          app: win-webserver-2
        name: win-webserver-2
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: win-webserver-2
        template:
          metadata:
            labels:
              app: win-webserver-2
            name: win-webserver-2
          spec:
           containers:
            - name: windowswebserver
              image: k8s.gcr.io/e2e-test-images/agnhost:2.36
              command: ["/agnhost"]
              args: ["netexec", "--http-port", "80"]
           topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: kubernetes.io/hostname
              whenUnsatisfiable: DoNotSchedule
              labelSelector:
                matchLabels:
                  app: win-webserver-2
           nodeSelector:
            kubernetes.io/os: windows
      
    8. Crea el servicio de Kubernetes correspondiente:

      apiVersion: v1
      kind: Service
      metadata:
        name: win-webserver-2
        annotations:
          cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "win-webserver-2"}}}'
      spec:
        type: ClusterIP
        selector:
          app: win-webserver-2
        ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80
      
    9. Verifica la implementación de la aplicación:

      kubectl get pods
      

      Comprueba la salida y verifica que hay tres pods en ejecución.

    10. Verifica que se hayan creado el servicio de Kubernetes y los tres NEGs:

      kubectl describe service win-webserver-2
      

    Configurar Cloud Service Mesh

    En esta sección, Cloud Service Mesh se configura como el plano de control de las pasarelas Envoy.

    Para asignar las pasarelas de Envoy a la configuración de enrutamiento de Cloud Service Mesh correspondiente, especifica el parámetro scope_name. El parámetro scope_name te permite configurar diferentes reglas de enrutamiento para las distintas puertas de enlace de Envoy.

    1. En Cloud Shell, crea una regla de cortafuegos que permita el tráfico entrante de los servicios de Google que comprueban la capacidad de respuesta de la aplicación:

      gcloud compute firewall-rules create allow-health-checks \
        --network=default \
        --direction=INGRESS \
        --action=ALLOW \
        --rules=tcp \
        --source-ranges="35.191.0.0/16,130.211.0.0/22,209.85.152.0/22,209.85.204.0/22"
      
    2. Comprueba la capacidad de respuesta de la primera aplicación:

      gcloud compute health-checks create http win-app-1-health-check \
        --enable-logging \
        --request-path="/healthz" \
        --use-serving-port
      
    3. Comprueba la capacidad de respuesta de la segunda aplicación:

      gcloud compute health-checks create http win-app-2-health-check \
        --enable-logging \
        --request-path="/healthz" \
        --use-serving-port
      
    4. Crea un servicio de backend de Cloud Service Mesh para la primera aplicación:

      gcloud compute backend-services create win-app-1-service \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --port-name=http \
       --health-checks win-app-1-health-check
      
    5. Crea un servicio de backend de Cloud Service Mesh para la segunda aplicación:

      gcloud compute backend-services create win-app-2-service \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --port-name=http \
       --health-checks win-app-2-health-check
      
    6. Añade los NEGs que has creado anteriormente. Estos NEGs están asociados a la primera aplicación que creaste como backend del servicio de backend de Cloud Service Mesh. Este ejemplo de código añade un NEG por cada zona del clúster regional que ha creado.

      BACKEND_SERVICE=win-app-1-service
      APP1_NEG_NAME=win-webserver-1
      MAX_RATE_PER_ENDPOINT=10
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP1_NEG_NAME \
        --network-endpoint-group-zone us-central1-b \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP1_NEG_NAME \
        --network-endpoint-group-zone us-central1-a \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP1_NEG_NAME \
        --network-endpoint-group-zone us-central1-c \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      
    7. Añade más NEGs. Estos NEGs están asociados a la segunda aplicación que has creado como backend del servicio de backend de Cloud Service Mesh. Este ejemplo de código añade un NEG por cada zona del clúster regional que has creado.

      BACKEND_SERVICE=win-app-2-service
      APP2_NEG_NAME=win-webserver-2
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP2_NEG_NAME \
        --network-endpoint-group-zone us-central1-b \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP2_NEG_NAME \
        --network-endpoint-group-zone us-central1-a \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      
      gcloud compute backend-services add-backend $BACKEND_SERVICE \
        --global \
        --network-endpoint-group $APP2_NEG_NAME \
        --network-endpoint-group-zone us-central1-c \
        --balancing-mode RATE \
        --max-rate-per-endpoint $MAX_RATE_PER_ENDPOINT
      

    Configurar recursos adicionales de Cloud Service Mesh

    Ahora que has configurado los servicios de Cloud Service Mesh, debes configurar dos recursos adicionales para completar la configuración de Cloud Service Mesh.

    En primer lugar, estos pasos muestran cómo configurar un recurso Gateway. Un recurso Gateway es un recurso virtual que se usa para generar reglas de enrutamiento de Cloud Service Mesh. Las reglas de enrutamiento de Cloud Service Mesh se usan para configurar proxies de Envoy como pasarelas.

    A continuación, se explica cómo configurar un recurso HTTPRoute para cada uno de los servicios backend. El recurso HTTPRoute asigna solicitudes HTTP al servicio de backend correspondiente.

    1. En Cloud Shell, crea un archivo YAML llamado gateway.yaml que defina el recurso Gateway:

      cat <<EOF> gateway.yaml
      name: gateway80
      scope: gateway-proxy
      ports:
      - 8080
      type: OPEN_MESH
      EOF
      
    2. Crea el recurso Gateway invocando el archivo gateway.yaml:

      gcloud network-services gateways import gateway80 \
        --source=gateway.yaml \
        --location=global
      

      El nombre de Gateway será projects/$PROJECT_ID/locations/global/gateways/gateway80.

      Este nombre de Gateway se usa al crear HTTPRoutes para cada servicio de backend.

    Crea el HTTPRoutes para cada servicio de backend:

    1. En Cloud Shell, almacena el ID de tu proyecto Google Cloud en una variable de entorno:

      export PROJECT_ID=$(gcloud config get project)
      
    2. Crea el archivo YAML HTTPRoute para la primera aplicación:

      cat <<EOF> win-app-1-route.yaml
      name: win-app-1-http-route
      hostnames:
      - win-app-1
      gateways:
      - projects/$PROJECT_ID/locations/global/gateways/gateway80
      rules:
      - action:
         destinations:
         - serviceName: "projects/$PROJECT_ID/locations/global/backendServices/win-app-1-service"
      EOF
      
    3. Crea el recurso HTTPRoute para la primera aplicación:

      gcloud network-services http-routes import win-app-1-http-route \
        --source=win-app-1-route.yaml \
        --location=global
      
    4. Crea el archivo HTTPRoute YAML para la segunda aplicación:

      cat <<EOF> win-app-2-route.yaml
      name: win-app-2-http-route
      hostnames:
      - win-app-2
      gateways:
      - projects/$PROJECT_ID/locations/global/gateways/gateway80
      rules:
      - action:
         destinations:
       - serviceName: "projects/$PROJECT_ID/locations/global/backendServices/win-app-2-service"
      EOF
      
    5. Crea el recurso HTTPRoute para la segunda aplicación:

      gcloud network-services http-routes import win-app-2-http-route \
        --source=win-app-2-route.yaml \
        --location=global
      

    Desplegar y exponer las pasarelas de Envoy

    Después de crear las dos aplicaciones de prueba basadas en Windows y Cloud Service Mesh, despliega las pasarelas de Envoy creando un archivo YAML de implementación. El archivo YAML de implementación realiza las siguientes tareas:

    • Inicializa las pasarelas de Envoy.
    • Configura las pasarelas de Envoy para que usen Cloud Service Mesh como plano de control.
    • Configura las pasarelas de Envoy para que usen HTTPRoutes en la pasarela llamada Gateway80.

    Despliega dos pasarelas Envoy de réplica. Este enfoque ayuda a que las pasarelas sean tolerantes a fallos y proporciona redundancia. Para escalar automáticamente las pasarelas de Envoy en función de la carga, puede configurar un autoescalador de pods horizontal. Si decides configurar un autoescalador de pods horizontal, debes seguir las instrucciones que se indican en el artículo Configurar el autoescalado de pods horizontal.

    1. En Cloud Shell, crea un archivo YAML:

      apiVersion: apps/v1
      kind: Deployment
          metadata:
        creationTimestamp: null
        labels:
          app: td-envoy-gateway
        name: td-envoy-gateway
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: td-envoy-gateway
        template:
          metadata:
            creationTimestamp: null
            labels:
              app: td-envoy-gateway
          spec:
            containers:
            - name: envoy
              image: envoyproxy/envoy:v1.21.6
              imagePullPolicy: Always
              resources:
                limits:
                  cpu: "2"
                  memory: 1Gi
                requests:
                  cpu: 100m
                  memory: 128Mi
              env:
              - name: ENVOY_UID
                value: "1337"
              volumeMounts:
                - mountPath: /etc/envoy
                  name: envoy-bootstrap
            initContainers:
            - name: td-bootstrap-writer
              image: gcr.io/trafficdirector-prod/xds-client-bootstrap-generator
              imagePullPolicy: Always
              args:
                - --project_number='my_project_number'
                - --scope_name='gateway-proxy'
                - --envoy_port=8080
                - --bootstrap_file_output_path=/var/lib/data/envoy.yaml
                - --traffic_director_url=trafficdirector.googleapis.com:443
                - --expose_stats_port=15005
              volumeMounts:
                - mountPath: /var/lib/data
                  name: envoy-bootstrap
            volumes:
              - name: envoy-bootstrap
                emptyDir: {}
      
      • Sustituye my_project_number por el número de tu proyecto.

        • Para encontrar el número de tu proyecto, ejecuta el siguiente comando:
        gcloud projects describe $(gcloud config get project)
         --format="value(projectNumber)"
        

      El puerto 15005 se usa para exponer el endpoint de administrador de Envoy llamado /stats. También se usa para los siguientes fines:

      • Como un endpoint de respuesta del balanceador de carga de aplicación interno.
      • Para consumir métricas de Google Cloud Managed Service para Prometheus desde Envoy.

      Cuando los dos pods de Envoy Gateway estén en ejecución, crea un servicio de tipo ClusterIP para exponerlos. También debes crear un archivo YAML llamado BackendConfig. BackendConfig define una comprobación de la capacidad de respuesta no estándar. Esta comprobación se usa para verificar la capacidad de respuesta de las pasarelas Envoy.

    2. Para crear la configuración del backend con una comprobación de respuesta no estándar, crea un archivo YAML llamado envoy-backendconfig:

      apiVersion: cloud.google.com/v1
      kind: BackendConfig
      metadata:
        name: envoy-backendconfig
      spec:
        healthCheck:
          checkIntervalSec: 5
          timeoutSec: 5
          healthyThreshold: 2
          unhealthyThreshold: 3
          type: HTTP
          requestPath: /stats
          port: 15005
      

      La comprobación de la capacidad de respuesta usará el endpoint /stats en el puerto 15005 para comprobar continuamente la capacidad de respuesta de las pasarelas Envoy.

    3. Crea el servicio de pasarelas de Envoy:

      apiVersion: v1
      kind: Service
      metadata:
        name: td-envoy-gateway
        annotations:
          cloud.google.com/backend-config: '{"default": "envoy-backendconfig"}'
      spec:
        type: ClusterIP
        selector:
          app: td-envoy-gateway
        ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
        - name: stats
          protocol: TCP
          port: 15005
          targetPort: 15005
      
    4. Consulta el servicio de pasarelas Envoy que has creado:

      kubectl get svc td-envoy-gateway
      

    Crear el recurso de Kubernetes Gateway

    Al crear el recurso de pasarela de Kubernetes, se aprovisiona el balanceador de carga de aplicación interno para exponer las pasarelas de Envoy.

    Antes de crear ese recurso, debes crear dos certificados autofirmados de muestra e importarlos al clúster de GKE como secretos de Kubernetes. Los certificados permiten la siguiente arquitectura de pasarela:

    • Cada aplicación se sirve a través de HTTPS.
    • Cada aplicación usa un certificado específico.

    Cuando se usan certificados autogestionados, el balanceador de carga de aplicaciones interno puede usar hasta el límite máximo de certificados para exponer aplicaciones con nombres de dominio completos diferentes.

    Para crear los certificados, usa openssl.

    1. En Cloud Shell, genera un archivo de configuración para el primer certificado:

      cat <<EOF >CONFIG_FILE
      [req]
      default_bits              = 2048
      req_extensions            = extension_requirements
      distinguished_name        = dn_requirements
      prompt                    = no
      [extension_requirements]
      basicConstraints          = CA:FALSE
      keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
      subjectAltName            = @sans_list
      [dn_requirements]
      0.organizationName        = example
      commonName                = win-webserver-1.example.com
      [sans_list]
      DNS.1                     = win-webserver-1.example.com
      EOF
      
    2. Genera una clave privada para el primer certificado:

      openssl genrsa -out sample_private_key 2048
      
    3. Genera una solicitud de certificado:

      openssl req -new -key sample_private_key -out CSR_FILE -config CONFIG_FILE
      
    4. Firma y genera el primer certificado:

      openssl x509 -req -signkey sample_private_key -in CSR_FILE -out sample.crt     -extfile CONFIG_FILE -extensions extension_requirements -days 90
      
    5. Genera un archivo de configuración para el segundo certificado:

      cat <<EOF >CONFIG_FILE2
      [req]
      default_bits              = 2048
      req_extensions            = extension_requirements
      distinguished_name        = dn_requirements
      prompt                    = no
      [extension_requirements]
      basicConstraints          = CA:FALSE
      keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
      subjectAltName            = @sans_list
      [dn_requirements]
      0.organizationName        = example
      commonName                = win-webserver-2.example.com
      [sans_list]
      DNS.1                     = win-webserver-2.example.com
      EOF
      
    6. Genera una clave privada para el segundo certificado:

      openssl genrsa -out sample_private_key2 2048
      
    7. Genera una solicitud de certificado:

      openssl req -new -key sample_private_key2 -out CSR_FILE2 -config CONFIG_FILE2
      
    8. Firma y genera el segundo certificado:

      openssl x509 -req -signkey sample_private_key2 -in CSR_FILE2 -out sample2.crt     -extfile CONFIG_FILE2 -extensions extension_requirements -days 90
      

    Importar certificados como secretos de Kubernetes

    En esta sección, realizarás las siguientes tareas:

    • Importa los certificados autofirmados al clúster de GKE como secretos de Kubernetes.
    • Crea una dirección IP estática para una VPC interna.
    • Crea el recurso de la API Gateway de Kubernetes.
    • Verifica que los certificados funcionen.
    1. En Cloud Shell, importa el primer certificado como un secreto de Kubernetes:

      kubectl create secret tls sample-cert --cert sample.crt --key sample_private_key
      
    2. Importa el segundo certificado como un secreto de Kubernetes:

      kubectl create secret tls sample-cert-2 --cert sample2.crt --key sample_private_key2
      
    3. Para habilitar el balanceador de carga de aplicaciones interno, crea una dirección IP estática en la VPC interna:

      gcloud compute addresses create sample-ingress-ip --region us-central1 --subnet default
      
    4. Crea el archivo YAML de recursos de la API de Kubernetes Gateway:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1beta1
      metadata:
        name: internal-https
      spec:
        gatewayClassName: gke-l7-rilb
        addresses:
          - type: NamedAddress
            value: sample-ingress-ip
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            mode: Terminate
            certificateRefs:
            - name: sample-cert
            - name: sample-cert-2
      

      De forma predeterminada, una pasarela de Kubernetes no tiene rutas predeterminadas. La pasarela devuelve un error de página no encontrada (404) cuando se le envían solicitudes.

    5. Configura un archivo route YAML predeterminado para la pasarela de Kubernetes que transfiera todas las solicitudes entrantes a las pasarelas de Envoy:

        kind: HTTPRoute
        apiVersion: gateway.networking.k8s.io/v1beta1
        metadata:
          name: envoy-default-backend
        spec:
          parentRefs:
          - kind: Gateway
            name: internal-https
          rules:
          - backendRefs:
            - name: td-envoy-gateway
              port: 8080
      

      Verifica el flujo completo enviando solicitudes HTTP a ambas aplicaciones. Para verificar que las pasarelas Envoy enrutan el tráfico a los pods de aplicación correctos, inspecciona el encabezado Host HTTP.

    6. Busca y almacena la dirección IP de Kubernetes Gateway en una variable de entorno:

      export EXTERNAL_IP=$(kubectl get gateway internal-https -o json | jq .status.addresses[0].value -r)
      
    7. Envía una solicitud a la primera aplicación:

      curl --insecure -H "Host: win-app-1" https://$EXTERNAL_IP/hostName
      
    8. Envía una solicitud a la segunda aplicación:

      curl --insecure -H "Host: win-app-2" https://$EXTERNAL_IP/hostName
      
    9. Verifica que el nombre de host devuelto por la solicitud coincida con los pods que se están ejecutando win-app-1 y win-app-2:

      kubectl get pods
      

      La salida debe mostrar win-app-1 y win-app-2.

    Monitorizar pasarelas Envoy

    Monitoriza tus pasarelas Envoy con Google Cloud Managed Service para Prometheus.

    Google Cloud Managed Service para Prometheus debería estar habilitado de forma predeterminada en el clúster que has creado anteriormente.

    1. En Cloud Shell, crea un recurso PodMonitoring aplicando el siguiente archivo YAML:

      apiVersion: monitoring.googleapis.com/v1
      kind: PodMonitoring
      metadata:
        name: prom-envoy
      spec:
        selector:
          matchLabels:
            app: td-envoy-gateway
        endpoints:
        - port: 15005
          interval: 30s
          path: /stats/prometheus
      

      Después de aplicar el archivo YAML, el sistema empieza a recoger métricas de Google Cloud Managed Service para Prometheus en un panel de control.

    2. Para crear el panel de métricas de Google Cloud Managed Service para Prometheus, sigue estas instrucciones:

      1. Inicia sesión en la Google Cloud consola.
      2. Abre el menú .
      3. Haga clic en Operaciones > Monitorización > Paneles de control.
    3. Para importar el panel de control, sigue estas instrucciones:

      1. En la pantalla Paneles de control, haga clic en Biblioteca de muestras.
      2. Escribe "envoy" en el cuadro de filtro.
      3. Haga clic en Resumen de Istio Envoy Prometheus.
      4. Marca la casilla de verificación.
      5. Haz clic en Importar y, a continuación, en Confirmar para importar el panel de control.
    4. Para ver el panel de control, sigue estas instrucciones:

      1. Haz clic en Lista de paneles de control.
      2. Selecciona Integraciones.
      3. Haga clic en Istio Envoy Prometheus Overview (Resumen de Istio Envoy Prometheus) para ver el panel de control.

    Ahora puede ver las métricas más importantes de sus pasarelas Envoy. También puedes configurar alertas en función de tus criterios. Antes de limpiar los datos, envía algunas solicitudes de prueba más a las aplicaciones y comprueba cómo se actualiza el panel de control con las métricas más recientes.

    Limpieza

    Para evitar que se apliquen cargos en tu cuenta de Google Cloud por los recursos utilizados en esta implementación, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

    Eliminar el proyecto

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Siguientes pasos

    Colaboradores

    Autor: Eitan Eibschutz | Asesor técnico de soluciones

    Otros colaboradores: