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 cambió. Actualizar una aplicación grande con muchos servicios sería no trivial.

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

  • Vuelva a implementar la aplicación sin resistencia en Kubernetes.
  • Implementar Linkerd en su clúster de Kubernetes.
  • Configurar la aplicación para que use Linkerd a fin de obtener resistencia.
  • Explorar 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 anterior a 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
    

Instalar la CLI

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

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

Implementar 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

Convetir el archivo docker-compose en manifiestos de Kubernetes

Por el 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 codespace, 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 [YOUR DOCKER USER NAME] por su nombre de usuario de Docker real.

  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 [YOUR DOCKER USER NAME] por su nombre de usuario de Docker real.

  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 se están ejecutando todos los servicios:

    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 aplicación eShop que se ejecuta en Kubernetes y seleccione el icono de globo junto al puerto de Front-end (32000).

Instalar 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 √

Implementar 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 del plano de control necesarios.
  • 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 espacio de nombres linkerd. La salida restante representa los objetos que se van a crear.

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 comando siguiente:

linkerd check

El comando anterior analiza las configuraciones de la CLI y el plano de control de Linkerd. Si Linkerd se configura 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

Si quiere ver una lista de los componentes de Linkerd que se instalaron, 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 reconoce los aspectos internos del servicio y no puede determinar si es adecuado reintentar una solicitud con errores. Por ejemplo, sería mala idea reintentar un HTTP POST erróneo para un pago. Es por esto que se necesita un perfil de servicio. Un perfil de servicio es un recurso Kubernetes personalizado que define rutas para el servicio. También permite características por ruta, como los reintentos y los tiempos de espera. Linkerd solo reintenta las rutas configuradas en el manifiesto del perfil de servicio.

Para mayor brevedad, implemente Linkerd solo en los servicios del agregador y de cupones. Para implementar Linkerd para estos dos servicios, deberá hacer lo siguiente:

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

Modificar las implementaciones de eShop

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

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

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Agregue la anotación linkerd.io/inject: enabled 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
    

Aplicación del 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:

  • Cualquier ruta HTTP GET idempotente que coincida con el patrón /api/Product se puede reintentar.
  • Los reintentos no pueden agregar más de un 20 por ciento adicional a la carga de solicitud, además de otros 10 reintentos "disponibles" 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

Instalar la supervisión en la malla de servicio

Linkerd tiene extensiones para proporcionarle características adicionales. Instale la extensión viz y verá 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. Visualice el panel con este comando:

    linkerd viz dashboard
    

    Vaya a la pestaña PUERTOS para ver un nuevo puerto reenviado con un proceso de linkerd viz dashboard en ejecución. Seleccione Abrir en navegador para abrir el panel.

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

  4. En Métricas HTTP, seleccione predeterminado.

    Screenshot showing the Linkerd dashboard with both the frontend and backend.

Pruebe la resistencia de Linkerd

Una vez que los contenedores que se han reimplementado correctamente 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 que aparece 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 de la resistencia diferente del que ha visto con la resistencia basada en el código. Linkerd reintentó de forma transparente la operación varias veces en una 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: