Guía de migración del complemento Open Service Mesh (OSM) al complemento istio

Importante

En este artículo se presenta cómo identificar las configuraciones de complementos de OSM y traducirlas a configuraciones de complementos de Istio equivalentes. No es una guía exhaustiva para una migración a producción.

En este artículo se relacionan las directivas de complemento de OSM con las directivas de complemento equivalentes de Istio. Tanto el origen como el destino de este artículo son complementos administrados de Azure Kubernetes Service (AKS). No cubre la migración desde Open Service Mesh upstream a una instalación autogestionada o de código abierto de Istio. Usa la aplicación de ejemplo Bookstore de OSM como referencia para los usuarios actuales del complemento de OSM. El artículo tiene dos secciones independientes:

Si no usa OSM y no está familiarizado con el complemento istio administrado, comience con Instalar el complemento istio. Si usa actualmente OSM, consulte el tutorial Aplicación de ejemplo de Bookstore de OSM antes de continuar. El siguiente tutorial no duplica la documentación de OSM y hace referencia a temas específicos cuando sea pertinente. Asegúrese de comprender la arquitectura de la aplicación Bookstore antes de continuar.

Requisitos previos

  • Una suscripción Azure con un clúster de AKS existente que ejecuta el complemento de OSM.

  • La CLI de Azure instalada.

  • Acceso al clúster de AKS donde puede habilitar o deshabilitar complementos administrados.

  • kubectl acceso al clúster.

  • El ejemplo Bookstore de OSM ya está implementado en los espacios de nombres bookbuyer, bookthief, bookstore y bookwarehouse.

  • Seleccione una revisión de Istio para instalar. Establezca LOCATION en la región de Azure para el clúster de AKS y busque las revisiones admitidas de Istio mediante el az aks mesh get-revisions comando :

    export LOCATION=<location>
    
    az aks mesh get-revisions --location ${LOCATION} -o table
    
  • Establezca las variables que se usan en este artículo. Establezca REVISION en una revisión devuelta por el comando az aks mesh get-revisions:

    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER=<cluster-name>
    export REVISION=<revision>
    export BOOKSTORE_NAMESPACES="bookbuyer bookthief bookstore bookwarehouse"
    

Migra el ejemplo Bookstore de OSM al complemento Istio

El complemento de OSM y el complemento istio no se pueden ejecutar simultáneamente en el mismo clúster de AKS. Este procedimiento migra el ejemplo de almacén de libros de OSM sin eliminar el clúster, los espacios de nombres, los servicios o los controladores de carga de trabajo. Los pods en ejecución no se cambian en su ubicación. Los pods existentes mantienen sus sidecars de OSM hasta que sus controladores crean pods de reemplazo después de etiquetar los espacios de nombres para la revisión administrada de Istio.

Warning

Esta migración provoca una interrupción del servicio. Al deshabilitar el complemento de OSM, se deja de aplicar inmediatamente la directiva de tráfico de SMI: mTLS y el control de acceso dejan de aplicarse aunque los pods existentes sigan ejecutándose. El intervalo entre deshabilitar OSM y completar el despliegue de Istio deja a las cargas de trabajo sin seguridad ni directivas de enrutamiento a nivel de malla. Cualquier reemplazo de pod durante esta ventana (reinicios de implementación, eventos de escalado, expulsiones de nodos o bucles de bloqueo) crea pods que no tienen un sidecar de OSM ni un sidecar de Istio hasta que se etiqueta el espacio de nombres y se vuelve a crear el pod. Planee primero un tiempo de inactividad de la aplicación o una ventana de disponibilidad reducida para cargas de trabajo de producción y valide el procedimiento completo en un clúster que no sea de producción. La configuración de mantenimiento planeado de AKS no programa ni controla esta migración manual.

La siguiente migración utiliza la siguiente secuencia de limpieza:

  1. Guarde los recursos de SMI antes de deshabilitar el complemento de OSM.
  2. Deshabilite el complemento de OSM antes de habilitar el complemento administrado de Istio.
  3. Quite los webhooks obsoletos de admisión de OSM antes de volver a etiquetar los espacios de nombres o reiniciar las cargas de trabajo.
  4. Mantenga las CRD de OSM y SMI en su ubicación durante la habilitación administrada de Istio y la implementación de cargas de trabajo, a menos que su propia validación muestre que bloquean la habilitación, la admisión o la implementación.
  5. Quite los marcadores de espacios de nombres obsoletos openservicemesh.io/* durante el intercambio de etiquetas.
  6. Etiquete los espacios de nombres de cargas de trabajo con istio.io/rev=<revision>.
  7. Aplique y compruebe los recursos de Istio traducidos que son seguros para los nombres y selectores de cargas de trabajo existentes.
  8. Implemente los controladores de cargas de trabajo existentes para que se creen pods de reemplazo con sidecars de Istio.
  9. Elimine las CRD residuales de OSM y SMI solo cuando los pods migrados estén listos.

Verificar el estado de la librería OSM

Compruebe que el complemento de OSM esté habilitado y que el complemento administrado de Istio no esté habilitado:

az aks show \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"

El openServiceMesh.enabled valor debe ser true. El serviceMeshProfile valor debe ser null o mostrarse mode: disabled antes de que se inicie la migración.

Compruebe que el plano de control de OSM está listo:

kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-controller --timeout=10m
kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-injector --timeout=10m
kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-bootstrap --timeout=10m

Compruebe que los pods de Bookstore están en ejecución y tienen varios contenedores listos. Los pods inyectados por OSM incluyen el contenedor init osm-init y el contenedor sidecar envoy.

kubectl get pods -A -o wide | grep -E '^(bookbuyer|bookstore|bookthief|bookwarehouse)'

En el siguiente ejemplo resumido, se muestran los pods de Bookstore con varios contenedores listos:

bookbuyer       bookbuyer-58c7699cb7-fxzvz       2/2   Running   0   51s   10.224.0.20   aks-nodepool1-32739176-vmss000002   <none>   <none>
bookstore       bookstore-7696584686-6zdkn       2/2   Running   0   50s   10.224.0.71   aks-nodepool1-32739176-vmss000001   <none>   <none>
bookthief       bookthief-77bf8c9b76-vswxz       2/2   Running   0   50s   10.224.0.15   aks-nodepool1-32739176-vmss000002   <none>   <none>
bookwarehouse   bookwarehouse-6b94d668f7-vksf4   2/2   Running   0   49s   10.224.0.82   aks-nodepool1-32739176-vmss000001   <none>   <none>
bookwarehouse   mysql-0                          3/3   Running   0   48s   10.224.0.17   aks-nodepool1-32739176-vmss000002   <none>   <none>

Confirme que los pods inyectados incluyen contenedores de OSM:

for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
  kubectl get pods -n ${NAMESPACE} \
    -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\tinit="}{range .spec.initContainers[*]}{.name}{","}{end}{"\tcontainers="}{range .spec.containers[*]}{.name}{","}{end}{"\n"}{end}'
done

Compruebe los recursos de SMI utilizados por el ejemplo:

kubectl get traffictargets.access.smi-spec.io,httproutegroups.specs.smi-spec.io,tcproutes.specs.smi-spec.io,trafficsplits.split.smi-spec.io -A

Compruebe los registros de Bookbuyer antes de cambiar la malla:

kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --tail=20

Opcionalmente, inicie un flujo de registro de Bookbuyer continuo para supervisar la disponibilidad de las aplicaciones. Mantenga la transmisión en ejecución durante el reetiquetado de espacios de nombres y la implementación de cargas de trabajo si desea que el registro cubra todo el periodo de migración.

BOOKBUYER_LOG=bookbuyer-migration.log
kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --timestamps --since=10s -f > ${BOOKBUYER_LOG} 2>&1 &
BOOKBUYER_LOG_PID=$!

Guardar la configuración de la directiva SMI

Guarde los recursos de SMI antes de la limpieza final de OSM y de la API de SMI. Utilice estos archivos para planificar la traducción y la reversión.

mkdir -p osm-smi-backup

kubectl get traffictargets.access.smi-spec.io -A -o yaml > osm-smi-backup/traffic-targets.yaml
kubectl get httproutegroups.specs.smi-spec.io -A -o yaml > osm-smi-backup/http-route-groups.yaml
kubectl get tcproutes.specs.smi-spec.io -A -o yaml > osm-smi-backup/tcp-routes.yaml
kubectl get trafficsplits.split.smi-spec.io -A -o yaml > osm-smi-backup/traffic-splits.yaml

No utilice webhooks residuales de OSM, CRD, etiquetas ni anotaciones como estado de reversión después de deshabilitar el complemento.

Traduzca los recursos de SMI guardados a recursos de Istio mediante los ejemplos de directivas más adelante en el artículo:

Recurso o comportamiento de OSM Equivalente de Istio
Incorporación del espacio de nombres de OSM Etiqueta del espacio de nombres istio.io/rev=<revision>
Inyección del sidecar de OSM Inyección del sidecar de Istio para la revisión seleccionada
TrafficTarget, HTTPRouteGroup y TCPRoute AuthorizationPolicy
TrafficSplit VirtualService y DestinationRule
Directiva de tráfico permisivo de OSM y configuración de mTLS PeerAuthentication y AuthorizationPolicy

Aplique y verifique los recursos de Istio traducidos correspondientes a sus cargas de trabajo antes de dar la migración por completada. Los pasos de Bookstore en su ubicación en esta sección verifican el cambio del plano de control y la implementación del sidecar. No aplican automáticamente los ejemplos de directivas en la sección de referencia y los manifiestos de ejemplo limpio que se muestran más adelante en este artículo deben adaptarse antes de aplicarlos a los espacios de nombres existentes.

Deshabilitar el complemento de OSM

Deshabilite el complemento de OSM:

az aks disable-addons \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --addons open-service-mesh

Compruebe que el complemento de OSM está deshabilitado:

az aks show \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"

El openServiceMesh.enabled valor debe ser false o null. El serviceMeshProfile valor debe permanecer sin cambios hasta que se habilite Istio administrado.

Compruebe que los pods de Bookstore existentes siguen ejecutándose:

kubectl get pods -n bookbuyer
kubectl get pods -n bookthief
kubectl get pods -n bookstore
kubectl get pods -n bookwarehouse

Es posible que los pods existentes sigan incluyendo sidecars de OSM después de deshabilitar OSM. Esto es lo esperado. Se reemplazan cuando sus controladores se implementan más adelante en el procedimiento.

Eliminar los bloqueos de admisión residuales de OSM

Compruebe si la admisión residual de OSM sigue afectando a un espacio de nombres de cargas de trabajo:

kubectl run osm-admission-probe \
  --namespace bookbuyer \
  --image mcr.microsoft.com/oss/nginx/nginx:1.25.5 \
  --restart Never \
  --dry-run=server \
  -o yaml

Quite las configuraciones de webhook del complemento de OSM de AKS. Si se ha producido un error en la simulación porque Kubernetes no puede llamar al servicio osm-injector, esta limpieza borra el bloqueador de admisión.

kubectl delete mutatingwebhookconfiguration aks-osm-webhook-osm --ignore-not-found
kubectl delete validatingwebhookconfiguration aks-osm-validator-mesh-osm --ignore-not-found

Elimine estas configuraciones del webhook antes de volver a etiquetar los espacios de nombres o reiniciar las cargas de trabajo. Un webhook residual roto de OSM puede bloquear la creación de pods para verificación, implementación de cargas de trabajo o pruebas de reversión.

Confirme que la admisión de pods del lado servidor se realiza correctamente después de la limpieza del webhook:

kubectl run osm-admission-probe \
  --namespace bookbuyer \
  --image mcr.microsoft.com/oss/nginx/nginx:1.25.5 \
  --restart Never \
  --dry-run=server \
  -o yaml

Compruebe que no quedan webhooks de admisión de OSM:

kubectl get mutatingwebhookconfiguration,validatingwebhookconfiguration | grep -i osm || true

Realice un inventario de los CRD restantes de OSM y SMI antes de habilitar Istio administrado. Deje estos CRD en su lugar a menos que la validación muestre que bloquean la habilitación, la admisión o la implementación.

kubectl get crd | grep -E 'openservicemesh.io|smi-spec.io' || true

Habilitar el complemento Istio y mover cargas de trabajo

Habilite el complemento Istio administrado:

az aks mesh enable \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --revision ${REVISION}

Verifique el estado del complemento Istio administrado:

az aks show \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --query "{mode:serviceMeshProfile.mode, revisions:serviceMeshProfile.istio.revisions}"

El mode valor debe ser Istioy la lista de revisiones debe incluir la revisión seleccionada.

Espere a que el plano de control de Istio y el webhook de inyección estén listos:

kubectl wait -n aks-istio-system --for=condition=Ready pod -l app=istiod --timeout=10m
kubectl get mutatingwebhookconfiguration | grep istio-sidecar-injector

Elimine los marcadores obsoletos de los espacios de nombres de OSM y etiquete los espacios de nombres de Bookstore con la revisión administrada de Istio. No use istio-injection=enabled con el complemento de Istio administrado de AKS.

for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
  kubectl label namespace ${NAMESPACE} openservicemesh.io/monitored-by- --overwrite
  kubectl annotate namespace ${NAMESPACE} openservicemesh.io/sidecar-injection- --overwrite
  kubectl label namespace ${NAMESPACE} istio.io/rev=${REVISION} --overwrite
done

Aplique y compruebe los recursos de Istio traducidos que son seguros para los nombres y selectores de cargas de trabajo existentes antes de implementar los controladores. Los archivos exactos dependen de los recursos de SMI guardados y traducidos.

kubectl apply -f translated-istio-resources.yaml
kubectl get peerauthentication,authorizationpolicy,destinationrule,virtualservice -A

No elimine las API de OSM o de SMI hasta que se haya verificado, en sus cargas de trabajo, un comportamiento equivalente de directivas y enrutamiento de Istio.

Implemente los controladores existentes para que Kubernetes cree pods de reemplazo con sidecars de Istio. El orden siguiente coincide con el flujo de validación de ejemplo:

kubectl rollout restart -n bookwarehouse deployment/bookwarehouse
kubectl rollout status -n bookwarehouse deployment/bookwarehouse --timeout=10m

kubectl rollout restart -n bookwarehouse statefulset/mysql
kubectl rollout status -n bookwarehouse statefulset/mysql --timeout=10m

kubectl rollout restart -n bookstore deployment/bookstore
kubectl rollout status -n bookstore deployment/bookstore --timeout=10m

kubectl rollout restart -n bookthief deployment/bookthief
kubectl rollout status -n bookthief deployment/bookthief --timeout=10m

kubectl rollout restart -n bookbuyer deployment/bookbuyer
kubectl rollout status -n bookbuyer deployment/bookbuyer --timeout=10m

Compruebe que los pods de reemplazo incluyen istio-proxy:

for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
  kubectl get pods -n ${NAMESPACE} \
    -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\tinit="}{range .spec.initContainers[*]}{.name}{","}{end}{"\tcontainers="}{range .spec.containers[*]}{.name}{","}{end}{"\n"}{end}'
done

Compruebe Bookbuyer después del lanzamiento:

kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --tail=20

Si se inició un flujo de registros de Bookbuyer, deténgalo e inspeccione las muestras recopiladas. Confirme que las marcas de tiempo cubren la ventana de reetiquetado e implementación antes de usar el registro como evidencia de disponibilidad.

kill ${BOOKBUYER_LOG_PID}
wait ${BOOKBUYER_LOG_PID} 2>/dev/null || true

grep "MAESTRO! THIS TEST FAILED!" ${BOOKBUYER_LOG} || true
grep "MAESTRO! THIS TEST SUCCEEDED!" ${BOOKBUYER_LOG} | tail

Una vez que los pods migrados estén listos, revise el inventario de CRD y elimine las CRD residuales de OSM y SMI en la limpieza final. Si elimina una CRD se eliminan todos los recursos personalizados de esa CRD en todo el clúster, no solo el ejemplo de Bookstore. No ejecute esta limpieza hasta que no confirme que ninguna carga de trabajo restante dependa de recursos de OSM o SMI.

kubectl delete crd \
  egresses.policy.openservicemesh.io \
  httproutegroups.specs.smi-spec.io \
  ingressbackends.policy.openservicemesh.io \
  meshconfigs.config.openservicemesh.io \
  meshrootcertificates.config.openservicemesh.io \
  retries.policy.openservicemesh.io \
  tcproutes.specs.smi-spec.io \
  trafficsplits.split.smi-spec.io \
  traffictargets.access.smi-spec.io \
  upstreamtrafficsettings.policy.openservicemesh.io \
  --ignore-not-found

Compruebe el complemento final y el estado de OSM residual:

az aks show \
  --resource-group ${RESOURCE_GROUP} \
  --name ${CLUSTER} \
  --query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"
kubectl get mutatingwebhookconfiguration,validatingwebhookconfiguration | grep -i osm || true
kubectl get crd | grep -E 'openservicemesh.io|smi-spec.io' || true

El estado final de AKS ahora debe mostrar OSM deshabilitado e Istio administrado habilitado. Si ha eliminado las CRD residuales de OSM y SMI, las comprobaciones de los recursos residuales de OSM no deberían devolver ningún recurso.

Referencia de traducción de la política de la librería

En el resto de este artículo se usa una implementación de ejemplo limpio de Bookstore para demostrar cómo traducir los recursos de SMI de OSM y los manifiestos de cargas de trabajo a los recursos de Istio. En una migración, aplique los mismos tipos de cambios a los manifiestos existentes y implemente los controladores de carga de trabajo existentes en lugar de eliminar y volver a crear la aplicación.

Note

Ejecute la referencia de traducción de directivas en un clúster aparte o elimine los espacios de nombres de Bookstore existentes antes de ejecutar los comandos de implementación de ejemplo. Los kubectl create namespace comandos producen un error si los espacios de nombres ya existen. El clúster de destino ya debe tener habilitado el complemento Istio administrado.

Para permitir que Istio administre la aplicación Bookstore de OSM, actualice los manifiestos del servicio Bookstore y MySQL existentes.

Modificaciones de la librería

Antes de traducir la directiva de tráfico de OSM, revise cómo Istio controla la administración del tráfico.

Istio usa una combinación de virtualService y destinationRule para el enrutamiento del tráfico. Revise los conceptos de un servicio virtual y una regla de destino antes de continuar.

El servicio virtual Istio define reglas de enrutamiento para los clientes que solicitan el host, que es el nombre del servicio. La regla de destino define la directiva de tráfico para ese servicio.

Los cambios en el servicio y la implementación de Bookstore de Istio mantienen la aplicación Bookstore detrás del servicio bookstore. La versión de Istio del manifiesto traffic-access-v1.yaml de OSM aparece en Crear pods, servicios y cuentas de servicio.

Modificaciones de MySQL

Los cambios en StatefulSet de MySQL solo son necesarios en la configuración del servicio. En la especificación del servicio, OSM necesitaba los atributos targetPort y appProtocol. Estos atributos no son necesarios para Istio. Mantenga el nombre del servicio como mysql porque el ejemplo bookstore y mySQL StatefulSet usan ese nombre. El siguiente servicio actualizado tiene el siguiente aspecto:

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: bookwarehouse
  labels:
    app: mysql
    service: mysql
spec:
  ports:
    - port: 3306
      name: tcp
  selector:
    app: mysql
  clusterIP: None

Implementación de la aplicación Bookstore modificada

De forma similar al tutorial de bookstore de OSM, el ejemplo comienza con una nueva instalación de la aplicación bookstore. En esta implementación de ejemplo se muestra el flujo de traducción de directivas. En el caso de las cargas de trabajo existentes, use el patrón de migración local anterior en este artículo.

Crear los espacios de nombres

kubectl create namespace bookstore
kubectl create namespace bookbuyer
kubectl create namespace bookthief
kubectl create namespace bookwarehouse

Agregar una etiqueta de espacio de nombres para la inyección sidecar de Istio

Para OSM, con el comando osm namespace add <namespace> se crearon las anotaciones necesarias en el espacio de nombres del controlador OSM para agregar la inserción automática de sidecar. Con el complemento administrado de Istio, etiquete el espacio de nombres con la revisión de Istio instalada para permitir que el controlador de Istio inyecte los proxies de sidecar de Envoy. La etiqueta predeterminada istio-injection=enabled no habilita la inyección de sidecar para el complemento de Istio.

for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
  kubectl label namespace ${NAMESPACE} istio.io/rev=${REVISION}
done

Implementación del servicio virtual Istio para Bookstore

Despliegue el servicio virtual para el servicio bookstore.

kubectl apply -f - <<EOF
# Create bookstore virtual service
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookstore-virtualservice
  namespace: bookstore
spec:
  hosts:
  - bookstore
  http:
  - route:
    - destination:
        host: bookstore
EOF

Crear pods, servicios y cuentas de servicio

Utilice un único archivo de manifiesto que contenga las modificaciones comentadas anteriormente en la guía para desplegar las aplicaciones bookbuyer, bookthief, bookstore, bookwarehouse y mysql.

kubectl apply -f - <<EOF
##################################################################################################
# bookbuyer service
##################################################################################################
---
# Create bookbuyer Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookbuyer
  namespace: bookbuyer
---
# Create bookbuyer Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookbuyer
  namespace: bookbuyer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bookbuyer
      version: v1
  template:
    metadata:
      labels:
        app: bookbuyer
        version: v1
    spec:
      serviceAccountName: bookbuyer
      nodeSelector:
        kubernetes.io/arch: amd64
        kubernetes.io/os: linux
      containers:
        - name: bookbuyer
          image: openservicemesh/bookbuyer:latest-main
          imagePullPolicy: Always
          command: ["/bookbuyer"]
          env:
            - name: "BOOKSTORE_NAMESPACE"
              value: bookstore
            - name: "BOOKSTORE_SVC"
              value: bookstore
---
##################################################################################################
# bookthief service
##################################################################################################
---
# Create bookthief ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookthief
  namespace: bookthief
---
# Create bookthief Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookthief
  namespace: bookthief
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bookthief
  template:
    metadata:
      labels:
        app: bookthief
        version: v1
    spec:
      serviceAccountName: bookthief
      nodeSelector:
        kubernetes.io/arch: amd64
        kubernetes.io/os: linux
      containers:
        - name: bookthief
          image: openservicemesh/bookthief:latest-main
          imagePullPolicy: Always
          command: ["/bookthief"]
          env:
            - name: "BOOKSTORE_NAMESPACE"
              value: bookstore
            - name: "BOOKSTORE_SVC"
              value: bookstore
            - name: "BOOKTHIEF_EXPECTED_RESPONSE_CODE"
              value: "503"
---
##################################################################################################
# bookstore service version 1 & 2
##################################################################################################
---
# Create bookstore Service
apiVersion: v1
kind: Service
metadata:
  name: bookstore
  namespace: bookstore
  labels:
    app: bookstore
spec:
  ports:
    - port: 14001
      name: bookstore-port
  selector:
    app: bookstore

---
# Create bookstore Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookstore
  namespace: bookstore

---
# Create bookstore-v1 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookstore-v1
  namespace: bookstore
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bookstore
      version: v1
  template:
    metadata:
      labels:
        app: bookstore
        version: v1
    spec:
      serviceAccountName: bookstore
      nodeSelector:
        kubernetes.io/arch: amd64
        kubernetes.io/os: linux
      containers:
        - name: bookstore
          image: openservicemesh/bookstore:latest-main
          imagePullPolicy: Always
          ports:
            - containerPort: 14001
              name: web
          command: ["/bookstore"]
          args: ["--port", "14001"]
          env:
            - name: BOOKWAREHOUSE_NAMESPACE
              value: bookwarehouse
            - name: IDENTITY
              value: bookstore-v1

##################################################################################################
# bookwarehouse service
##################################################################################################
---
# Create bookwarehouse Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookwarehouse
  namespace: bookwarehouse
---
# Create bookwarehouse Service
apiVersion: v1
kind: Service
metadata:
  name: bookwarehouse
  namespace: bookwarehouse
  labels:
    app: bookwarehouse
spec:
  ports:
  - port: 14001
    name: bookwarehouse-port
  selector:
    app: bookwarehouse
---
# Create bookwarehouse Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookwarehouse
  namespace: bookwarehouse
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bookwarehouse
  template:
    metadata:
      labels:
        app: bookwarehouse
        version: v1
    spec:
      serviceAccountName: bookwarehouse
      nodeSelector:
        kubernetes.io/arch: amd64
        kubernetes.io/os: linux
      containers:
        - name: bookwarehouse
          image: openservicemesh/bookwarehouse:latest-main
          imagePullPolicy: Always
          command: ["/bookwarehouse"]
##################################################################################################
# mysql service
##################################################################################################
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mysql
  namespace: bookwarehouse
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: bookwarehouse
  labels:
    app: mysql
    service: mysql
spec:
  ports:
    - port: 3306
      name: tcp
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: bookwarehouse
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      serviceAccountName: mysql
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: mypassword
        - name: MYSQL_DATABASE
          value: booksdemo
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - mountPath: /mysql-data
          name: data
        readinessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 15
          periodSeconds: 10
      volumes:
        - name: data
          emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 250M
EOF

Para ver estos recursos en el clúster, ejecute los siguientes comandos:

kubectl get pods,deployments,serviceaccounts -n bookbuyer
kubectl get pods,deployments,serviceaccounts -n bookthief

kubectl get pods,deployments,serviceaccounts,services,endpoints -n bookstore
kubectl get pods,deployments,serviceaccounts,services,endpoints -n bookwarehouse

Visualización de las interfaces de usuario de la aplicación

De forma similar a la guía original de OSM, si tiene clonado el repositorio de OSM, puede usar los scripts de redirección de puertos para ver las interfaces de usuario de la aplicación. Para obtener más información, consulte Visualización de las interfaces de usuario de la aplicación. Por ahora, vea solo las interfaces de usuario de bookbuyer y bookthief.

cp .env.example .env
bash <<EOF
./scripts/port-forward-bookbuyer-ui.sh &
./scripts/port-forward-bookthief-ui.sh &
wait
EOF

En un explorador, abra las siguientes direcciones URL:

http://localhost:8080 - comprador de libros

http://localhost:8083 - ladrón de libros

Configuración de las directivas de tráfico de Istio

Para mantener la traducción de Istio alineada con el tutorial de Bookstore de OSM, comience con el modo de directiva de tráfico permisivo de OSM. El modo de directiva de tráfico permisivo de OSM permitía o denegaba el tráfico en la malla cuando no estaba implementada ninguna regla de control de acceso al tráfico de SMI específica. Este modo permite a los usuarios incorporar aplicaciones a la malla y obtener el cifrado mTLS antes de definir reglas de permiso explícitas. Puede establecer este valor en true o false a través de MeshConfig de OSM.

Istio controla el cumplimiento de mTLS de forma diferente. A diferencia de OSM, el modo permisivo de Istio configura automáticamente los servidores proxy sidecar para usar mTLS y permite a los servicios aceptar el tráfico de texto no cifrado y mTLS. Use la configuración de Istio PeerAuthentication como equivalente a la configuración del modo permisivo de OSM. Puede configurar PeerAuthentication para un espacio de nombres o para toda la malla. Para obtener más información, lea el artículo Migración mutua de TLS de Istio.

Aplicar el modo estricto de Istio a espacios de nombres de Bookstore

Recuerde que, al igual que el modo permisivo de OSM, la configuración de Istio PeerAuthentication solo se aplica a la exigencia de mTLS. Istio gestiona las políticas de capa 7, como las que se usan en los HTTPRouteGroups de OSM, con configuraciones AuthorizationPolicy.

Ponga los espacios de nombres bookbuyer, bookthief, bookstore y bookwarehouse en el modo estricto de mTLS de Istio.

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: bookbuyer
  namespace: bookbuyer
spec:
  mtls:
    mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: bookthief
  namespace: bookthief
spec:
  mtls:
    mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: bookstore
  namespace: bookstore
spec:
  mtls:
    mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: bookwarehouse
  namespace: bookwarehouse
spec:
  mtls:
    mode: STRICT
EOF

Implementación de directivas de control de acceso de Istio

OSM usa los recursos SMI Traffic Target y SMI Traffic Specs para definir directivas de control de acceso y enrutamiento para la comunicación de aplicaciones. Istio proporciona controles granulares similares mediante configuraciones de AuthorizationPolicy.

En el ejemplo siguiente se muestra la traducción de la directiva TrafficTarget de bookstore, que permite a bookbuyer comunicarse con bookstore utilizando rutas, encabezados y métodos específicos de nivel 7. Este contenido es una parte del manifiesto traffic-access-v1.yaml .

kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha3
metadata:
  name: bookstore
  namespace: bookstore
spec:
  destination:
    kind: ServiceAccount
    name: bookstore
    namespace: bookstore
  rules:
    - kind: HTTPRouteGroup
      name: bookstore-service-routes
      matches:
        - buy-a-book
        - books-bought
  sources:
    - kind: ServiceAccount
      name: bookbuyer
      namespace: bookbuyer
---
apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
  name: bookstore-service-routes
  namespace: bookstore
spec:
  matches:
    - name: books-bought
      pathRegex: /books-bought
      methods:
        - GET
      headers:
        - "user-agent": ".*-http-client/*.*"
        - "client-app": "bookbuyer"
    - name: buy-a-book
      pathRegex: ".*a-book.*new"
      methods:
        - GET

En la directiva TrafficTarget, spec.destination define el servicio de destino y spec.sources define el servicio de origen autorizado. En este ejemplo, bookbuyer puede comunicarse con la librería. El istio AuthorizationPolicy equivalente tiene el siguiente aspecto:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bookstore
  namespace: bookstore
spec:
  selector:
    matchLabels:
      app: bookstore
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer"]

En la AuthorizationPolicy de Istio, el servicio de destino TrafficTarget de OSM se asigna al espacio de nombres de directiva y a la coincidencia de etiquetas del selector. El servicio de origen se corresponde con el atributo source.serviceAccounts bajo rules.from.

Además de la configuración de origen y destino en TrafficTarget de OSM, OSM enlaza un HTTPRouteGroup para definir la autorización de nivel 7 para el origen. El siguiente HTTPRouteGroup incluye dos matches correspondientes al servicio de origen permitido.

apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
  name: bookstore-service-routes
  namespace: bookstore
spec:
  matches:
    - name: books-bought
      pathRegex: /books-bought
      methods:
        - GET
      headers:
        - "user-agent": ".*-http-client/*.*"
        - "client-app": "bookbuyer"
    - name: buy-a-book
      pathRegex: ".*a-book.*new"
      methods:
        - GET

La coincidencia books-bought permite al origen acceder a la ruta /books-bought utilizando el método GET con la información de los encabezados user-agent y client-app. La coincidencia buy-a-book utiliza una expresión regular para una ruta que contiene .*a-book.*new con el método GET.

Defina estas configuraciones de OSM HTTPRouteGroup en la sección de reglas del Istio AuthorizationPolicy. Mantenga las condiciones de origen, operación y encabezado en la misma regla para que no permitan solicitudes por separado. Los campos de cadena AuthorizationPolicy de Istio admiten coincidencias exactas, de prefijo, de sufijo y de presencia, no expresiones regulares arbitrarias de SMI. En la muestra siguiente se usan rutas exactas y un prefijo del agente de usuario de un cliente HTTP de Go que coincide con el de la muestra Bookstore. Para las cargas de trabajo, traduzca cada expresión regular de encabezado y SMI pathRegex a una coincidencia explícita de Istio que conserve el acceso previsto.

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "bookstore"
  namespace: bookstore
spec:
  selector:
    matchLabels:
      app: bookstore
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/books-bought"]
      when:
        - key: request.headers[user-agent]
          values: ["Go-http-client/*"]
        - key: request.headers[client-app]
          values: ["bookbuyer"]
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/buy-a-book/new"]

Implemente el manifiesto migrado de OSM traffic-access-v1.yaml como una AuthorizationPolicy de Istio. No hay una AuthorizationPolicy para bookthief, por lo que la interfaz de usuario de bookthief debe dejar de aumentar el número de libros desde bookstore v1:

kubectl apply -f - <<EOF
##################################################################################################
# bookstore policy
##################################################################################################
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "bookstore"
  namespace: bookstore
spec:
  selector:
    matchLabels:
      app: bookstore
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/books-bought"]
      when:
        - key: request.headers[user-agent]
          values: ["Go-http-client/*"]
        - key: request.headers[client-app]
          values: ["bookbuyer"]
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/buy-a-book/new"]
---
##################################################################################################
# bookwarehouse policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "bookwarehouse"
  namespace: bookwarehouse
spec:
  selector:
    matchLabels:
      app: bookwarehouse
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookstore/bookstore"]
      to:
        - operation:
            methods: ["POST"]
---
##################################################################################################
# mysql policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "mysql"
  namespace: bookwarehouse
spec:
  selector:
    matchLabels:
      app: mysql
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookwarehouse/bookwarehouse"]
      to:
         - operation:
            ports: ["3306"]
EOF

Permitir que la aplicación Bookthief acceda a Bookstore

Actualmente, ninguna AuthorizationPolicy permite que bookthief se comunique con bookstore. Implemente la siguiente AuthorizationPolicy para permitir que bookthief se comunique con bookstore. Tenga en cuenta la regla agregada en la directiva de bookstore que permite el acceso a bookthief.

kubectl apply -f - <<EOF
##################################################################################################
# bookstore policy
##################################################################################################
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "bookstore"
  namespace: bookstore
spec:
  selector:
    matchLabels:
      app: bookstore
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer", "bookthief/bookthief"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/books-bought"]
      when:
        - key: request.headers[user-agent]
          values: ["Go-http-client/*"]
        - key: request.headers[client-app]
          values: ["bookbuyer"]
    - from:
        - source:
            serviceAccounts: ["bookbuyer/bookbuyer", "bookthief/bookthief"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/buy-a-book/new"]
---
##################################################################################################
# bookwarehouse policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "bookwarehouse"
  namespace: bookwarehouse
spec:
  selector:
    matchLabels:
      app: bookwarehouse
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookstore/bookstore"]
      to:
        - operation:
            methods: ["POST"]
---
##################################################################################################
# mysql policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "mysql"
  namespace: bookwarehouse
spec:
  selector:
    matchLabels:
      app: mysql
  action: ALLOW
  rules:
    - from:
        - source:
            serviceAccounts: ["bookwarehouse/bookwarehouse"]
      to:
         - operation:
            ports: ["3306"]
EOF

La interfaz de usuario de bookthief debería incrementar ahora los libros de bookstore.

Resumen

En este tutorial se muestra cómo migrar directivas de OSM a directivas de Istio. Para obtener información sobre cómo implementar y operar el complemento istio administrado en AKS, consulte Instalación del complemento Istio. Revise los conceptos de Istio ascendentes cuando necesite información general sobre las API de Istio y el comportamiento de administración del tráfico.