Ejercicio: Implementación de la resistencia de la infraestructura con Kubernetes

Completado

En la unidad anterior, implementó la resistencia agregando código de control de errores mediante la extensión de resistencia nativa de .NET. Sin embargo, este cambio solo se aplica al servicio que ha cambiado. La actualización de una aplicación grande con muchos servicios sería intrivial.

En lugar de usar la resistencia basada en código , esta unidad usa un enfoque denominado resistencia basada en infraestructura que abarca toda la aplicación. Harás lo siguiente:

  • Vuelva a implementar la aplicación sin resistencia en Kubernetes.
  • Implemente Linkerd en el clúster de Kubernetes.
  • Configure la aplicación para que use Linkerd para lograr resistencia.
  • Explore el comportamiento de la aplicación con Linkerd.

Reimplementación de la aplicación

Antes de aplicar Linkerd, revierta la aplicación a un estado antes de agregar la resistencia basada en código. Para revertir, siga estos pasos:

  1. En el panel inferior, seleccione la pestaña TERMINAL y ejecute los siguientes comandos git para deshacer los cambios:

    cd Store
    git checkout Program.cs
    git checkout Store.csproj
    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    

Instalación de Kubernetes

En el espacio de código, instale Kubernetes y k3d. k3d es una herramienta que ejecuta un clúster de Kubernetes de un solo nodo dentro de una máquina virtual (VM) en la máquina local. Resulta útil para probar las implementaciones de Kubernetes localmente y se ejecuta bien dentro de un espacio de código.

Ejecute estos comandos para instalar Kubernetes y MiniKube:

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubectl

curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create devcluster --config k3d.yml

Implementación de los servicios de eShop en Docker Hub

Las imágenes locales de los servicios que cree deben hospedarse en un registro de contenedor para poder implementarse en Kubernetes. En esta unidad, usará Docker Hub como registro de contenedor.

Ejecute estos comandos para insertar las imágenes en Docker Hub:

sudo docker login

sudo docker tag products [your username]/productservice
sudo docker tag store [your username]/storeimage

sudo docker push [your username]/productservice
sudo docker push [your username]/storeimage

Conversión del archivo docker-compose en manifiestos de Kubernetes

En este momento, se define cómo se ejecuta la aplicación en Docker. Kubernetes usa un formato diferente para definir cómo se ejecuta la aplicación. Puede usar una herramienta denominada Kompose para convertir el archivo docker-compose en manifiestos de Kubernetes.

  1. Debe editar estos archivos para usar las imágenes que insertó en Docker Hub.

  2. En el espacio de código, abra el archivo backend-deploy.yml.

  3. Cambie esta línea:

      containers:
        - image: [YOUR DOCKER USER NAME]/productservice:latest
    

    Reemplace el marcador de posición [SU NOMBRE DE USUARIO DE DOCKER] por el nombre de usuario real de Docker.

  4. Repita estos pasos para el archivo frontend-deploy.yml .

  5. Cambie esta línea:

      containers:
      - name: storefrontend
        image: [YOUR DOCKER USER NAME]/storeimage:latest  
    

    Reemplace el marcador de posición [SU NOMBRE DE USUARIO DE DOCKER] por el nombre de usuario real de Docker.

  6. Implemente la aplicación eShop en Kubernetes:

    kubectl apply -f backend-deploy.yml,frontend-deploy.yml  
    

    Debería ver una salida similar a los mensajes siguientes:

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. Compruebe que todos los servicios se están ejecutando:

    kubectl get pods
    

    Debería ver una salida similar a los mensajes siguientes:

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. Cambie a la pestaña PUERTOS para ver la eShop que se ejecuta en Kubernetes, seleccione el icono de globo junto al puerto front-end (32000).

Instalación de linkerd

El contenedor de desarrollo necesita instalar la CLI de Linkerd. Ejecute el siguiente comando para confirmar que se cumplen los requisitos previos de Linkerd:

curl -sL run.linkerd.io/install | sh
export PATH=$PATH:/home/vscode/.linkerd2/bin
linkerd check --pre

Aparece una variación del resultado siguiente:

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected

pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability

linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date

Status check results are √

Implementación de Linkerd en Kubernetes

En primer lugar, ejecute el siguiente comando para instalar las definiciones de recursos personalizados (CRD):

linkerd install --crds | kubectl apply -f -

Ejecute el siguiente comando:

linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -

En el comando anterior:

  • linkerd install genera un manifiesto de Kubernetes con los recursos necesarios del plano de control.
  • El manifiesto generado se canaliza a kubectl apply, que instala esos recursos del plano de control en el clúster de Kubernetes.

La primera línea de la salida muestra que el plano de control se instaló en su propio linkerd espacio de nombres. La salida restante representa los objetos que se crean.

namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created

Validación de la implementación de Linkerd

Ejecute el siguiente comando:

linkerd check

El comando anterior analiza las configuraciones de la CLI de Linkerd y el plano de control. Si Linkerd está configurado correctamente, se muestra la siguiente salida:

kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-api
-----------
√ control plane pods are ready
√ control plane self-check
√ [kubernetes] control plane can talk to Kubernetes
√ [prometheus] control plane can talk to Prometheus
√ tap api service is running

linkerd-version
---------------
√ can determine the latest version
√ CLI is up to date

control-plane-version
---------------------
√ control plane is up to date
√ control plane and CLI versions match

linkerd-addons
--------------
√ 'linkerd-config-addons' config map exists

linkerd-grafana
---------------
√ grafana add-on service account exists
√ grafana add-on config map exists
√ grafana pod is running

Status check results are √

Sugerencia

Para ver una lista de componentes de Linkerd instalados, ejecute este comando: kubectl -n linkerd get deploy

Configuración de la aplicación para usar Linkerd

Linkerd se implementa, pero no está configurado. El comportamiento de la aplicación no cambia.

Linkerd no es consciente de los elementos internos del servicio y no puede determinar si es adecuado reintentar una solicitud con error. Por ejemplo, sería una mala idea volver a intentar un ERROR HTTP POST para un pago. Un perfil de servicio es necesario por este motivo. Un perfil de servicio es un recurso de Kubernetes personalizado que define rutas para el servicio. También habilita las características por ruta, como reintentos y tiempos de espera. Linkerd solo reintenta las rutas configuradas en el manifiesto del perfil de servicio.

Por motivos de brevedad, implemente Linkerd solo en los servicios de agregador y cupones. Para implementar Linkerd para esos dos servicios, hará lo siguiente:

  • Modifique las implementaciones de eShop para que Linkerd cree su contenedor proxy en los pods.
  • Para configurar reintentos en la ruta del servicio de cupones, agregue un objeto de perfil de servicio al clúster.

Modificación de las implementaciones de eShop

Los servicios deben configurarse para usar contenedores de proxy de Linkerd.

  1. Agregue la linkerd.io/inject: enabled anotación al archivo backend-deploy.yml en metadatos de plantilla.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Agregue la linkerd.io/inject: enabled anotación al archivo frontend-deploy.yml en el mismo lugar.

  3. Actualice las implementaciones en el clúster de Kubernetes:

    kubectl apply -f backend-deploy.yml,frontend-deploy.yml
    

Aplicar el perfil de servicio linkerd para el servicio de producto

El manifiesto de perfil de servicio para el servicio de producto es:

apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: backend
  namespace: default
spec:
  routes:
  - condition:
      method: GET
      pathRegex: /api/Product
    name: GET /v1/products
    isRetryable: true
  retryBudget:
    retryRatio: 0.2
    minRetriesPerSecond: 10
    ttl: 120s

El manifiesto anterior está configurado para:

  • Se puede reintentar cualquier ruta HTTP GET idempotente que coincida con el patrón /api/Product .
  • Los reintentos no pueden agregar más de un 20 % adicional a la carga de la solicitud, además de otros 10 reintentos "libres" por segundo.

Ejecute el siguiente comando para usar el perfil de servicio en el clúster de Kubernetes:

kubectl apply -f - <<EOF
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: backend
  namespace: default
spec:
  routes:
  - condition:
      method: GET
      pathRegex: /api/Product
    name: GET /v1/products 
    isRetryable: true
  retryBudget:
    retryRatio: 0.2
    minRetriesPerSecond: 10
    ttl: 120s  
EOF

Se mostrará la siguiente salida:

serviceprofile.linkerd.io/backend created

Instalación de la supervisión en la malla de servicio

Linkerd tiene extensiones para proporcionarle características adicionales. Instale la extensión viz y vea el estado de la aplicación en el panel de Linkerd.

  1. En el terminal, ejecute este comando para instalar la extensión:

    linkerd viz install | kubectl apply -f -
    
  2. Vea el panel con este comando:

    linkerd viz dashboard
    

    Vaya a la pestaña PUERTOS y para ver un nuevo puerto reenviado con un proceso de enlace del panel viz en ejecución. Seleccione abrir en el explorador para abrir el panel.

  3. En el panel linkerd, seleccione Espacios de nombres.

  4. En Métricas HTTP, seleccione predeterminado.

    Captura de pantalla que muestra el panel de Linkerd con el front-end y el back-end.

Resistencia de Test Linkerd

Una vez que los contenedores implementados de nuevo estén en buen estado, siga estos pasos para probar el comportamiento de la aplicación con Linkerd:

  1. Compruebe el estado de los pods en ejecución con este comando:

    kubectl get pods --all-namespaces
    
  2. Detenga todos los pods del servicio de producto:

    kubectl scale deployment productsbackend --replicas=0
    
  3. Vaya a la aplicación web de eShop e intente ver los productos. Hay un retraso hasta el mensaje de error : "Hay un problema al cargar nuestros productos. Inténtelo de nuevo más tarde".

  4. Reinicie los pods del servicio de producto:

    kubectl scale deployment productsbackend --replicas=1
    
  5. La aplicación ahora debería mostrar los productos.

Linkerd sigue un enfoque diferente a la resistencia que ha visto con la resistencia basada en código. Linkerd reintenta de forma transparente la operación varias veces en sucesión rápida. No es necesario cambiar la aplicación para admitir este comportamiento.

Información adicional

Para obtener más información sobre la configuración de Linkerd, consulte los siguientes recursos: