Trabajar con Istio como programa independiente

Descubra cómo instalar Istio como un programa independiente en clusters que ha creado con Kubernetes Engine (OKE).

En este tema se proporciona un ejemplo de cómo instalar Istio como programa independiente en clusters que ha creado con Kubernetes Engine (OKE). Además, se demuestran las características clave de OKE e Istio.

Los temas que se incluyen:

Tenga en cuenta que los productos de malla de servicios (como Oracle Cloud Infrastructure Service Mesh, Istio y Linkerd) están soportados al utilizar el plugin CNI de red de pod nativo de VCN de OCI para redes de pod. Tenga en cuenta que, a excepción del complemento Istio, actualmente el soporte está limitado a Oracle Linux 7 (el soporte de Oracle Linux 8 está planificado). El complemento Istio está soportado con Oracle Linux 7 y Oracle Linux 8. Los nodos de trabajador deben ejecutar Kubernetes 1.26 (o posterior).

Nota

Puede utilizar Istio con pools de nodos gestionados, pero no con pools de nodos virtuales.

Instalación de Istio como programa independiente

Para comenzar a utilizar Istio, cree un cluster de OKE o utilice un cluster de OKE existente y, a continuación, instale Istio. En las secciones que se proporcionan a continuación, se describen los pasos para instalar y probar la configuración de Istio. Para obtener una lista completa de las opciones de instalación, consulte aquí.

Creación de un cluster de OKE

Cree un cluster de OKE.

  1. Si aún no lo ha hecho, cree un cluster de OKE en su arrendamiento de OCI. Hay varias opciones disponibles para crear un cluster de OKE. La opción más sencilla es el asistente de creación rápida en la consola web.
  2. Para acceder al cluster de OKE en la máquina local, instale kubectl y oci-cli.
  3. Acceda al cluster de OKE desde la línea de comandos mediante kubectl configurando el archivo kubeconfig y asegúrese de que kubectl pueda acceder al cluster.

Descarga de Istio desde la línea de comandos

Siga estos pasos para descargar Istio desde la línea de comandos.

  1. Descargue Istio ejecutando el siguiente comando:
    curl -L https://istio.io/downloadIstio | sh -
  2. Vaya al directorio del paquete Istio. Por ejemplo, si el paquete es istio-1.11.2:
    cd istio-1.11.2
  3. Agregue la herramienta de cliente istioctl a PATH para la estación de trabajo.
    export PATH=$PWD/bin:$PATH
  4. Valide si el cluster cumple los requisitos de instalación de Istio ejecutando la comprobación previa:
    istioctl x precheck

Instalación de Istio con istioctl

Instale Istio con istioctl mediante el siguiente comando:
istioctl install

Ejecución de la aplicación Bookinfo

El proyecto Istio proporciona la aplicación Bookinfo como una forma de demostrar las características de Istio. La aplicación muestra información sobre un libro, similar a una única entrada de catálogo de una tienda de libros en línea. Cada página de libro contiene una descripción del libro, detalles sobre el libro (ISBN, número de páginas) y algunas reseñas de libros. Para obtener más información sobre la aplicación Bookinfo, consulte los documentos de Bookinfo aquí.

Diagrama de la aplicación Bookinfo

Como puede ver en el diagrama, la aplicación Bookinfo se compone de cuatro microservicios.

  • Servicio de página de producto: llama a los servicios Detalles y Revisiones para crear una página de producto.
  • Servicio de detalles: devuelve información del libro.
  • Servicio de revisiones: devuelve las revisiones de libros y llama al servicio Calificaciones.
  • Servicio de calificaciones: devuelve información de clasificación para una revisión de libro.

Para instalar y ejecutar la aplicación Bookinfo, siga estos pasos.

  1. Etiquete el espacio de nombres que aloja la aplicación con istio-injection=enabled.
    kubectl label namespace default istio-injection=enabled
  2. Despliegue la aplicación Bookinfo de ejemplo.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  3. Verifique que todos los servicios y pods se estén ejecutando.
    kubectl get services
    kubectl get pods
  4. Confirme que la aplicación se está ejecutando enviando un comando curl desde un pod.
    kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
  5. Haga que se pueda acceder a la aplicación desde fuera del cluster.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  6. Verifique que la aplicación esté utilizando el gateway. Determine INGRESS_HOST y INGRESS_PORT mediante estas instrucciones.
    curl -s "http://${INGRESS_HOST}:${INGRESS_PORT}/productpage" | grep -o "<title>.*</title>"

Además, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador para ver la página web de Bookinfo. Actualice la página varias veces para ver las diferentes versiones de revisiones que se muestran en la página del producto.

Adición de aplicaciones de integración de Istio

Istio se integra bien con varias aplicaciones populares relacionadas con Kubernetes.

Prometheus

Istio proporciona una instalación básica de ejemplo para poner en marcha rápidamente Prometheus.

kubectl apply -f samples/addons/prometheus.yaml

También puede instalar prometheus y configurar para raspar las métricas de Istio.

Para la supervisión a escala de producción mediante Prometheus, consulte Uso de Prometheus para la supervisión a escala de producción.

Grafana

Istio proporciona una instalación básica de ejemplo para que Grafana funcione rápidamente. Todos los paneles de control de Istio se incluyen en la instalación.

kubectl apply -f samples/addons/grafana.yaml

Como alternativa, instale Grafana por separado. Además, se pueden importar paneles de control preconfigurados de Istio.

Jaeger

Istio proporciona una instalación de ejemplo básica para poner en marcha Jaeger rápidamente.

kubectl apply -f samples/addons/jaeger.yaml

Como alternativa, instale Jaeger por separado y configure Istio para enviar rastreos a la implementación de Jaeger.

Zipkin

Istio proporciona una instalación básica de ejemplo para poner en marcha rápidamente zipkin.

kubectl apply -f samples/addons/extras/zipkin.yaml

También puede instalar zipkin por separado y configurar Istio para enviar rastreos al despliegue de zipkin.

Kiali

Istio proporciona una instalación de ejemplo básica para poner en marcha Kiali rápidamente:

kubectl apply -f samples/addons/kiali.yaml
            

También puede instalar y configurar Kiali por separado.

Exploración de la observabilidad de Istio

En esta sección, explore las métricas de rendimiento y las funciones de rastreo proporcionadas por las aplicaciones de integración de Istio.

Consulta de métricas de Prometheus para la aplicación Bookinfo

Con Prometeo e Istio, los datos de rendimiento de Bookinfo se analizan de varias maneras.

Primero, verifique que Prometeo está instalado.

kubectl -n istio-system get svc prometheus

Inicie la interfaz de usuario de Prometheus con el siguiente comando:

istioctl dashboard prometheus

Haga clic en Gráfico a la derecha de Prometeo en el encabezado. Para ver algunos datos, genere tráfico para la página del producto mediante un explorador o curl. El tráfico se refleja en el panel de Prometheus.

Visualización de métricas para la aplicación Bookinfo con Grafana

La combinación de Prometheus con Grafana proporciona algunos paneles de control de rendimiento agradables para las aplicaciones. Para utilizar los paneles de control, compruebe primero que Prometheus y Grafana están instalados.

kubectl -n istio-system get svc prometheus
kubectl -n istio-system get svc grafana

Inicie el panel de control de Istio Grafana.

istioctl dashboard grafana

Gestión de paneles de Grafana

La malla de servicios de Istio ofrece seis paneles de control de Grafana. Aquí se capturan las instantáneas del panel de control de Grafana de la malla de servicios de Istio.

Nota

Genere tráfico a la página del producto mediante un explorador o curl y vea que se refleja en el panel de control de Grafana.

Panel de control de Istio Mesh

Instantánea de panel de control de Istio Mesh

Panel de Control de Servicios de Istio

Instantánea de panel de control de servicio de Istio

Panel de control de carga de trabajo de Istio

Instantánea del panel de control de carga de trabajo de Istio

Panel de Control de Rendimiento de Istio

Instantánea de panel de control de rendimiento de Istio

Panel de control de Istio

Instantánea del panel de control de Istio

Para obtener más información sobre cómo crear, configurar y editar paneles de control, consulte la documentación de Grafana.

Realización de Rastreo Distribuido mediante Jaeger

Utilice el marco de código abierto de Jaeger para realizar el rastreo de aplicaciones con Istio.

  1. Active y configure el rastreo mediante istioctl:
    istioctl install --set meshConfig.enableTracing=true
  2. Con la aplicación Bookinfo desplegada, abra la interfaz de usuario de Jaeger mediante istioctl.
    istioctl dashboard jaeger
  3. Para generar rastreos, envíe solicitudes a la página del producto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Verá que los rastreos se reflejan en el panel de control de Jaeger.

Panel de control de Jaeger

Instantánea de panel de control de Istio Jaeger

Seguimiento de Aplicación Jaeger

Instantánea de rastreo de aplicación de Istio Jaeger

Realización de Rastreo Distribuido mediante zipkin

Utilice el marco de código abierto zipkin para realizar el rastreo de aplicaciones con Istio.

  1. Active y configure el rastreo mediante istioctl.
    istioctl install --set meshConfig.enableTracing=true
  2. Con la aplicación Bookinfo desplegada, abra la interfaz de usuario zipkin mediante istioctl.
    istioctl dashboard zipkin
  3. Para generar rastreos, envíe solicitudes a la página del producto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Verá que los rastreos se reflejan en el panel de control zipkin.

Ejemplo de panel de control zipkin

Instantánea de panel de control de Istio Zipkin

Realización de un rastreo distribuido con OCI Application Performance Monitoring

OCI Application Performance Monitoring (APM) se integra con herramientas del sistema de rastreo de código abierto como Jaeger y zipkin. APM permite cargar datos de rastreo en OCI. Para realizar la integración con OCI APM, cree un dominio de APM siguiendo las instrucciones mencionadas aquí. Un dominio de APM es un recurso de OCI que contiene los sistemas supervisados por APM.

Una vez creado el dominio, consulte los detalles del dominio y obtenga el punto final de carga de datos, la clave privada y la clave pública para crear la URL del recopilador de APM. La URL del recopilador de APM es necesaria al configurar rastreadores de código abierto para comunicarse con el servicio APM. El formato de URL de recopilador necesita una URL creada utilizando el punto final de carga de datos como URL base y genera la ruta de acceso en función de las opciones, incluidos los valores de nuestra clave privada o pública. El formato se documenta aquí. Con la ruta de URL construida, conecte la URL a la configuración de Istio.

Nota

Para obtener información más detallada sobre la configuración de políticas de servicio de APM, consulte:

Configuración de Istio para enviar rastreos a APM

  1. Active el rastreo con istioctl.
    istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
    Nota

    La dirección de punto final de aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com es un ejemplo y no un punto final real.
  2. Configure Envoy para enviar los rastreos de zipkin a APM. Sustituya el código de samples/custom-bootstrap/custom-bootstrap.yaml por el siguiente bloque de código.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: default
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  3. Aplique la configuración personalizada.
    kubectl apply -f samples/custom-bootstrap/custom-bootstrap.yaml
  4. Para que todos nuestros servicios de Bookinfo utilicen esta configuración de inicialización personalizada, agregue una anotación sidecar.istio.io/bootstrapOverride con el nombre de ConfigMap personalizado como valor. En el siguiente ejemplo, se agrega una anotación para la página del producto en samples/bookinfo/platform/kube/bookinfo.yaml. Agregue una anotación similar a otros servicios.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
          annotations:
            sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config" #[Name of custom configmap]
        spec:
          serviceAccountName: bookinfo-productpage
          containers:
            - name: productpage
              image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 9080
              volumeMounts:
                - name: tmp
                  mountPath: /tmp
              securityContext:
                runAsUser: 1000
          volumes:
            - name: tmp
              emptyDir: {}
    ---
  5. Aplique el yaml, todos los pods reiniciados empezarán a enviar rastreos a APM.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  6. Para permitir que una puerta de enlace de entrada envíe rastreos, cree un configmap denominado custom-bootstrap.yaml en el espacio de nombres istio-system:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: istio-system
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  7. Cree un parche denominado gateway-patch.yaml para que el gateway de entrada empiece a utilizar la configuración custom-bootstrap:
    spec:
      template:
        spec:
          containers:
          - name: istio-proxy
            env:
            - name: ISTIO_BOOTSTRAP_OVERRIDE
              value: /etc/istio/custom-bootstrap/custom_bootstrap.json
            volumeMounts:
            - mountPath: /etc/istio/custom-bootstrap
              name: custom-bootstrap-volume
              readOnly: true
          volumes:
          - configMap:
              name: istio-custom-bootstrap-config
              defaultMode: 420
              optional: false
            name: custom-bootstrap-volume
  8. Aplique el parche anterior para el gateway de entrada:
    kubectl --namespace istio-system patch deployment istio-ingressgateway --patch "$(cat gateway-patch.yaml)"
  9. Para generar rastreos, envíe solicitudes a la página del producto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Puede ver que los rastreos se reflejan en el panel de control de APM siguiendo los pasos aquí.

Zipkin Trace Explorer

Captura de pantalla del explorador de rastreo de Zipkin

Zipkin Trace

Captura de pantalla de un rastreo de Zipkin

Intervalos Zipkin

Para ver los intervalos, haga clic en Home en la lista APM.

Captura de pantalla de un período de Zipkin

Panel de control de la aplicación Zipkin

APM proporciona funcionalidad para crear paneles de control y explorar los períodos generados a lo largo del tiempo. Para crear paneles de control, siga los pasos que se indican aquí.

Captura de pantalla de un panel de control de la aplicación Zipkin

Explorador de métricas de Zipkin

APM le permite supervisar el estado, la capacidad y el rendimiento de las aplicaciones mediante métricas, alarmas y notificaciones. Siga los pasos aquí para configurar métricas.

Captura de pantalla de un explorador de métricas de Zipkin

Observación de logs con OCI Logging

OCI Logging es un componente central para analizar y buscar entradas de archivos log para arrendamientos en OCI. Los logs de contenedor de Kubernetes de los nodos de trabajador de OKE se pueden publicar como logs personalizados en OCI Logging. Siga los pasos que se describen aquí para configurar OCI Logging para ingerir logs de contenedor.

  1. Active el registro de acceso de enviado en Istio con istioctl.
    istioctl install --set meshConfig.accessLogFile=/dev/stdout
  2. Acceda a la página del producto Bookinfo utilizando un explorador o una curl. Los logs de acceso generados se pueden ver mediante el comando kubectl.
    kubectl logs -l app=productpage -c istio-proxy

Si OCI Logging está configurado para el cluster, estos logs se pueden consultar y analizar mediante la página de búsqueda de logs de la consola de OCI.

Búsqueda de OCI Logging

Captura de pantalla de una búsqueda de OCI Logging

Búsqueda de OCI Logging ampliada

Captura de pantalla de una búsqueda ampliada de OCI Logging

Visualización de malla con Kiali

Verifique que Kiali esté instalado.

kubectl -n istio-system get svc kiali

Abra la interfaz de usuario de Kiali en el explorador.

istioctl dashboard kiali

Envía un poco de tráfico a la página del producto.

for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Visualice su malla en Kiali siguiendo el paso 5 desde aquí.

Gestión del Tráfico

Las reglas de enrutamiento de tráfico de Istio le permiten controlar el flujo de tráfico entre servicios y simplifican la configuración de propiedades de nivel de servicio como disyuntores, timeouts y reintentos. Istio facilita la configuración de tareas importantes, como pruebas A/B, lanzamientos canarios e implementaciones temporales con divisiones de tráfico basadas en porcentajes.

Recursos de API de gestión de tráfico de Istio:

Para que Istio controle el enrutamiento de la versión de la aplicación Bookinfo, defina todas las versiones disponibles del servicio, denominadas subconjuntos, en las reglas de destino. Cree reglas de destino por defecto para los servicios Bookinfo:
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Cambio de tráfico

Istio nos permite migrar el tráfico gradualmente de una versión de un microservicio a otra versión mediante la función de enrutamiento ponderado de Istio. El siguiente ejemplo muestra cómo configurar el envío del 50% del tráfico a reviews:v1 y del 50% a reviews:v3. Después de eso, complete la migración enviando el 100% del tráfico a reviews:v3.

  1. Enrute todo el tráfico a la versión v1 de cada microservicio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

    Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador. Observe que la parte de revisiones de la página se muestra sin estrellas de calificación, independientemente de cuántas veces se refresque. Istio está configurado para enrutar todo el tráfico del servicio de revisiones a reviews:v1 y esta versión del servicio no accede al servicio de calificaciones por estrellas.

  2. Transfiera el 50% del tráfico de reviews:v1 a reviews:v3 con el siguiente comando y espere a que se propaguen las nuevas reglas.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

    Refresque la URL de /productpage en el explorador y vea las calificaciones de estrellas de color rojo aproximadamente el 50% del tiempo. reviews:v3 accede al servicio de calificaciones por estrellas, pero la versión reviews:v1 no.

  3. Ahora dirija el 100% del tráfico a reviews:v3.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
  4. Refresque la URL /productpage en el explorador y vea las calificaciones de estrellas de color rojo todo el tiempo para cada revisión.

Gestión de enrutamiento de solicitudes

Istio puede enrutar el tráfico de varias maneras. Para empezar, configure Istio para enrutar todo el tráfico a través de v1 de cada microservicio.
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador . Observe que la parte de revisiones de la página se muestra sin estrellas de calificación, independientemente de cuántas veces se refresque. Porque Istio está configurado para enrutar todo el tráfico del servicio de revisiones a la versión reviews:v1. Esta versión del servicio no accede al servicio de estrellas.

Captura de pantalla de un libro de Booinfo de muestra.

Enrutamiento basado en identidad de usuario

Para enrutar según la identidad del usuario:

  1. Cambie la configuración de ruta para que todo el tráfico de un usuario específico denominado jason se direccione a reviews:v2. Istio no tiene ninguna comprensión especial e integrada de la identidad del usuario. En este ejemplo, el servicio productpage agrega una cabecera de usuario final personalizada a todas las solicitudes HTTP salientes al servicio de revisiones.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. Para ver la página web de Bookinfo e iniciar sesión como usuario jason, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador. Actualiza el navegador para ver que las valoraciones de estrellas aparecen junto a cada valoración.

    Captura de pantalla de un libro de muestra de Booinfo con estrellas
  3. Abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador para ver la página web de Bookinfo e iniciar sesión como usuario que no sea jason. Actualice el explorador para que no aparezca ninguna estrella para cada revisión.

    Captura de pantalla de un libro de muestra de Booinfo sin estrellas

Enrutamiento basado en reescritura de URL

En este ejemplo, las solicitudes HTTP con una ruta que empieza por /products o /bookinfoproductpage se reescriben en /productpage. Las solicitudes HTTP se envían a los pods con productpage en ejecución en el puerto 9080. Para obtener más información sobre la reescritura de URL de Istio, consulte aquí.

  1. Aplique el siguiente yaml:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            prefix: /products
        - uri:
            prefix: /bookinfoproductpage
        rewrite:
          uri: /productpage
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  2. Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/products y http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage en un explorador. En ambos casos, se realiza una reescritura antes de reenviar la solicitud.

    Reescribir /bookproductpage

    Captura de pantalla de un libro de Booinfo de muestra con /bookproductpage

    Reescribir /productos

    Captura de pantalla de un libro de Booinfo de muestra con /products
  3. Limpie el archivo yaml a la versión original proporcionada por Istio y aplíquelo.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  4. Abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage o http://${INGRESS_HOST}:${INGRESS_PORT}/products para no ver la página del producto porque el yaml no reescribe la solicitud.

    Error 404 /productos

    Captura de pantalla de un libro de muestra de Booinfo con /products 404

    Error 404 /booksproductpage

    Captura de pantalla de un libro de Booinfo de muestra con /booksproductpage 404

Prueba de resiliencia de red

Istio le permite configurar su instalación para tiempos de espera de solicitud, inyección de fallos y disyuntores. Esta configuración permite gestionar y probar la tolerancia a fallos de las aplicaciones desplegadas.

Definición de Timeouts de Solicitud

Un timeout es la cantidad de tiempo que un proxy de Envoy espera las respuestas de un servicio determinado. El tiempo de espera garantiza que los servicios no esperen las respuestas indefinidamente y garantiza que las llamadas se realicen correctamente o fallen dentro de un marco de tiempo predecible. Para obtener más información sobre los timeouts, consulte aquí.

Se puede especificar un timeout para las solicitudes HTTP mediante el campo de timeout de la regla de rutas. Por defecto, el timeout de solicitud está desactivado.

  1. Inicialice el enrutamiento de la versión de la aplicación ejecutando el siguiente comando:
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Enrutar solicitudes al servicio reviews:v2, en efecto, una versión que llama al servicio de calificaciones:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
    EOF
  3. Agregue un retraso de 2 segundos a las llamadas al servicio de calificaciones:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - fault:
          delay:
            percent: 100
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
    EOF
  4. Para ver la página web de Bookinfo con las estrellas de clasificación mostradas, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un navegador . Se produce un retraso de 2 segundos cada vez que refresca la página.
    Captura de pantalla de la página web del producto de libro.
  5. Agregue un timeout de solicitud de medio segundo para las llamadas al servicio de revisiones:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
        timeout: 0.5s
    EOF
  6. Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador. Observe que la página vuelve en aproximadamente 1 segundo, en lugar de 2, y las revisiones no están disponibles.
    Captura de pantalla de la página web del producto de libro.

El motivo por el que la respuesta tarda 1 segundo, aunque el timeout esté configurado en medio segundo, se debe a un reintento de codificación fija en el servicio productpage. El servicio llama al servicio de revisiones con timeout dos veces antes de volver.

Además de sustituirlos en reglas de ruta, el timeout también se puede sustituir por solicitud si la aplicación agrega una cabecera x-envoy-upstream-rq-timeout-ms a las solicitudes salientes.

Gestión de la inyección de errores

La inyección de fallos es un método de prueba que introduce errores en un sistema para garantizar que el sistema resista y se recupere de las condiciones de error. Istio permite la inyección de fallos en la capa de aplicación, como los códigos de error HTTP. Istio inyecta dos tipos de fallos, ambos configurados mediante un servicio virtual. Para obtener más información sobre la inyección de fallos, consulte aquí.

  • Retrasos: los retrasos son fallos de temporización que imitan el aumento de la latencia de red o un servicio ascendente sobrecargado.
  • Abortos: los abortos son fallos de bloqueo que imitan fallos en servicios ascendentes. Aborta el manifiesto en forma de códigos de error HTTP o fallos de conexión TCP.

Para probar la inyección de fallos, ejecute el siguiente comando para inicializar el enrutamiento de la versión de la aplicación:

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

Inyección de un fallo de retraso de HTTP

Para inyectar un fallo de retraso, siga estos pasos:

  • Cree una regla de inyección de fallos para retrasar el tráfico procedente del usuario jason. El siguiente comando inyecta un retraso de 7 segundos entre reviews:v2 y clasifica los microservicios para el usuario jason.
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
    Nota

    El servicio reviews:v2 tiene un timeout de conexión codificada de 10 segundos para las llamadas al servicio de calificaciones. Con un retraso de 7 segundos, espere que el flujo de extremo a extremo continúe sin errores.
  • Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador.
    Instantánea de la página Bookinfo que muestra errores de retraso

    La página de inicio de Bookinfo se carga sin errores en aproximadamente siete segundos. Sin embargo, la sección de revisiones muestra un mensaje de error: Lo sentimos, las revisiones de productos no están disponibles actualmente para este libro. Existe un bug en el código de la aplicación. El timeout codificado entre el servicio productpage y el servicio reviews da como resultado un retraso de 6 segundos, 3 segundos más 1 reintento. Como resultado, la llamada productpage a reviews sufre un timeout prematuro y devuelve un error después de 6 segundos.

    Para corregir el bug, aumente el tiempo de espera del servicio productpage a reviews o disminuya el tiempo de espera de reviews a ratings a menos de 3 segundos.

  • Corrijamos el bug agregando un retraso de 2 segundos al servicio ratings para el usuario jason.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        fault:
          delay:
            percentage:
              value: 100.0
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
      - route:
        - destination:
            host: ratings
            subset: v1
    EOF
  • Ahora que se corrige el error, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un navegador para ver la página web de Bookinfo. Inicie sesión como jason con estrellas de calificación mostradas.
    Instantánea de la página Bookinfo sin errores de supresión

Inyección de un fallo de aborto de HTTP

Siga estos pasos para inyectar un fallo de anulación:

  1. Cree una regla de inyección de fallos para enviar una respuesta de anulación HTTP para el usuario jason:
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
  2. Para ver la página web de Bookinfo, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador. Conéctese como usuario jason. Un mensaje indica que el servicio ratings no está disponible.
    Captura de pantalla de la página Bookinfo con servicio de calificación no disponible

    Desconéctese del usuario jason o conéctese con cualquier otro usuario para no ver ningún mensaje de error.

    Captura de pantalla de la página Bookinfo sin errores

Creación de disyuntores

La rotura de circuitos nos permite escribir aplicaciones que limitan el impacto de fallos, picos de latencia y otros efectos indeseables de las peculiaridades de la red. Para obtener más información sobre los disyuntores, consulte aquí.

  1. Cree una regla de destino para aplicar la configuración de interrupción del circuito al llamar al servicio del producto. La siguiente regla define que el número máximo de conexiones no sea más de una y tenga un máximo de una solicitud HTTP pendiente. Además, las reglas configuran los hosts para que se exploren cada 1 segundo. Cualquier host que falle una vez con un código de error 5XX se expulsa durante 3 minutos. Además, se expulsa el 100% de los hosts del pool de equilibrio de carga para el servicio ascendente.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      trafficPolicy:
        connectionPool:
          tcp:
            maxConnections: 1
          http:
            http1MaxPendingRequests: 1
            maxRequestsPerConnection: 1
        outlierDetection:
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 3m
          maxEjectionPercent: 100
      subsets:
      - name: v1
        labels:
          version: v1
    EOF
  2. Enrute todo el tráfico a la versión v1 de cada microservicio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  3. Cree un cliente para enviar tráfico al servicio de producto. Fortio le permite controlar el número de conexiones, la simultaneidad y los retrasos de las llamadas HTTP salientes. Si ha activado la inyección automática de sidecar, despliegue el servicio fortio:
    kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
    También puede inyectar manualmente el sidecar antes de desplegar la aplicación fortio.
    kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)
  4. Conéctese al pod de cliente y utilice la herramienta fortio para llamar a productpage y verifique que el código de estado de respuesta sea 200 con los siguientes comandos.
    export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio curl http://productpage:9080
    
    Se genera la siguiente salida:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 1683
    server: envoy
    date: Tue, 07 Sep 2021 11:01:02 GMT
    x-envoy-upstream-service-time: 5
  5. Llame al servicio con 2 conexiones simultáneas (-c 2) y envíe 20 solicitudes (-n 20). Curiosamente, 16 solicitudes se transfieren y 4 fallan.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
    El comando produce una salida similar a lo siguiente.
    11:03:43 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 20 calls: http://productpage:9080
    Starting at max qps with 2 thread(s) [gomax 128] for exactly 20 calls (10 per thread + 0)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 51.340006ms : 20 calls. qps=389.56
    Aggregated Function Time : count 20 avg 0.0045031997 +/- 0.002036 min 0.000387421 max 0.007704444 sum 0.090063995
    # range, mid point, percentile, count
    >= 0.000387421 <= 0.001 , 0.000693711 , 15.00, 3
    > 0.003 <= 0.004 , 0.0035 , 20.00, 1
    > 0.004 <= 0.005 , 0.0045 , 65.00, 9
    > 0.005 <= 0.006 , 0.0055 , 75.00, 2
    > 0.006 <= 0.007 , 0.0065 , 95.00, 4
    > 0.007 <= 0.00770444 , 0.00735222 , 100.00, 1
    # target 50% 0.00466667
    # target 75% 0.006
    # target 90% 0.00675
    # target 99% 0.00756356
    # target 99.9% 0.00769036
    Sockets used: 5 (for perfect keepalive, would be 2)
    Jitter: false
    Code 200 : 16 (80.0 %)
    Code 503 : 4 (20.0 %)
    Response Header Sizes : count 20 avg 133.6 +/- 66.8 min 0 max 167 sum 2672
    Response Body/Total Sizes : count 20 avg 1528.2 +/- 643.6 min 241 max 1850 sum 30564
    All done 20 calls (plus 0 warmup) 4.503 ms avg, 389.6 qps
  6. Aumente el número de conexiones simultáneas a 3.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://productpage:9080
    Solo el 26,7% de las solicitudes tuvieron éxito y la interrupción del circuito atrapa al resto.
    11:10:19 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 30 calls: http://productpage:9080
    Starting at max qps with 3 thread(s) [gomax 128] for exactly 30 calls (10 per thread + 0)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 28.105508ms : 30 calls. qps=1067.4
    Aggregated Function Time : count 30 avg 0.0024256753 +/- 0.003264 min 0.000261072 max 0.010510116 sum 0.07277026
    # range, mid point, percentile, count
    >= 0.000261072 <= 0.001 , 0.000630536 , 66.67, 20
    > 0.001 <= 0.002 , 0.0015 , 73.33, 2
    > 0.005 <= 0.006 , 0.0055 , 76.67, 1
    > 0.006 <= 0.007 , 0.0065 , 83.33, 2
    > 0.007 <= 0.008 , 0.0075 , 93.33, 3
    > 0.009 <= 0.01 , 0.0095 , 96.67, 1
    > 0.01 <= 0.0105101 , 0.0102551 , 100.00, 1
    # target 50% 0.000805545
    # target 75% 0.0055
    # target 90% 0.00766667
    # target 99% 0.0103571
    # target 99.9% 0.0104948
    Sockets used: 25 (for perfect keepalive, would be 3)
    Jitter: false
    Code 200 : 8 (26.7 %)
    Code 503 : 22 (73.3 %)
    Response Header Sizes : count 30 avg 44.533333 +/- 73.85 min 0 max 167 sum 1336
    Response Body/Total Sizes : count 30 avg 670.06667 +/- 711.5 min 241 max 1850 sum 20102
    All done 30 calls (plus 0 warmup) 2.426 ms avg, 1067.4 qps
  7. Consulte las estadísticas de istio-proxy para obtener más información.
    kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
    Interrupción de circuitos 32 llamadas mirando la métrica upstream_rq_pending_overflow.
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_active: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_overflow: 32
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_total: 39
  8. Limpie el cliente.
    kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
    kubectl delete deploy fortio-deploy
    kubectl delete svc fortio

Duplicación

El reflejo del tráfico, también denominado sombreado, permite a los equipos realizar cambios en la producción con el menor riesgo posible. El reflejo envía una copia del tráfico activo a un servicio reflejado. El tráfico reflejado se produce fuera de la ruta de solicitud crítica para el servicio principal.

  1. Enrute todo el tráfico a la versión v1 de cada microservicio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Cambie la regla de ruta para duplicar el tráfico en reviews:v2.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v1
          weight: 100
        mirror:
          host: reviews
          subset: v2
        mirrorPercentage:
          value: 100.0
    EOF

    La regla de ruta anterior envía el 100% del tráfico a reviews:v1 y refleja el 100% del mismo tráfico al servicio reviews:v2.

    Cuando el tráfico se duplica, las solicitudes se envían al servicio reflejado con sus cabeceras Host/Authority agregadas con -shadow. Por ejemplo, las revisiones se convierten en solicitudes de reviews-shadow.Mirrored consideradas como "fuego y olvido". Las respuestas reflejadas se descartan.

    En lugar de reflejar todas las solicitudes, cambie el campo de valor del campo mirrorPercentage para reflejar una fracción del tráfico. Si este campo está ausente, todo el tráfico se refleja.

  3. Envíe algo de tráfico refrescando la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador.
  4. Logs del servicio reviews:v1. Tenga en cuenta que el servicio v1 no llama al servicio de calificaciones.
    Captura de pantalla del servicio reviews:v1
  5. Logs del servicio reflejado reviews:v2. Tenga en cuenta que para el servicio v2, la cabecera se agrega con -shadow.
    Captura de pantalla del servicio reviews:v2 con -shadow

Gestión de gateways

Gateway describe un equilibrador de carga que funciona en el borde de la malla que recibe conexiones HTTP/TCP entrantes o salientes. Las configuraciones de gateway se aplican a los proxies de Envoy independientes que se ejecutan en el borde de la malla, en lugar de a los proxies de Envoy sidecar que se ejecutan junto con sus cargas de trabajo de servicio. Istio proporciona algunos despliegues de proxy de gateway preconfigurados istio-ingressgateway y istio-egressgateway.

Si no ha configurado los gateways de Istio como parte de la instalación, ejecute el siguiente comando para instalarlos.
istioctl install

El comando despliega Istio mediante la configuración predeterminada que incluye una puerta de enlace. Para obtener más información, consulte .

Nota

Determine INGRESS_HOST y INGRESS_PORT mediante estas instrucciones.

Configuración de entrada mediante Istio Gateway

El gateway de entrada configura los puertos y protocolos expuestos, pero a diferencia de los recursos de entrada de Kubernetes, no incluye ninguna configuración de enrutamiento de tráfico. El enrutamiento de tráfico para el tráfico de entrada se configura mediante reglas de enrutamiento de Istio. Para obtener más información sobre la entrada de Istio, consulte aquí.

Nota

Si ya ha desplegado la aplicación Bookinfo, no es necesario realizar los siguientes pasos.
  1. Cree un gateway de Istio que se configure en el puerto 80 para el tráfico HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - "*"
    EOF
  2. Configure rutas para el tráfico que entra a través del gateway:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  3. Para desplegar la aplicación Bookinfo, consulte la sección "Ejecución de la aplicación Bookinfo" de la página Instalación de Istio y OKE.
  4. Acceda al servicio productpage mediante curl:
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/productpage

    El comando produce la siguiente salida:

    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 4183
    server: istio-envoy
    date: Tue, 07 Sep 2021 13:48:39 GMT
    x-envoy-upstream-service-time: 36
  5. Acceda a cualquier otra URL que no se haya expuesto explícitamente. Aparece un error de HTTP 404.
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any

    El comando produce la siguiente salida:

    HTTP/1.1 404 Not Found
    date: Tue, 07 Sep 2021 13:49:45 GMT
    server: istio-envoy
    transfer-encoding: chunked
  6. Para hosts explícitos en gateways, utilice el indicador -H para definir la cabecera HTTP del host. El indicador es necesario porque el gateway de entrada y el servicio virtual están configurados para manejar el host. Por ejemplo, el host es example.com y el nombre se especifica en gateways y servicio virtual.
    curl -s -I -HHost:example.com http://$INGRESS_HOST:$INGRESS_PORT/productpage
  7. Además, abra la URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage en un explorador para ver la página web de Bookinfo.

Configuración de entrada mediante el recurso de entrada de Kubernetes

El lector asume que la aplicación Bookinfo está desplegada en el cluster. Para desplegar la aplicación Bookinfo, consulte la sección "Ejecución de la aplicación Bookinfo" de la página Instalación de Istio y OKE.

  1. Elimine la puerta de enlace Istio si la configuración ya se ha aplicado.
    kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. Cree un recurso de entrada en el puerto 80 para el tráfico HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: istio
      name: ingress
    spec:
      rules:
      - http:
         paths:
         - path: /productpage
           pathType: Prefix
           backend:
              service:
                name: productpage
                port:
                  number: 9080
    EOF

    Se necesita la anotación kubernetes.io/ingress.class para indicar al controlador de gateway de Istio que maneje este Ingress.

  3. Verifique el acceso a la aplicación Bookinfo siguiendo las instrucciones de la sección anterior.
  4. Suprima el recurso y active el gateway de Istio para realizar más tareas.
    kubectl delete ingress ingress
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Acceso a servicios externos con salida

Por defecto, todo el tráfico saliente de un pod activado por Istio se redirige a su proxy sidecar e Istio configura el proxy Envoy para transferir solicitudes de servicios desconocidos. Istio configura el manejo sidecar de servicios externos mediante un campo de configuración meshConfig.outboundTrafficPolicy.mode. Si esta opción se define como:

  • ALLOW_ANY (por defecto): el proxy Istio permite que se transfieran las llamadas a servicios desconocidos.
  • REGISTRY_ONLY: el proxy Istio bloquea cualquier host sin un servicio HTTP o una entrada de servicio definida en la malla.

El lector asume que la aplicación Bookinfo se ha desplegado en el cluster. De lo contrario, siga los pasos para desplegar la aplicación Bookinfo.

Gestión de la transferencia de Envoy a servicios externos

Para activar la transferencia a servicios externos, siga estos pasos.

  1. Cambie la opción meshConfig.outboundTrafficPolicy.mode a ALLOW_ANY con istioctl.
    istioctl install --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
    Nota

    Este paso solo es necesario si ha definido explícitamente la opción en REGISTRY_ONLY durante la instalación.
  2. Para confirmar las 200 respuestas correctas, realice una solicitud a servicios externos desde SOURCE_POD:
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    El comando produce la siguiente salida:
    HTTP/1.1 200 OK

Sin embargo, la desventaja de este enfoque es que se pierde la supervisión y el control de Istio para el tráfico a servicios externos.

Control de acceso a servicios externos [Recomendado]

Para configurar el acceso controlado a servicios externos, siga estos pasos:

  1. Cambie la opción meshConfig.outboundTrafficPolicy.mode a REGISTRY_ONLY. Este paso sólo es necesario si no ha definido explícitamente la opción en REGISTRY_ONLY durante la instalación.
  2. Siga solo el paso 1 de la sección "Transferencia de Envoy a Servicios Externos". El único cambio que se puede realizar aquí es sustituir ALLOW_ANY por REGISTRY_ONLY.
  3. Para verificar que los servicios externos están bloqueados, realice un par de solicitudes a servicios HTTPS externos desde SOURCE_POD. Los cambios de configuración tardan varios segundos en propagarse, por lo que es posible realizar conexiones correctas. Espere varios segundos y, a continuación, vuelva a intentar el último comando.
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"

    El comando produce la siguiente salida:

    HTTP/1.1 502 Bad Gateway
  4. Cree un ServiceEntry para permitir el acceso a un servicio HTTP externo.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: ServiceEntry
    metadata:
      name: httpbin-ext
    spec:
      hosts:
      - httpbin.org
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
      location: MESH_EXTERNAL
    EOF
  5. Realice una solicitud al servicio HTTP externo desde SOURCE_POD. Observe que las cabeceras agregadas por el proxy de sidecar Istio: X-Envoy-Decorator-Operation.
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    El comando produce la siguiente salida:
    HTTP/1.1 200 OK

    Elimine el comando grep para ver todas las cabeceras.

    kubectl exec $SOURCE_POD -c ratings -- curl -sS http://httpbin.org/headers

    El comando produce la siguiente salida:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.org",
        "User-Agent": "curl/7.52.1",
        "X-Amzn-Trace-Id": "Root=1-61384b41-2d3cf8b5571ba7504ab9a834",
        "X-B3-Sampled": "0",
        "X-B3-Spanid": "6983ef0cec914f83",
        "X-B3-Traceid": "d510c4d190cb099d6983ef0cec914f83",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-Decorator-Operation": "httpbin.org:80/*",
        "X-Envoy-Peer-Metadata": "ChsKDkFQUF9DT05UQUlORVJTEgkaB3JhdGluZ3MKGgoKQ0xVU1RFUl9JRBIMGgpLdWJlcm5ldGVzChkKDUlTVElPX1ZFUlNJT04SCBoGMS4xMS4xCtQBCgZMQUJFTFMSyQEqxgEKEAoDYXBwEgkaB3JhdGluZ3MKIAoRcG9kLXRlbXBsYXRlLWhhc2gSCxoJYzk5NDdiOTlmCiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KLAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIJGgdyYXRpbmdzCisKI3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLXJldmlzaW9uEgQaAnYxCg8KB3ZlcnNpb24SBBoCdjEKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiQKBE5BTUUSHBoacmF0aW5ncy12MS1jOTk0N2I5OWYtbGN4bHQKFgoJTkFNRVNQQUNFEgkaB2RlZmF1bHQKTgoFT1dORVISRRpDa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2RlZmF1bHQvZGVwbG95bWVudHMvcmF0aW5ncy12MQoXChFQTEFURk9STV9NRVRBREFUQRICKgAKHQoNV09SS0xPQURfTkFNRRIMGgpyYXRpbmdzLXYx",
        "X-Envoy-Peer-Metadata-Id": "sidecar~10.244.0.11~ratings-v1-c9947b99f-lcxlt.default~default.svc.cluster.local"
      }
    }
  6. Para acceder a llamadas HTTPS, sustituya el puerto y el protocolo al crear entradas de servicio.
  7. El enfoque agrega funciones de gestión de tráfico de servicio externo, como timeouts e inyección de fallos. La siguiente solicitud devuelve 200 (OK) en aproximadamente cinco segundos.
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
    Utilice kubectl para establecer un timeout de 3 segundos en las llamadas al servicio externo httpbin.org:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-ext
    spec:
      hosts:
        - httpbin.org
      http:
      - timeout: 3s
        route:
          - destination:
              host: httpbin.org
            weight: 100
    EOF
    Esta vez aparece un timeout después de 3 segundos. Aunque httpbin.org estaba esperando cinco segundos, Istio cortó la solicitud a los 3 segundos:
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
  8. Limpie los recursos para futuras tareas.
    kubectl delete serviceentry httpbin-ext
    kubectl delete virtualservice httpbin-ext --ignore-not-found=true

Dirección de acceso a servicios externos

Este enfoque omite el proxy de sidecar de Istio, lo que proporciona a los servicios acceso directo a cualquier servidor externo. Sin embargo, la configuración del proxy de esta manera requiere conocimientos y configuración específicos del proveedor del cluster. Al igual que el primer enfoque, perdemos el control del acceso a servicios externos y no podemos aplicar las funciones de Istio en el tráfico a servicios externos. Siga estos pasos para proporcionar acceso directo a servicios externos.

Protección de Istio

Las funciones de seguridad de Istio proporcionan una identidad sólida, una política potente, cifrado TLS transparente y herramientas de autenticación, autorización y auditoría (AAA) para proteger sus servicios y datos.

Configuración de la autenticación

Istio ofrece TLS mutua como una solución de pila completa para la autenticación de transporte, que está activada sin necesidad de realizar cambios en el código de servicio.

Despliegue los servicios sleep y httpbin en el espacio de nombres por defecto.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/httpbin/httpbin.yaml

De forma predeterminada, Istio realiza varias tareas. Istio realiza un seguimiento de las cargas de trabajo del servidor migradas a los proxies de Istio. Istio configura proxies de cliente para enviar tráfico TLS mutuo a esas cargas de trabajo automáticamente. Istio envía tráfico de texto sin formato a cargas de trabajo sin sidecares.

Para verificar que se han enviado certificados, envíe una solicitud de un pod sleep al pod httpbin y busque la cabecera X-Forwarded-Client-Cert.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -s http://httpbin.default:8000/headers -s | grep X-Forwarded-Client-Cert | sed 's/Hash=[a-z0-9]*;/Hash=<redacted>;/'
Despliegue otra instancia de los servicios sleep y httpbin sin el sidecar activado.
kubectl create ns legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
La solicitud del pod sleep en el espacio de nombres por defecto al pod httpbin en el espacio de nombres heredado es de texto sin formato porque el destino no está activado para sidecar. Verifique que se envíe texto sin formato ejecutando el siguiente comando.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
La solicitud del pod sleep en el espacio de nombres heredado a httpbin en el espacio de nombres por defecto también se realiza correctamente con una conexión de texto sin formato. Esto se puede verificar con el siguiente comando.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Para evitar el tráfico TLS no mutuo para toda la malla, defina una política de autenticación de peer de malla con el modo TLS mutuo definido en STRICT.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF
La conexión de un pod sleep en el espacio de nombres heredado a httpbin en el espacio de nombres por defecto ya no funciona cuando el modo TLS mutuo está definido en STRICT.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Revierta la configuración de autenticación de peer STRICT suprimiendo la solicitud de cambio.
kubectl delete peerauthentication -n istio-system default

Además de la configuración TLS mutua global, también se puede definir en un espacio de nombres o nivel de carga de trabajo. Siga la documentación de Istio para obtener configuraciones de autenticación detalladas.

Configuración de autorización

Istio le permite configurar políticas de autorización para sus aplicaciones.

En primer lugar, configure una política allow-nothing simple que rechace todas las solicitudes a la carga de trabajo y, a continuación, otorgue más acceso a la carga de trabajo de forma gradual e incremental.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}
EOF

Abra la página del producto Bookinfo en su navegador. Muestra el error "RBAC: access denied" que confirma que la política deny-all funciona según lo previsto.

Cree una política para otorgar a todos los usuarios y cargas de trabajo acceso a la página del producto mediante el siguiente comando.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "productpage-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF

Verá la página "Bookinfo Sample", pero el servicio productpage no puede acceder a la página de detalles y revisiones.

Agregue las siguientes políticas para otorgar acceso a la carga de trabajo productpage a los detalles y revise las cargas de trabajo y revise el acceso a la carga de trabajo ratings.

Establecer visor de detalles

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Establecer visor de revisiones

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Establecer visor de calificaciones

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ratings-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: ratings
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
    to:
    - operation:
        methods: ["GET"]
EOF

Ver la página del producto desde un navegador sin ningún error.

Para revertir las políticas aplicadas, introduzca los siguientes comandos.

kubectl delete authorizationpolicy.security.istio.io/allow-nothing
kubectl delete authorizationpolicy.security.istio.io/productpage-viewer
kubectl delete authorizationpolicy.security.istio.io/details-viewer
kubectl delete authorizationpolicy.security.istio.io/reviews-viewer
kubectl delete authorizationpolicy.security.istio.io/ratings-viewer

Protección de gateways con TLS

Podemos exponer la aplicación Bookinfo como un servicio HTTPS seguro utilizando TLS simple o mutuo. Para firmar los certificados de los servicios, cree un certificado raíz y una clave privada:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt

Cree un certificado y una clave privada para productpage.bookinfo.com.

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

Asegúrese de que ha desplegado la aplicación Bookinfo. Cree un secreto para los certificados de gateway de entrada.

kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt

Actualice la puerta de enlace de Bookinfo para incluir un puerto seguro.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway-https
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: bookinfo-credential
    hosts:
    - bookinfo.example.com
EOF

Cree reglas de destino de Bookinfo si aún no se han creado.

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Cree un servicio virtual enlazado al gateway.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: bookinfo-https
spec:
  hosts:
  - "bookinfo.example.com"
  gateways:
  - bookinfo-gateway-https
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
EOF

Puede verificar la conexión TLS al gateway con el siguiente comando curl.

curl -v -HHost:bookinfo.example.com --resolve "bookinfo.example.com:443:$INGRESS_HOST" --cacert example.com.crt "https://bookinfo.example.com/productpage"