Proteger los servicios de Kubernetes con Istio

Este instructivo está dirigido a usuarios y administradores de Kubernetes que tienen interés en utilizar la malla de servicios de Istio para implementar con seguridad Services de Kubernetes y habilitar la comunicación mutua de TLS (mTLS).

Istio y Cloud Service Mesh

Istio no es un producto compatible de Google. Recomendamos ejecutar con Cloud Service Mesh. Para obtener más información, consulta Aprovisiona Cloud Service Mesh en un clúster de GKE Autopilot.

Cloud Service Mesh proporciona los siguientes beneficios:

  • Puedes aprovisionar la malla de servicios de Cloud administrada con la API de Fleet sin herramientas del cliente como istioctl.
  • Cloud Service Mesh inserta proxies de sidecar automáticamente en las cargas de trabajo sin otorgarles privilegios elevados a tus contenedores.
  • Puedes ver paneles enriquecidos para la malla y los servicios sin ninguna configuración adicional y, luego, usar estas métricas para configurar objetivos de nivel de servicio (SLO) y alertas para supervisar el estado de las aplicaciones.
  • El plano de control de Cloud Service Mesh administrado se actualiza automáticamente para garantizar que obtengas los parches de seguridad y las funciones más recientes.
  • El plano de datos administrado de Cloud Service Mesh actualiza automáticamente el archivo adicional en las cargas de trabajo para que no debas reiniciar los servicios cuando haya actualizaciones de proxy y parches de seguridad disponibles.
  • Cloud Service Mesh es un producto compatible y se puede configurar mediante las APIs de código abierto de Istio estándar. Para obtener más información, consulta características compatibles.

Objetivos

En este instructivo, se incluyen los siguientes pasos:

  • Crea un clúster de GKE Autopilot.
  • Instala Istio con la herramienta de línea de comandos de istioctl.
  • Implementa una aplicación de ejemplo para probar la autenticación mutua de TLS (mTLS).
  • Configura Istio para usar la autenticación mTLS para la comunicación de servicio a servicio mediante un recurso personalizado PeerAuthentication.
  • Verifica la autenticación de mTLS mediante el panel de Kiali

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para obtener una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios de Google Cloud nuevos cumplan con los requisitos para acceder a una prueba gratuita.

Cuando completes las tareas que se describen en este documento, podrás borrar los recursos que creaste para evitar que se te siga facturando. Para obtener más información, consulta Realiza una limpieza.

Antes de comenzar

Cloud Shell está preinstalado con el software que necesitas para este instructivo, incluido lo siguiente: kubectl, gcloud CLI y Terraform. Si no usas Cloud Shell, debes instalar gcloud CLI.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si usas un proveedor de identidad externo (IdP), primero debes Acceder a la gcloud CLI con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select 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 role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  7. Enable the GKE API:

    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.

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si usas un proveedor de identidad externo (IdP), primero debes Acceder a la gcloud CLI con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select 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 role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  13. Enable the GKE API:

    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.

    gcloud services enable container.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example, myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.
  15. Prepare el entorno

    Para configurar tu entorno, sigue estos pasos:

    1. Establece las variables de entorno:

      export PROJECT_ID=PROJECT_ID
      gcloud config set project $PROJECT_ID
      gcloud config set compute/region us-central1
      

      Reemplaza PROJECT_ID por el ID del proyecto de Google Cloud.

    2. Clona el repositorio de GitHub:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
      
    3. Cambia al directorio de trabajo:

      cd kubernetes-engine-samples/service-mesh/istio-tutorial
      

    Crea un clúster de GKE

    Habilita las funciones de Linux que requiere Istio: NET_RAW y NET_ADMIN. Autopilot de GKE no permite NET_ADMIN de forma predeterminada, pero puedes habilitar NET_ADMIN con el --workload-policies=allow-net-admin en GKE 1.27 y versiones posteriores:

    gcloud container clusters create-auto istio-cluster \
        --location="us-central1" \
        --workload-policies="allow-net-admin"
    

    Para obtener más información sobre la seguridad de GKE Autopilot, consulta Parámetros de configuración de seguridad integrados

    Instala Istio

    Puedes instalar Istio en un clúster de GKE usando Istioctl.

    En este instructivo, instalarás Istio con el archivo perfil de configuración recomendadas para implementaciones de producción.

    1. Instala Istio:

      • Para instalar la versión más reciente de Istio, haz lo siguiente:

        curl -L https://istio.io/downloadIstio | sh -
        
      • Para instalar una versión específica de Istio, haz lo siguiente:

        export ISTIO_VERSION=VERSION_NUMBER
        curl -L https://istio.io/downloadIstio | TARGET_ARCH=$(uname -m) sh -
        

        Reemplaza VERSION_NUMBER por la versión de Istio que deseas instalar. Para obtener información sobre las versiones de Istio, consulta los anuncios de versiones.

    2. Agrega la herramienta de línea de comandos istioctl a la ruta de acceso:

      cd istio-*
      export PATH=$PWD/bin:$PATH
      
    3. Instala Istio en el clúster:

      istioctl install --set profile="default" -y
      

      Este paso puede tardar varios minutos.

    4. Espera a que los Pods de Istio estén listos.

      watch kubectl get pods -n istio-system
      

      El resultado es similar al siguiente:

      NAME                                    READY   STATUS        RESTARTS   AGE
      istio-ingressgateway-5c47bff876-wjm96   1/1     Running       0          2m54s
      istiod-5fc7cb65cd-k8cp4                 1/1     Running       0          2m57s
      

      Cuando los Pods de Istio sean Running, presiona Ctrl+C para regresar a la línea de comandos.

    Implementa la aplicación de ejemplo

    En esta sección, usarás la aplicación de ejemplo Bank of Anthos para crear una malla de servicios con autenticación mTLS.

    1. Agregar una etiqueta de espacio de nombres que indique a Istio que habilite el permiso automático Inyección de proxies de sidecar de Envoy:

      kubectl label namespace default istio-injection=enabled
      
    2. Implementa la aplicación de ejemplo:

      cd ..
      git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git
      kubectl apply -f bank-of-anthos/extras/jwt/jwt-secret.yaml
      kubectl apply -f bank-of-anthos/kubernetes-manifests/
      
    3. Espera a que la aplicación esté lista:

      watch kubectl get pods
      

      El resultado es similar al siguiente:

      NAME                                 READY   STATUS    RESTARTS   AGE
      accounts-db-0                        2/2     Running   0          2m16s
      balancereader-5c695f78f5-x4wlz       2/2     Running   0          3m8s
      contacts-557fc79c5-5d7fg             2/2     Running   0          3m7s
      frontend-7dd589c5d7-b4cgq            2/2     Running   0          3m7s
      ledger-db-0                          2/2     Running   0          3m6s
      ledgerwriter-6497f5cf9b-25c6x        2/2     Running   0          3m5s
      loadgenerator-57f6896fd6-lx5df       2/2     Running   0          3m5s
      transactionhistory-6c498965f-tl2sk   2/2     Running   0          3m4s
      userservice-95f44b65b-mlk2p          2/2     Running   0          3m4s
      

      Cuando los Pods sean Running, vuelve a la línea de comandos presionando Ctrl+C

    4. Revisa el siguiente manifiesto:

      # Copyright 2020 Google LLC
      #
      # Licensed under the Apache License, Version 2.0 (the "License");
      # you may not use this file except in compliance with the License.
      # You may obtain a copy of the License at
      #
      #      http://www.apache.org/licenses/LICENSE-2.0
      #
      # Unless required by applicable law or agreed to in writing, software
      # distributed under the License is distributed on an "AS IS" BASIS,
      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      # See the License for the specific language governing permissions and
      # limitations under the License.
      
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: frontend-gateway
      spec:
        selector:
          istio: ingressgateway # use Istio default gateway implementation
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: frontend-ingress
      spec:
        hosts:
        - "*"
        gateways:
        - frontend-gateway
        http:
        - route:
          - destination:
              host: frontend
              port:
                number: 80

      En este manifiesto, se describe Istio Gateway y VirtualService recursos que exponen la aplicación y usan Istio Controlador de entrada.

    5. Aplica el manifiesto al clúster:

      kubectl apply -f bank-of-anthos/extras/istio/frontend-ingress.yaml
      

    Configurar mTLS

    La autenticación mutua de TLS (mTLS) está habilitada de forma predeterminada en Istio. Esto significa que Istio supervisa las cargas de trabajo del servidor que se migraron a proxies de Istio y configura automáticamente los proxies de cliente para establecer conexiones mTLS con estas cargas de trabajo. Istio también configura los proxies de cliente para que no usen mTLS cuando se conectan a cargas de trabajo sin proxies de sidecar.

    Istio puede configurar mTLS para que funcione en tres modos:

    • PERMISSIVE: Las cargas de trabajo aceptan mTLS y tráfico de texto sin formato.
    • STRICT: Las cargas de trabajo solo aceptan tráfico de mTLS.
    • DISABLE: mTLS está inhabilitado. Usa este modo si quieres usar tu propia solución de seguridad.

    Puedes aplicar la configuración de mTLS de manera global, por espacio de nombres o por carga de trabajo. En este instructivo, aplicarás la configuración por espacio de nombres con el modo de mTLS STRICT.

    1. Revisa el siguiente manifiesto:

      apiVersion: security.istio.io/v1beta1
      kind: PeerAuthentication
      metadata:
        name: default
      spec:
        mtls:
            mode: STRICT

      En este manifiesto, se describe un recurso personalizado de Istio de autenticación de intercambio de tráfico.

    2. Aplica el manifiesto al clúster:

      kubectl apply -f peer-authentication.yaml
      

    Para obtener más información sobre mTLS en Istio, consulta autenticación TLS mutua.

    Verifica que la mTLS esté habilitada

    Kiali es un panel de observabilidad basado en la Web para la malla de servicios de Istio que proporciona una vista gráfica del entorno de microservicios, lo que te permite supervisar y solucionar problemas de tus aplicaciones. Puedes usar Kiali para verificar que la autenticación de mTLS esté habilitada y funcione correctamente en la malla de servicios de Istio. Kiali requiere Prometheus como fuente de datos de telemetría. En este instructivo, se usa Google Cloud Managed Service para Prometheus.

    Instala una interfaz de consulta

    1. Crea una cuenta de servicio de IAM con roles/monitoring.viewer para permitir que la interfaz de consulta acceda a las métricas:

      gcloud iam service-accounts create monitoring \
          --display-name="Service account for query interface"
      gcloud projects add-iam-policy-binding PROJECT_ID \
          --member "serviceAccount:monitoring@PROJECT_ID.iam.gserviceaccount.com" \
          --role roles/monitoring.viewer
      gcloud iam service-accounts add-iam-policy-binding \
        monitoring@PROJECT_ID.iam.gserviceaccount.com \
          --role roles/iam.workloadIdentityUser \
          --member "serviceAccount:PROJECT_ID.svc.id.goog[monitoring/default]"
      
    2. Crea un espacio de nombres de Kubernetes:

      kubectl create namespace monitoring
      
    3. Anota la cuenta de servicio de Kubernetes predeterminada en el espacio de nombres para configurar la federación de identidades para cargas de trabajo para GKE:

      kubectl annotate serviceaccount -n monitoring default \
          iam.gke.io/gcp-service-account=monitoring@PROJECT_ID.iam.gserviceaccount.com --overwrite
      
    4. Implementa la carga de trabajo de la interfaz de consulta:

      kubectl -n monitoring apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
      
    5. Revisa el siguiente manifiesto:

      apiVersion: monitoring.googleapis.com/v1
      kind: PodMonitoring
      metadata:
        name: istiod
        namespace: istio-system
      spec:
        selector:
          matchLabels:
            app: istiod
        endpoints:
        - port: 15014
          path: /metrics
          timeout: 30s
          interval: 60s

      En este manifiesto, se describe un recurso PodMonitoring que recopila Istio y métricas del proxy de Envoy.

    6. Aplica el manifiesto al clúster:

      kubectl apply -f pod-monitorings.yaml
      
    7. Obtén un vínculo a la aplicación de ejemplo:

      INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
      echo "http://$INGRESS_HOST"
      
    8. Abre el vínculo para ver la aplicación de ejemplo. Accede con el nombre de usuario y la contraseña predeterminados para generar tráfico entre los microservicios.

    Instala Kiali

    Recomendamos que instales Kiali con el operador de Kiali.

    1. Instala el operador de Kiali:

      helm repo add kiali https://kiali.org/helm-charts
      helm repo update
      helm install \
          --namespace kiali-operator \
          --create-namespace \
          kiali-operator \
          kiali/kiali-operator
      
    2. Revisa el siguiente manifiesto:

      apiVersion: kiali.io/v1alpha1
      kind: Kiali
      metadata:
        name: kiali
        namespace: istio-system
      spec:
        deployment:
          namespace: istio-system
        auth:
          strategy: anonymous
        external_services:
          custom_dashboards:
            prometheus:
              url: "http://frontend.monitoring:9090/"
              auth:
                type: none
          prometheus:
            url: "http://frontend.monitoring:9090/"
            auth:
              type: none
          tracing:
            enabled: false
          grafana:
            enabled: false

      En este manifiesto, se describe un recurso personalizado de operador que define el servidor de Kiali.

    3. Aplica el manifiesto al clúster:

      kubectl apply -f kiali.yaml
      
    4. Espera a que el servidor de Kiali esté listo:

      watch kubectl get pods -n istio-system
      

      El resultado es similar al siguiente:

      NAME                                    READY   STATUS    RESTARTS   AGE
      istio-ingressgateway-6845466857-92zp8   1/1     Running   0          9m11s
      istiod-6b47d84cf-4cqlt                  1/1     Running   0          12m
      

      Cuando los Pods sean Running, vuelve a la línea de comandos presionando Ctrl+C

    5. Configura la redirección de puertos en el Service del servidor de Kiali para acceder al panel:

      kubectl -n istio-system port-forward svc/kiali 8080:20001
      
    6. Abre la vista previa en la Web. En Kiali, ve a la sección Graph y selecciona la opción Security en el menú desplegable Display. En esta vista, se muestra el estado de seguridad de cada nodo en el gráfico. Nodos con una insignia de mTLS habilitado indican que mTLS está habilitado para ese servicio y los nodos sin la insignia indican que no se habilitó mTLS.

    Limpia

    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

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Borra los recursos individuales

    Si usaste un proyecto existente y no quieres borrarlo, borra los recursos individuales.

    1. Borra Kiali:

      kubectl -n istio-system delete kiali kiali
      helm uninstall --namespace kiali-operator kiali-operator
      
    2. Borra los recursos de supervisión:

      kubectl -n monitoring delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
      
    3. Borra la aplicación de muestra:

      kubectl delete -f bank-of-anthos/extras/istio/frontend-ingress.yaml
      kubectl delete -f bank-of-anthos/kubernetes-manifests
      
    4. Desinstala Istio:

      istioctl uninstall --purge -y
      
    5. Borra el clúster de GKE:

      gcloud container clusters delete --location us-central1 istio-cluster --quiet
      

    ¿Qué sigue?

    • Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.