Proteger servicios de Kubernetes con Istio

Este tutorial está dirigido a usuarios y administradores de Kubernetes que quieran usar la malla de servicios de Istio para desplegar servicios de Kubernetes de forma segura y habilitar la comunicación TLS mutua (mTLS).

Istio y Cloud Service Mesh

Istio no es un producto de Google admitido. Te recomendamos que ejecutes Cloud Service Mesh gestionado. Para obtener más información, consulta Aprovisionar Cloud Service Mesh en un clúster Autopilot de GKE.

Cloud Service Mesh ofrece las siguientes ventajas:

  • Puedes aprovisionar Cloud Service Mesh gestionado con la API Fleet sin herramientas del lado del cliente como istioctl.
  • Cloud Service Mesh inserta automáticamente proxies sidecar en las cargas de trabajo sin conceder privilegios elevados a tus contenedores.
  • Puedes ver paneles de control detallados de tu malla y tus servicios sin necesidad de realizar ninguna configuración adicional. Después, puedes usar estas métricas para configurar objetivos de nivel de servicio (SLOs) y alertas para monitorizar el estado de tus aplicaciones.
  • El plano de control gestionado de Cloud Service Mesh se actualiza automáticamente para que obtengas los parches de seguridad y las funciones más recientes.
  • El plano de datos gestionado de Cloud Service Mesh actualiza automáticamente los proxies sidecar de tus cargas de trabajo, por lo que no tienes que reiniciar los servicios tú mismo cuando haya disponibles actualizaciones de proxy y parches de seguridad.
  • Cloud Service Mesh es un producto compatible que se puede configurar mediante APIs de Istio de código abierto estándar. Para obtener más información, consulta las funciones admitidas.

Objetivos

Este tutorial incluye los siguientes pasos:

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

Costes

En este documento, se utilizan 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 pueden disfrutar de una prueba gratuita. Google Cloud

Cuando termines las tareas que se describen en este documento, 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

Cloud Shell tiene preinstalado el software que necesitas para este tutorial, como kubectl, la CLI de gcloud y Terraform. Si no usas Cloud Shell, debes instalar la CLI de gcloud.

  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 utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud 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 utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud 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. Preparar el entorno

    Para configurar tu entorno, sigue estos pasos:

    1. Define las variables de entorno:

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

      Sustituye PROJECT_ID por el Google Cloud ID de tu proyecto.

    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
      

    Crear un clúster de GKE

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

    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 Autopilot de GKE, consulta las configuraciones de seguridad integradas.

    Instalar Istio

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

    En este tutorial, instalarás Istio con el perfil de configuración predeterminado, que se recomienda para las implementaciones de producción.

    1. Instala Istio:

      • Para instalar la versión más reciente de Istio, sigue estos pasos:

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

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

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

    2. Añade la herramienta de línea de comandos istioctl a la variable PATH:

      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 debería ser 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 estén Running, vuelve a la línea de comandos pulsando Ctrl+C.

    Desplegar 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. Añade una etiqueta de espacio de nombres que indique a Istio que habilite la inyección automática de proxies sidecar de Envoy:

      kubectl label namespace default istio-injection=enabled
      
    2. Despliega 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 debería ser 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 estén Running, vuelve a la línea de comandos pulsando Ctrl+C.

    4. Revisa el siguiente archivo de 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

      Este manifiesto describe los recursos Gateway y VirtualService de Istio que exponen la aplicación y usan Istio como controlador de entrada.

    5. Aplica el manifiesto a tu clúster:

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

    Configurar mTLS

    La autenticación TLS mutua (mTLS) está habilitada de forma predeterminada en Istio. Esto significa que Istio monitoriza las cargas de trabajo del servidor que se han migrado 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 al conectarse a cargas de trabajo sin proxies sidecar.

    Istio puede configurar mTLS para que funcione de tres formas:

    • PERMISSIVE: las cargas de trabajo aceptan tanto el tráfico mTLS como el de texto sin formato.
    • STRICT: las cargas de trabajo solo aceptan tráfico 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 forma global, por espacio de nombres o por carga de trabajo. En este tutorial, aplicarás la configuración por espacio de nombres mediante el modo STRICT mTLS.

    1. Revisa el siguiente archivo de manifiesto:

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

      Este manifiesto describe un recurso personalizado de Istio de autenticación entre pares.

    2. Aplica el manifiesto a tu clúster:

      kubectl apply -f peer-authentication.yaml
      

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

    Verificar que mTLS esté habilitado

    Kiali es un panel de control de observabilidad basado en web para la malla de servicios de Istio que proporciona una vista gráfica de tu entorno de microservicios, lo que te permite monitorizar tus aplicaciones y solucionar problemas. Puedes usar Kiali para verificar que la autenticación 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 tutorial se usa Google Cloud Managed Service para Prometheus.

    Instalar una interfaz de consulta

    1. Crea una cuenta de servicio de gestión de identidades y accesos con el rol 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 Workload Identity Federation para GKE:

      kubectl annotate serviceaccount -n monitoring default \
          iam.gke.io/gcp-service-account=monitoring@PROJECT_ID.iam.gserviceaccount.com --overwrite
      
    4. Despliega 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 archivo de 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

      Este manifiesto describe un recurso PodMonitoring que recoge métricas de Istio y Envoy Proxy.

    6. Aplica el manifiesto a tu clúster:

      kubectl apply -f pod-monitorings.yaml
      
    7. Obtén un enlace 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 enlace para ver la aplicación de ejemplo. Inicia sesión con el nombre de usuario y la contraseña predeterminados para generar tráfico entre los microservicios.

    Instalar Kiali

    Te 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 archivo de 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

      Este manifiesto describe un recurso personalizado de Operator que define el servidor de Kiali.

    3. Aplica el manifiesto a tu 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 debería ser 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 estén Running, vuelve a la línea de comandos pulsando Ctrl+C.

    5. Configura el reenvío de puertos en el servicio del servidor de Kiali para acceder al panel de control:

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

    Limpieza

    Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

    Eliminar el proyecto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Eliminar los recursos concretos

    Si has usado un proyecto que ya existía y no quieres eliminarlo, elimina los recursos concretos.

    1. Eliminar Kiali:

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

      kubectl -n monitoring delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
      
    3. Elimina 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. Elimina el clúster de GKE:

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

    Siguientes pasos