Configura la finalización de TLS en la puerta de enlace de entrada

Descripción general

En esta página, se muestra cómo configurar una terminación de TLS en la puerta de enlace de entrada en Cloud Service Mesh para administrar el tráfico HTTPS externo a tus servicios. Aprenderás a configurar la puerta de enlace para que realice comunicaciones seguras con TLS, lo que habilitará el acceso encriptado a tus aplicaciones. Este proceso aprovecha las capacidades de Cloud Service Mesh para exponer servicios de forma segura.

Antes de comenzar

Para completar los pasos de este documento, necesitas los siguientes recursos:

  • Un clúster de Kubernetes con Cloud Service Mesh instalado.

Configura tu entorno

Ejecuta los siguientes comandos desde una estación de trabajo que pueda acceder al clúster que deseas usar. Asegúrate de que la herramienta de kubectl esté configurada para usar el contexto de clúster específico del clúster.

  1. Configure las variables de entorno.

    export ASM_INGRESSGATEWAY_NAMESPACE=asm-ingressgateway
    export ASM_INGRESSGATEWAY_DEPLOYMENT_NAME=asm-ingressgateway
    export ASM_INGRESSGATEWAY_SERVICE_NAME=asm-ingressgateway
    
  2. La aplicación foo implementada en tu clúster Instálalo con lo siguiente:

    apiVersion: v1
    kind: Service
    metadata:
      name: foo
      namespace: foo
    spec:
      selector:
        app: test-backend
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: foo
      namespace: foo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: test-backend
      template:
        metadata:
          labels:
            app: test-backend
        spec:
          containers:
          - name: whereami
            image: gcr.io/google-samples/whereami:v1.2.23
            ports:
            - containerPort: 8080
    EOF
    
  3. Genera certificados y claves

Para proteger tu puerta de enlace de entrada, necesitarás certificados y claves TLS. Puedes usar cualquier herramienta de generación de certificados o seguir estos pasos con openssl para crear las credenciales necesarias.

  • Crea un certificado y una clave de AC raíz

    mkdir example_certs
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example Corp/CN=example.com' \
      -keyout example.com.key -out example.com.crt
    
  • Genera un certificado y una clave para la entrada

    openssl req -out foo.example.com.csr -newkey rsa:2048 -nodes \
      -keyout foo.example.com.key -subj "/CN=foo.example.com/O=Foo Org"
    
    openssl x509 -req -sha256 -days 365 -CA example.com.crt \
      -CAkey example.com.key -set_serial 0 \
      -in foo.example.com.csr -out foo.example.com.crt
    

Configura una puerta de enlace de entrada de TLS

Antes de completar las instrucciones de esta sección, deberás determinar la implementación de tu plano de control. Para ello, usa las instrucciones que se indican en Cómo identificar la implementación del plano de control.

  1. Crea el espacio de nombres. Este espacio de nombres se usa para implementar la puerta de enlace de entrada.

    kubectl create namespace ${ASM_INGRESSGATEWAY_NAMESPACE}
    
  2. Aplica la etiqueta de inserción predeterminada al espacio de nombres:

    kubectl label namespace ${ASM_INGRESSGATEWAY_NAMESPACE} \
        istio.io/rev- istio-injection=enabled --overwrite
    
  3. Aplica el archivo de manifiesto de la puerta de enlace de entrada.

    kubectl --namespace ${ASM_INGRESSGATEWAY_NAMESPACE} apply --filename https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml
    

    Resultado esperado:

    serviceaccount/asm-ingressgateway created
    role.rbac.authorization.k8s.io/asm-ingressgateway created
    rolebinding.rbac.authorization.k8s.io/asm-ingressgateway created
    deployment.apps/asm-ingressgateway created
    service/asm-ingressgateway created
    poddisruptionbudget.policy/asm-ingressgateway created
    horizontalpodautoscaler.autoscaling/asm-ingressgateway created
    
  4. Almacena las credenciales de TLS en un secreto de Kubernetes:

    kubectl create -n ${ASM_INGRESSGATEWAY_NAMESPACE} secret tls foo-credential \
      --key=example_certs/foo.example.com.key \
      --cert=example_certs/foo.example.com.crt
    
  5. Define la puerta de enlace de entrada: Crea un recurso de puerta de enlace para controlar el tráfico HTTPS en el puerto 443:

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1
    kind: Gateway
    metadata:
      name: secure-gateway
      namespace: ${ASM_INGRESSGATEWAY_NAMESPACE}
    spec:
      selector:
        app: asm-ingressgateway
        istio: ingressgateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        tls:
          mode: SIMPLE
          credentialName: foo-credential
        hosts:
        - "foo.example.com"
    EOF
    
  6. Enruta el tráfico al servicio foo: Define un VirtualService para dirigir el tráfico a la implementación de foo:

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: foo-routing
      namespace: ${ASM_INGRESSGATEWAY_NAMESPACE}
    spec:
      hosts:
      - "foo.example.com"
      gateways:
      - secure-gateway
      http:
      - match:
        - uri:
            prefix: /status
        - uri:
            prefix: /delay
        route:
        - destination:
            host: foo
            port:
              number: 8080
    EOF
    
  7. Configura el balanceador de cargas externo para que se conecte con la puerta de enlace de entrada del clúster.

  8. Prueba la conexión segura: Usa curl para verificar la configuración:

    export EXTERNAL_LB_IP_ADDRESS=EXTERNAL_LB_IP_ADDRESS
    curl -v -H "Host: foo.example.com" --resolve "foo.example.com:443:$EXTERNAL_LB_IP_ADDRESS" \
      --cacert example_certs/example.com.crt "https://foo.example.com:443/ping"
    

Reemplaza EXTERNAL_LB_IP_ADDRESS por la IP del balanceador de cargas externo.

El resultado es similar a este:

    {
      "cluster_name": "gke-us",
      "host_header": "34.120.175.141",
      "pod_name": "whereami-deployment-954cbf78-mtlpf",
      "pod_name_emoji": "😎",
      "project_id": "my-project",
      "timestamp": "2021-11-29T17:01:59",
      "zone": "us-central1-b"
    }

¿Qué sigue?