Automatizar la gestión de certificados TLS para la puerta de enlace de entrada de Cloud Service Mesh con el servicio de autoridad de certificación

En este tutorial se explica a los operadores de plataformas cómo usar el emisor del servicio de autoridad de certificación (CA Service) para la herramienta cert-manager con el fin de automatizar la gestión de certificados TLS para la puerta de enlace de entrada de Cloud Service Mesh. Los certificados permiten que la puerta de enlace de entrada finalice el tráfico HTTPS y otro tráfico TLS y mTLS procedente de clientes de tu nube privada virtual (VPC), pero fuera de la malla de servicios. En este tutorial se da por supuesto que tienes conocimientos básicos de Kubernetes y de certificados TLS.

Introducción

Cloud Service Mesh proporciona certificados TLS a cada carga de trabajo de la malla de servicios. Estos certificados permiten la comunicación cifrada y autenticada mutuamente con TLS (mTLS) entre las cargas de trabajo de la malla de servicios. Una de las autoridades de certificación admitidas emite y firma los certificados.

Sin embargo, Cloud Service Mesh no aprovisiona automáticamente certificados a la puerta de enlace de entrada para el tráfico que entra en la malla de servicios. Una solución habitual es usar la herramienta de código abierto cert-manager para automatizar la gestión de los certificados de la pasarela de entrada.

La herramienta cert-manager solicita certificados a un emisor, que representa una autoridad de certificación (CA). Servicio de Autoridades de Certificación es un Google Cloud servicio que te permite crear tu propia AC privada. La herramienta cert-manager puede solicitar certificados del Servicio de Autoridades de Certificación mediante el emisor externo de código abierto para el Servicio de Autoridades de Certificación.

Una CA privada puede emitir certificados TLS que autentiquen y cifren el tráfico dentro de una red interna. Las pasarelas de entrada de Cloud Service Mesh suelen configurarse para permitir el tráfico entrante de clientes que están dentro de tu VPC, pero fuera de la malla de servicios. Para el tráfico de red interno, puedes usar una autoridad de certificación privada en el servicio de autoridades de certificación para emitir certificados para la puerta de enlace de entrada.

En este tutorial se explica cómo configurar la herramienta cert-manager y el emisor del servicio de AC para automatizar el aprovisionamiento y la renovación de certificados TLS para la puerta de enlace de entrada. La herramienta cert-manager aprovisiona certificados como recursos Secret de Kubernetes de tipo TLS. Cuando la herramienta cert-manager renueva un certificado, actualiza el recurso Secret con un nuevo certificado. La pasarela de entrada ejecuta Envoy Proxy y admite el servicio de detección de secretos (SDS) de Envoy. SDS permite que la puerta de enlace de entrada empiece a usar un nuevo certificado sin que un administrador tenga que reiniciar o volver a cargar el proceso.

Los proxies sidecar que forman parte de la malla pueden obtener certificados TLS del servicio de CA o de la autoridad de certificación de Cloud Service Mesh. En este tutorial, usarás el servicio de AC para los certificados de proxy adicional y de puerta de enlace de entrada. De esta forma, puedes usar una CA raíz para todos los certificados TLS.

En el siguiente diagrama se muestran los recursos que aprovisionarás en este tutorial. Aprovisiona un balanceador de carga de red de paso a través interno para la pasarela de entrada. El balanceador de carga de red de paso a través interno no es un proxy, por lo que no finaliza las conexiones TCP ni realiza handshakes TLS. En su lugar, dirige las conexiones a los pods de la implementación de istio-ingressgateway.

El secreto hello-example-com-credential contiene un certificado y una clave privada. La puerta de enlace hello configura los pods de la implementación istio-ingressgateway para que usen este certificado y esta clave privada para realizar handshakes TLS en las solicitudes con el nombre de host hello.example.com.

Gestión de mTLS con el servicio de CA

Los pods de la implementación de google-cas-issuer en el espacio de nombres cert-manager solicitan certificados de la CA que creas en el Servicio de Autoridades de Certificación. Crea un enlace de política de Gestión de Identidades y Accesos que permita a los pods ca-service-isser actuar como una cuenta de servicio de Google mediante Workload Identity Federation for GKE. Para conceder permiso a esta cuenta de servicio de Google para solicitar certificados de tu AC en el Servicio de AC, crea un enlace de política de gestión de identidades y accesos en tu grupo de ACs.

Objetivos

Costes

En este tutorial se usan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios. Los usuarios nuevos Google Cloud pueden disfrutar de una prueba gratuita.

Cuando termines este tutorial, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

  1. En la Google Cloud consola, ve a la página del selector de proyectos y, a continuación, selecciona o crea un proyecto.

  2. Asegúrate de que la facturación esté habilitada en tu Google Cloud proyecto.

  3. En la Google Cloud consola, ve a Cloud Shell.

    En la parte inferior de la Google Cloud consola, se abre una sesión de Cloud Shell y se muestra un mensaje de la línea de comandos. Usarás Cloud Shell para ejecutar todos los comandos de este tutorial.

  4. Define el Google Cloud proyecto de consola que quieras usar en este tutorial:

    gcloud config set core/project PROJECT_ID
    

    Sustituye PROJECT_ID por el ID del proyecto de Cloud.

    En el cuadro de diálogo Autorizar Cloud Shell, haz clic en Autorizar. Al hacer clic en Autorizar, permites que los comandos de gcloud que ejecutes en Cloud Shell usen tus credenciales de usuario para autenticarse en las APIs de Google.

  5. Habilita las APIs Resource Manager, GKE, GKE Hub, autoridad de certificación de Cloud Service Mesh y CA Service:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        gkehub.googleapis.com \
        meshca.googleapis.com \
        privateca.googleapis.com
    

Configurar el servicio de AC

En esta sección, crearás una AC raíz y dos ACs subordinadas en el servicio de AC. Una CA subordinada emite certificados a la puerta de enlace de entrada y la otra CA subordinada emite certificados a los proxies sidecar de la malla.

Para simplificar las cosas, en este tutorial se usa el mismo proyecto para el clúster de GKE y las ACs raíz y subordinada. En tu propio entorno, puedes usar un proyecto diferente para el clúster de GKE y las CAs.

  1. En Cloud Shell, crea un grupo de ACs que se usará para la AC raíz:

    gcloud privateca pools create ROOT_CA_POOL \
        --location CA_LOCATION \
        --tier enterprise
    
    • ROOT_CA_POOL es el nombre del grupo de CAs. Por ejemplo, root-ca-pool-tutorial.
    • CA_LOCATION es la ubicación del grupo de autoridades de certificación. Por ejemplo, us-central1.

    Puedes consultar las ubicaciones de CA Service disponibles con este comando: gcloud privateca locations list

  2. Crea y habilita una CA raíz:

    gcloud privateca roots create ROOT_CA \
        --auto-enable \
        --key-algorithm ec-p384-sha384 \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --subject "CN=Example Root CA, O=Example Organization" \
        --use-preset-profile root_unconstrained
    
    • ROOT_CA es el nombre que quieres usar para la CA raíz. Por ejemplo, root-ca-tutorial.
  3. Crea un grupo de autoridades de certificación que se usará para la autoridad de certificación subordinada que emite certificados a la pasarela de entrada:

    gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --tier devops
    
    • SUBORDINATE_CA_POOL_GATEWAYS es el nombre del grupo de CAs. Por ejemplo, subordinate-ca-mtls-pool-gateways-tutorial.
  4. Crea y habilita la CA subordinada que emite certificados a la puerta de enlace de entrada:

    gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --subject "CN=Example Gateway mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS es el nombre que quieres usar para la autoridad de certificación subordinada. Por ejemplo, subordinate-ca-mtls-gateways-tutorial.
    • La marca --use-preset-profile configura la AC subordinada para que utilice el perfil de certificado mTLS subordinado. Este perfil permite que la CA subordinada emita certificados TLS de cliente y de servidor para mTLS.

    Si quieres que tu pasarela de entrada use TLS simple en lugar de mTLS, tu AC subordinada solo tiene que emitir certificados TLS de servidor. En este caso, puedes usar el perfil de certificado TLS de servidor subordinado (subordinate_server_tls_pathlen_0).

  5. Crea una política de emisión de certificados:

    cat << EOF > policy.yaml
    baselineValues:
      keyUsage:
        baseKeyUsage:
          digitalSignature: true
          keyEncipherment: true
        extendedKeyUsage:
          serverAuth: true
          clientAuth: true
      caOptions:
        isCa: false
    identityConstraints:
      allowSubjectPassthrough: false
      allowSubjectAltNamesPassthrough: true
      celExpression:
        expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") )
    EOF
    

    Esta política de emisión restringe a las CAs para que solo emitan certificados para cargas de trabajo de la malla.

  6. Crea un grupo de autoridades de certificación que se usará para la autoridad de certificación subordinada que emite certificados a los proxies sidecar de la malla. Aplica la política de emisión al grupo de ACs:

    gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \
     --issuance-policy policy.yaml \
     --location CA_LOCATION \
     --tier devops
    
    • SUBORDINATE_CA_POOL_SIDECARS es el nombre del grupo de CAs. Por ejemplo, subordinate-ca-mtls-pool-sidecars-tutorial.
  7. Crea y habilita la AC subordinada que emite certificados a los proxies sidecar de la malla:

    gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS es el nombre que quieres usar para la autoridad de certificación subordinada. Por ejemplo, subordinate-ca-mtls-sidecars-tutorial.

Crear un clúster de Google Kubernetes Engine

  1. En Cloud Shell, crea un clúster de GKE:

    gcloud container clusters create CLUSTER_NAME \
        --enable-ip-alias \
        --num-nodes 4 \
        --release-channel regular \
        --scopes cloud-platform \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
    

    Sustituye CLUSTER_NAME por el nombre que quieras usar para el clúster. Por ejemplo, asm-ingress-cert-manager-ca-service.

    Sustituye ZONE por la zona que quieras usar en el clúster. Por ejemplo, us-central1-f.

    Ten en cuenta lo siguiente sobre el comando:

    • La marca --release-channel selecciona el canal de lanzamiento de GKE del clúster.
    • Tanto Cloud Service Mesh como el emisor del servicio de CA de la herramienta cert-manager requieren que definas el ámbito cloud-platform en los nodos del clúster.
    • El argumento --workload-pool habilita Workload Identity Federation para GKE, lo que permite que la cuenta de servicio de Kubernetes del emisor del servicio de CA suplante la identidad de una cuenta de servicio de Google. Esta suplantación significa que los pods del emisor del servicio de CA pueden acceder a la API del servicio de CA sin descargar un archivo de claves de la cuenta de servicio de Google.
  2. Concede permisos de administrador de clúster a tu cuenta de usuario:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    Necesitas los permisos que proporciona el cluster-adminClusterRole de Kubernetes para crear las reglas de control de acceso basado en roles (RBAC) de Cloud Service Mesh e instalar la herramienta cert-manager.

Instalar el plano de control de Anthos Service Mesh

En este tutorial, instalarás Cloud Service Mesh gestionado en un clúster de GKE en Google Cloud, con todos los recursos en un proyecto. En tu propio entorno, puedes aplicar la solución descrita en este documento mediante Cloud Service Mesh gestionado o un plano de control en el clúster.

Cloud Service Mesh ofrece varias opciones de instalación para diferentes situaciones. Una vez que hayas completado este tutorial, te recomendamos que consultes la guía de instalación para seleccionar la opción que mejor se adapte a tu entorno.

  1. En Cloud Shell, descarga la herramienta de instalación asmcli:

    curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.26
    
    chmod +x asmcli
    

    Utilizas asmcli para instalar el plano de control de Cloud Service Mesh.

  2. Instala el plano de control de Cloud Service Mesh:

    ./asmcli install \
        --ca gcp_cas \
        --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \
        --cluster_location ZONE \
        --cluster_name CLUSTER_NAME \
        --enable_all \
        --enable_registration \
        --fleet_id PROJECT_ID \
        --managed \
        --output_dir asm-files \
        --project_id PROJECT_ID \
        --verbose
    

    La instalación tarda varios minutos. Cuando se haya completado la instalación, verás el siguiente resultado:

    asmcli: Successfully installed ASM.
    

Instalar la pasarela de entrada

  1. En Cloud Shell, crea un espacio de nombres de Kubernetes para el gateway de entrada:

    kubectl create namespace GATEWAY_NAMESPACE
    
    • GATEWAY_NAMESPACE es el nombre del espacio de nombres que quieres usar para la pasarela de entrada. Por ejemplo, istio-ingress.
  2. Reserva una dirección IP interna estática para usarla en el balanceador de carga de red de paso a través interno de la pasarela de entrada:

    LOAD_BALANCER_IP=$(gcloud compute addresses create \
        asm-ingress-gateway-ilb \
        --region REGION \
        --subnet default \
        --format 'value(address)')
    
    • Sustituye REGION por la región que contiene la zona o las zonas que usan los nodos de tu clúster de GKE. Por ejemplo, si tu clúster usa la zona us-central1-f, sustituye REGION por us-central1.

    Este comando reserva una dirección IP de la subred predeterminada de la región que especifiques.

  3. Crea un manifiesto de operador para la pasarela de entrada:

    cat << EOF > ingressgateway-operator.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      name: ingressgateway-operator
      annotations:
        config.kubernetes.io/local-config: "true"
    spec:
      profile: empty
      revision: asm-managed
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: GATEWAY_NAMESPACE
          enabled: true
          k8s:
            overlays:
            - apiVersion: apps/v1
              kind: Deployment
              name: istio-ingressgateway
              patches:
              - path: spec.template.metadata.annotations
                value:
                  inject.istio.io/templates: gateway
              - path: spec.template.metadata.labels.sidecar\.istio\.io/inject
                value: "true"
              - path: spec.template.spec.containers[name:istio-proxy]
                value:
                  name: istio-proxy
                  image: auto
            service:
              loadBalancerIP: $LOAD_BALANCER_IP
            serviceAnnotations:
              networking.gke.io/load-balancer-type: Internal
              networking.gke.io/internal-load-balancer-allow-global-access: "true"
    EOF
    

    Ten en cuenta lo siguiente sobre el manifiesto del operador:

  4. Crea el manifiesto de instalación de la pasarela de entrada con el manifiesto del operador y la herramienta istioctl que descargó la secuencia de comandos asmcli al instalar el plano de control:

    ./asm-files/istioctl manifest generate \
        --filename ingressgateway-operator.yaml \
        --output ingressgateway
    
  5. Instala la pasarela de entrada:

    kubectl apply --recursive --filename ingressgateway/
    

Instalar la herramienta cert-manager

  1. En Cloud Shell, descarga y aplica el manifiesto de instalación de la herramienta cert-manager:

    CERT_MANAGER_VERSION=v1.5.4
    
    curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
    
    kubectl apply --filename cert-manager.yaml
    

    La instalación de la herramienta cert-manager tarda aproximadamente un minuto en completarse.

Instalar el controlador del emisor del servicio de AC

El controlador de la entidad emisora del Servicio de Autoridades de Certificación permite que la herramienta cert-manager solicite certificados mediante el Servicio de Autoridades de Certificación. El controlador usa la herramienta cert-manager mecanismo de extensión emisor externo.

  1. En Cloud Shell, crea una cuenta de servicio de Google:

    gcloud iam service-accounts create CAS_ISSUER_GSA \
        --display-name "CA Service issuer for cert-manager"
    
    • CAS_ISSUER_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo, cert-manager-ca-service-issuer.

    El controlador de emisores de Servicio de Autoridades de Certificación usa esta cuenta de servicio de Google para autenticarse en las APIs de Servicio de Autoridades de Certificación.

  2. Crea un enlace de política de Gestión de Identidades y Accesos que permita a la cuenta de servicio de Google del controlador de emisores del Servicio de Autoridades de Certificación solicitar certificados del grupo de autoridades de certificación que contenga tu autoridad de certificación subordinada:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  3. Descarga el manifiesto de instalación del controlador de emisores del servicio de autoridad de certificación:

    CAS_ISSUER_VERSION=v0.5.3
    
    curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
    
  4. Crea un enlace de política de IAM para permitir que la cuenta de servicio de Kubernetes del espacio de nombres cert-manager ksa-google-cas-issuer suplante la identidad de la cuenta de servicio de Google (GSA) mediante Workload Identity Federation para GKE:

    gcloud iam service-accounts add-iam-policy-binding \
     CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    

    Los pods del controlador de emisores de CA Service usan la cuenta de servicio de Kubernetes ksa-google-cas-issuer.

  5. Instala el controlador del emisor del servicio de AC en tu clúster de GKE:

    kubectl apply --filename ca-service-issuer.yaml
    
  6. Añade la anotación de Workload Identity Federation para GKE iam.gke.io/gcp-service-account a la cuenta de servicio de Kubernetes que usan los pods del controlador del emisor del servicio de CA:

    kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \
       "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
    

    Esta anotación informa a GKE de que la cuenta de servicio de Kubernetes puede suplantar la identidad de la cuenta de servicio de Google para acceder a las APIs de Google.

Crear un emisor de certificados

  1. En Cloud Shell, crea y aplica un manifiesto de GoogleCASIssuer:

    cat << EOF > gateway-cas-issuer.yaml
    apiVersion: cas-issuer.jetstack.io/v1beta1
    kind: GoogleCASIssuer
    metadata:
      name: gateway-cas-issuer
      namespace: GATEWAY_NAMESPACE
    spec:
      caPoolId: SUBORDINATE_CA_POOL_GATEWAYS
      location: CA_LOCATION
      project: PROJECT_ID
    EOF
    
    kubectl apply --filename gateway-cas-issuer.yaml
    

    El emisor permite que la herramienta cert-manager aprovisione certificados de tu grupo de autoridades de certificación secundarias en el espacio de nombres de tu gateway de entrada.

Desplegar una aplicación de ejemplo

En esta sección, verificas que la herramienta cert-manager puede usar el emisor de CA Service para obtener certificados de CA Service. Para verificarlo, despliega una aplicación de ejemplo con una configuración de enrutamiento de solicitudes y un certificado para la pasarela de entrada.

  1. En Cloud Shell, crea un espacio de nombres para los recursos de la aplicación de ejemplo:

    cat << EOF > sample-app-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: APP_NAMESPACE
      annotations:
        mesh.cloud.google.com/proxy: '{"managed":"true"}'
      labels:
        istio.io/rev: asm-managed
    EOF
    
    kubectl apply --filename sample-app-namespace.yaml
    
    • APP_NAMESPACE es el nombre del espacio de nombres de la aplicación de ejemplo. Por ejemplo, sample-app.

    La anotación mesh.cloud.google.com/proxy habilita el plano de datos gestionado del espacio de nombres.

    La etiqueta istio.io/rev: asm-managed selecciona el canal de lanzamiento normal para el plano de datos gestionado en el espacio de nombres de la aplicación de ejemplo. Cambia el valor de esta etiqueta si usas los canales de lanzamiento Rápido o Estable.

  2. Crea un recurso Deployment para la aplicación de ejemplo:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: APP_NAMESPACE
      labels:
        app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - image: gcr.io/google-samples/hello-app:1.0
            name: hello-app
            ports:
            - containerPort: 8080
    EOF
    
    kubectl apply --filename deployment.yaml
    
  3. Crea un recurso Service para la aplicación de muestra:

    cat << EOF > service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
      namespace: APP_NAMESPACE
    spec:
      ports:
      - name: http-hello
        port: 8080
      selector:
        app: hello
      type: ClusterIP
    EOF
    
    kubectl apply --filename service.yaml
    
    • SERVICE_NAME es el nombre del servicio. Por ejemplo, hello.
  4. Crea un recurso Certificate para el nombre de dominio hello.example.com usando la entidad emisora de certificados:

    cat << EOF > certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: hello-example-com-certificate
      namespace: GATEWAY_NAMESPACE
    spec:
      secretName: hello-example-com-credential
      commonName: hello.example.com
      dnsNames:
      - hello.example.com
      duration: 24h
      renewBefore: 8h
      issuerRef:
        group: cas-issuer.jetstack.io
        kind: GoogleCASIssuer
        name: gateway-cas-issuer
    EOF
    
    kubectl apply --filename certificate.yaml
    

    El espacio de nombres del certificado debe coincidir con el espacio de nombres de la pasarela de entrada. Normalmente, solo los administradores de la plataforma pueden cambiar los recursos de este espacio de nombres, ya que los cambios pueden afectar a toda la malla de servicios. La herramienta cert-manager crea el recurso Secret para el certificado TLS en el mismo espacio de nombres. Esto significa que los administradores de aplicaciones no necesitan tener acceso al espacio de nombres de la pasarela de entrada.

    Puedes añadir nombres de host adicionales en la lista dnsNames del certificado. Estos nombres de host se incluyen en el certificado como nombres alternativos del sujeto (SANs).

  5. Crea un recurso Gateway para la aplicación de ejemplo:

    cat << EOF > gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - APP_NAMESPACE/hello.example.com
        port:
          name: https-hello
          number: 443
          protocol: HTTPS
        tls:
          credentialName: hello-example-com-credential
          mode: MUTUAL
    EOF
    
    kubectl apply --filename gateway.yaml
    
    • GATEWAY_NAME es el nombre de la pasarela. Por ejemplo, hello.
    • El campo credentialName de la puerta de enlace coincide con el campo secretName del certificado. La herramienta cert-manager crea un secreto de Kubernetes con el certificado TLS del servicio de CA. Este certificado permite que la pasarela de entrada finalice el tráfico TLS destinado a hello.example.com.

    El manifiesto de la pasarela especifica MUTUAL TLS (mTLS). Si quieres configurar la pasarela para usar TLS normal, define el modo TLS de la pasarela como SIMPLE.

  6. Crea un recurso VirtualService para la aplicación de ejemplo:

    cat << EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: hello
      namespace: APP_NAMESPACE
    spec:
      hosts:
      - hello.example.com
      gateways:
      - GATEWAY_NAMESPACE/GATEWAY_NAME
      http:
      - route:
        - destination:
            host: SERVICE_NAME
            port:
              number: 8080
    EOF
    
    kubectl apply --filename virtual-service.yaml
    

    Gateway y VirtualService usan espacios de nombres diferentes. Este patrón habitual restringe los cambios en el enrutamiento basado en el host de la puerta de enlace a los administradores de la plataforma que tienen permisos para cambiar los recursos en el espacio de nombres de la puerta de enlace de entrada.

    Los administradores de aplicaciones que tengan permisos para editar el VirtualService en el espacio de nombres de la aplicación de ejemplo pueden cambiar el enrutamiento por otros campos de solicitud, como la ruta de la URL, sin coordinarse con los administradores de la plataforma.

Si quieres consultar otras opciones de configuración, lee la documentación de la API de los recursos Certificate, Gateway y VirtualService.

Puedes aplicar políticas de autenticación y autorización al tráfico que entra en la malla de servicios a través de la puerta de enlace de entrada. Para ello, consulta la documentación de las APIs PeerAuthentication y AuthorizationPolicy de Istio.

Verificar la solución

En esta sección, verificará que puede enviar solicitudes HTTPS mediante mTLS a la aplicación de ejemplo desde fuera de la malla de servicios. Para verificarlo, crea una instancia de máquina virtual de Compute Engine, solicita un certificado TLS de cliente al servicio de AC y usa este certificado para autenticar la solicitud a la aplicación de ejemplo.

Necesitas acceso SSH a la instancia de VM. La red predeterminada incluye una regla de cortafuegos que permite el acceso SSH. Si no tienes acceso SSH, consulta la documentación sobre reglas de cortafuegos para crear una regla que permita las conexiones TCP entrantes en el puerto 22.

  1. En Cloud Shell, crea una cuenta de servicio de Google:

    gcloud iam service-accounts create CLIENT_VM_GSA \
        --display-name "CA Service tutorial VM instance service account"
    
    • CLIENT_VM_GSA es el nombre de la cuenta de servicio de Google. Por ejemplo, cas-tutorial-client.

    Asigna esta cuenta de servicio de Google a la instancia de VM de Compute Engine.

  2. Asigna el rol Solicitante del certificado del Servicio de Autoridades de Certificación al grupo de ACs secundarias de las pasarelas a la cuenta de servicio de Google:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    

    Este rol proporciona permisos para solicitar certificados del grupo de ACs.

  3. Crea una instancia de VM de Compute Engine en la misma VPC que el clúster de GKE:

    gcloud compute instances create cas-tutorial-client \
        --scopes cloud-platform \
        --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --zone ZONE
    

    La instancia de VM requiere el permiso cloud-platform para acceder a la API del servicio de CA.

  4. Guarda la dirección IP del balanceador de carga de red de paso a través interno de la pasarela de entrada en un archivo:

    kubectl get services istio-ingressgateway \
       --namespace GATEWAY_NAMESPACE \
       --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
    
  5. Guarda el certificado de clave pública de tu AC raíz en un archivo:

    gcloud privateca roots describe ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --format 'value(pemCaCertificates)' > root-ca-cert.pem
    
  6. Copia el certificado de AC raíz y el archivo que contiene la dirección IP del balanceador de carga de red interno de transferencia directa de la puerta de enlace de entrada en la instancia de VM:

    gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \
       --zone ZONE
    
  7. Conéctate a la instancia de VM mediante SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Ejecuta el resto de los comandos de esta sección desde la sesión SSH.

  8. Instala los paquetes ca-certificates y coreutils, así como las herramientas de línea de comandos curl, openssl y jq:

    sudo apt-get update --yes
    
    sudo apt-get install --yes ca-certificates coreutils curl jq openssl
    
  9. Crea un par de claves para el certificado TLS del cliente:

    openssl genrsa -out private-key.pem 2048
    
    openssl rsa -in private-key.pem -pubout -out public-key.pem
    
  10. Consulta el servidor de metadatos para obtener la dirección de correo de la identidad de la cuenta de servicio de Google asociada a la instancia de VM:

    GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
    
  11. Crea un archivo JSON que usarás como cuerpo de la solicitud al solicitar un certificado TLS de cliente a la API del Servicio de Autoridades de Certificación:

    cat << EOF > request.json
    {
      "config": {
        "publicKey": {
          "format": "PEM",
          "key": "$(base64 --wrap 0 public-key.pem)"
        },
        "subjectConfig": {
          "subject": {
            "commonName": "$(hostname --short)",
            "organization": "Example Organization"
          },
          "subjectAltName": {
            "dnsNames": [
              "$(hostname --fqdn)"
            ],
            "emailAddresses": [
              "$GSA_EMAIL"
            ]
          }
        },
        "x509Config": {
          "caOptions": {
            "isCa": false
          },
          "keyUsage": {
            "baseKeyUsage": {
              "digitalSignature": true,
              "keyEncipherment": true
            },
            "extendedKeyUsage": {
              "clientAuth": true
            }
          }
        }
      },
      "lifetime": "86400s"
    }
    EOF
    

    Para obtener más información sobre los campos de la sección de configuración, consulta el tipo CertificateConfig en la documentación de la API del servicio de CA.

  12. Solicita un token de acceso de OAuth 2.0 al servidor de metadatos:

    TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
    

    Este token de acceso proporciona los permisos concedidos a la cuenta de servicio de Google que está asociada a la instancia de VM.

  13. Solicita un certificado TLS de cliente a la API del servicio de AC y almacena el cuerpo de la respuesta en un archivo:

    curl --silent --request POST \
        --header "Authorization: Bearer $TOKEN" \
        --header "Content-Type: application/json" \
        --data @request.json \
        --output response.json \
        "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
    

    El comando usa el token de acceso para autenticar la solicitud de la API.

  14. Guarda el certificado de cliente y la cadena de certificados en un archivo:

    jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
    
  15. Usa curl para enviar una solicitud HTTPS desde la instancia de VM a la aplicación de ejemplo:

    curl --cert client-cert-chain.pem --key private-key.pem \
        --cacert root-ca-cert.pem \
        --resolve hello.example.com:443:$(cat ilb-ip.txt) \
        --silent https://hello.example.com | head -n1
    

    La salida tiene este aspecto:

    Hello, world!
    

    Esta respuesta muestra que curl ha enviado correctamente la solicitud HTTPS mediante mTLS. La aplicación de ejemplo ha respondido con el mensaje que ves en la salida del terminal.

    El comando curl hace lo siguiente:

    • Las marcas --cert y --key indican a curl que use el certificado TLS del cliente y la clave privada para autenticar la solicitud. El archivo de certificado de cliente contiene la cadena completa de certificados, desde el certificado de cliente hasta la AC raíz.

    • La marca --cacert indica a curl que verifique que la AC raíz que has creado en este tutorial o una de sus ACs subordinadas ha emitido el certificado de servidor.

      Si omite esta marca, curl intentará verificar el certificado del servidor utilizando el paquete de AC predeterminado de su sistema operativo, como el paquete ca-certificates en Debian. La verificación falla porque el paquete de AC predeterminado no incluye la AC raíz que has creado en este tutorial.

    • La marca --resolve indica a curl que use la dirección IP del balanceador de carga de red de transferencia interno como destino de las solicitudes para alojar hello.example.com en el puerto 443.

      Si omites esta marca, curl intentará usar el DNS para resolver el nombre de host hello.example.com. La resolución de DNS falla porque no hay ninguna entrada de DNS para este nombre de host.

      En tu propio entorno, te recomendamos que crees un registro A de DNS que apunte a la dirección IP del balanceador de carga de red interno de tipo pasarela ($LOAD_BALANCER_IP). Crea este registro con Cloud DNS siguiendo la documentación sobre gestión de registros.

    • La marca --silent suprime los informes de progreso de descarga de respuestas en la salida del terminal.

    • El comando canaliza la salida de curl a head -n1. El resultado es que la salida en la terminal solo incluye la primera línea del cuerpo de la respuesta.

  16. Cierra la sesión SSH:

    exit
    

En esta sección, has solicitado un certificado TLS de cliente directamente a la API del servicio de autoridad de certificación. En el caso de que el cliente sea la puerta de enlace de salida de otra malla de servicios en un clúster de Kubernetes independiente, puedes usar la herramienta cert-manager y el emisor del servicio de autoridad de certificación con la misma AC raíz para proporcionar certificados de cliente a la puerta de enlace de salida.

En otras situaciones, puedes usar herramientas como HashiCorp Vault, Terraform o gcloud para solicitar certificados TLS de cliente para cargas de trabajo fuera de la malla de servicios. Para obtener más información, consulta la documentación del servicio de CA sobre soluciones de ejemplo y la documentación de gcloud sobre el servicio de CA.

(Opcional) Añadir certificados de AC al almacén de confianza

En esta sección opcional se explica cómo añadir certificados de AC a la tienda de certificados de AC de confianza para la distribución Debian de Linux. Estas instrucciones también se aplican a las distribuciones derivadas de Debian, como Ubuntu.

Si añades tus certificados de AC a este almacén, no tendrás que especificar la ubicación de los certificados de AC de confianza al enviar solicitudes HTTPS con curl, Python, Go y Ruby.

  1. Conéctate a la instancia de VM mediante SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Ejecuta el resto de los comandos de esta sección desde la sesión SSH.

  2. Copia el certificado de la AC raíz en el directorio /usr/local/share/ca-certificates y asegúrate de que el archivo tenga la extensión .crt:

    sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
    
  3. Define los permisos del archivo para que todos los usuarios puedan leer el archivo del certificado de la AC raíz:

    sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
    
  4. Ejecuta la secuencia de comandos update-ca-certificates:

    sudo update-ca-certificates
    

    Esta secuencia de comandos añade el certificado al conjunto de certificados de confianza del directorio /etc/ssl/certs y al archivo /etc/ssl/certs/ca-certificates.crt.

    El resultado es el siguiente:

    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    
  5. Usa curl para enviar una solicitud HTTPS desde la instancia de VM a la aplicación de ejemplo:

    curl --cert client-cert-chain.pem --key private-key.pem \
       --resolve hello.example.com:443:$(cat ilb-ip.txt) \
       --silent https://hello.example.com | head -n1
    

    La salida tiene este aspecto:

    Hello, world!
    

    Esta respuesta muestra que curl ha enviado correctamente la solicitud HTTPS mediante mTLS y ha validado el certificado TLS del servidor de la puerta de enlace de entrada mediante el almacén de certificados de CA predeterminado.

  6. Cierra la sesión SSH:

    exit
    

Solucionar problemas

Si el controlador del emisor del servicio de CA no crea el secreto del certificado TLS, consulta los registros del controlador del emisor del servicio de CA:

kubectl logs deployment/google-cas-issuer --namespace cert-manager

Si tienes problemas para instalar Cloud Service Mesh, ejecuta la herramienta asmcli para validar tu proyecto de Cloud y tu clúster de GKE.

Si tienes otros problemas con este tutorial, te recomendamos que consultes estos documentos:

Limpieza

Para evitar que se sigan aplicando cargos a tu cuenta Google Cloud por los recursos utilizados en este tutorial, puedes eliminar el proyecto o los recursos.

Eliminar el proyecto

  1. En Cloud Shell, elimina el proyecto:

    gcloud projects delete PROJECT_ID
    

Eliminar los recursos

Si quieres conservar el Google Cloud proyecto que has usado en este tutorial, elimina los recursos:

  1. En Cloud Shell, da de baja el clúster de GKE de GKE Hub:

    gcloud container hub memberships unregister CLUSTER_NAME \
        --gke-cluster ZONE/CLUSTER_NAME
    
  2. Elimina el clúster de GKE:

    gcloud container clusters delete CLUSTER_NAME \
        --zone ZONE --async --quiet
    
  3. Elimina las vinculaciones de políticas de gestión de identidades y accesos del grupo de AC subordinada:

    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  4. Inhabilita y programa la eliminación de las ACs subordinadas y la AC raíz:

    gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca roots disable ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --quiet
    
    gcloud privateca roots delete ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --ignore-active-certificates \
        --quiet
    
  5. Elimina el enlace de la política de gestión de identidades y accesos de la cuenta de servicio de Google del controlador de emisores del servicio de AC:

    gcloud iam service-accounts remove-iam-policy-binding \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    
  6. Elimina las cuentas de servicio de Google:

    gcloud iam service-accounts delete --quiet \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
    
  7. Elimina la dirección IP reservada del balanceador de carga:

    gcloud compute addresses delete asm-ingress-gateway-ilb \
        --region REGION --quiet
    
  8. Elimina la instancia de VM de Compute Engine:

    gcloud compute instances delete cas-tutorial-client \
        --zone ZONE --quiet
    

Siguientes pasos