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 generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar 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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • 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.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • 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.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com
  12. 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_IDENTIFIER" --role=ROLE
    • Replace PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.

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:

    export ISTIO_VERSION=1.20.2
    curl -L https://istio.io/downloadIstio | TARGET_ARCH=$(uname -m) sh -
    
  2. Agrega la herramienta de línea de comandos istioctl a la ruta de acceso:

    cd istio-${ISTIO_VERSION}
    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 --region us-central1 istio-cluster --quiet
    

¿Qué sigue?

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