Exercício: Implementar uma resiliência de infraestrutura com o Kubernetes

Concluído

Na unidade anterior, você implementou a resiliência adicionando um código de manuseio de falhas usando a extensão de resiliência nativa do .NET. No entanto, essa alteração se aplica somente ao serviço que você alterou. Atualizar um aplicativo grande com muitos serviços seria uma tarefa nada trivial.

Em vez de usar resiliência baseada em código, esta unidade usa uma abordagem chamada resiliência baseada em infraestrutura, que abrange todo o aplicativo. Você terá a oportunidade de:

  • Implante novamente o aplicativo sem nenhuma resiliência no Kubernetes.
  • Implante o Linkerd no seu cluster do Kubernetes.
  • Configurar o aplicativo para usar o Linkerd para fins de resiliência.
  • Explorar o comportamento do aplicativo com o Linkerd.

Reimplantar o aplicativo

Antes de aplicar o Linkerd, reverta o aplicativo para um estado anterior à adição da resiliência baseada em código. Para reverter, siga essas etapas:

  1. No painel inferior, selecione a guia TERMINAL e execute os seguintes comandos do Git para desfazer suas alterações:

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

Instalar o Kubernetes

Em seu codespace, instale o Kubernetes e o k3d. k3d é uma ferramenta que executa um cluster do Kubernetes de nó único dentro de uma máquina virtual (VM) em seu computador local. É útil para testar implantações do Kubernetes localmente e pode ser bem executado dentro de um codespace.

Execute esses comandos para instalar o Kubernetes e o 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

Implantar os serviços do eShop no Docker Hub

As imagens locais de seus serviços que você cria precisam ser hospedadas em um registro de contêiner para serem implantáveis no Kubernetes. Nesta unidade, você usa o Docker Hub como registro de contêiner.

Execute esses comandos para enviar suas imagens por push para o 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

Converter seu arquivo docker-compose em manifestos do Kubernetes

No momento, você define como o seu aplicativo é executado no Docker. O Kubernetes usa um formato diferente para definir como o seu aplicativo é executado. Você pode usar uma ferramenta chamada Kompose para converter seu arquivo docker-compose em manifestos do Kubernetes.

  1. Você precisa editar esses arquivos para usar as imagens enviadas por push para o Docker Hub.

  2. No codespace, abra o arquivo backend-deploy.yml.

  3. Altere esta linha:

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

    Substitua o espaço reservado [YOUR DOCKER USER NAME] por seu nome de usuário do Docker real.

  4. Repita essas etapas para o arquivo frontend-deploy.yml.

  5. Altere esta linha:

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

    Substitua o espaço reservado [YOUR DOCKER USER NAME] por seu nome de usuário do Docker real.

  6. Implante o aplicativo eShop no Kubernetes:

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

    Você deverá ver uma saída semelhante às seguintes mensagens:

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. Verifique se todos os serviços estão em execução:

    kubectl get pods
    

    Você deverá ver uma saída semelhante às seguintes mensagens:

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. Alterne para a guia PORTAS para ver o eShop em execução no Kubernetes e selecione o ícone de globo ao lado da porta de Front-End (32000).

Instalar o Linkerd

O contêiner de desenvolvimento requer que a CLI do Linkerd seja instalada. Execute o seguinte comando para confirmar se os pré-requisitos do Linkerd foram satisfeitos:

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

Uma variação do seguinte resultado é exibida:

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 √

Implantar o Linkerd no Kubernetes

Primeiro, execute o seguinte comando para instalar as Definições de Recurso Personalizado (CRDs):

linkerd install --crds | kubectl apply -f -

Em seguida, execute o seguinte comando:

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

No comando anterior:

  • linkerd install gera um manifesto do Kubernetes com os recursos de painel de controle necessários.
  • O manifesto gerado é canalizado para o kubectl apply, que instala esses recursos do painel de controle no cluster do Kubernetes.

A primeira linha da saída mostra que o painel de controle foi instalado em seu próprio namespace linkerd. A saída restante representa a criação dos objetos.

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

Validar a implantação do Linkerd

Execute o seguinte comando:

linkerd check

O comando anterior analisa as configurações da CLI do Linkerd e do painel de controle. Se o Linkerd estiver configurado corretamente, esta saída será exibida:

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 √

Dica

Para ver uma lista dos componentes do Linkerd que foram instalados, execute este comando: kubectl -n linkerd get deploy

Configurar o aplicativo para usar o Linkerd

O Linkerd foi implantado, mas não está configurado. O comportamento do aplicativo continua inalterado.

O Linkerd não reconhece os elementos internos do serviço e não é capaz de determinar se é apropriado repetir uma solicitação com falha. Por exemplo, seria uma má ideia repetir um HTTP POST com falha para um pagamento. Por isso um perfil de serviço é necessário. Um perfil de serviço é um recurso personalizado do Kubernetes que define as rotas para o serviço. Ele também habilita recursos segundo a rota, como repetições e tempos limite. O Linkerd repete apenas as rotas configuradas no manifesto do perfil de serviço.

Para resumir, implemente o Linkerd somente nos serviços de agregador e de cupom. Para implementar o Linkerd nesses dois serviços, você vai:

  • Modifique as implantações do eShop para que o Linkerd crie seu contêiner de proxy nos pods.
  • Para configurar novas tentativas na rota do serviço de cupom, adicione um objeto de perfil de serviço ao cluster.

Modificar as implantações do eShop

Os serviços precisam ser configurados para usar contêineres de proxy do Linkerd.

  1. Adicione a anotação linkerd.io/inject: enabled ao arquivo backend-deploy.yml nos metadados de modelo.

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. Adicione a anotação linkerd.io/inject: enabled ao arquivo frontend-deploy.yml no mesmo lugar.

  3. Atualize as implantações no cluster do Kubernetes:

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

Aplicar o perfil de serviço do Linkerd para o serviço de produto

O manifesto do perfil de serviço para o serviço de produto é:

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

O manifesto anterior é configurado para:

  • Qualquer rota HTTP GET idempotente correspondente ao padrão /api/Product possa ser repetida.
  • As novas tentativas poderem adicionar não mais do que 20% a mais à carga da solicitação, além de outras 10 novas tentativas "gratuitas" por segundo.

Execute o seguinte comando para usar o perfil de serviço no cluster do 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

O seguinte resultado é exibido:

serviceprofile.linkerd.io/backend created

Instalar o monitoramento na malha do serviço

O Linkerd tem extensões para fornecer recursos extras. Instale a extensão viz e exiba o status do aplicativo no painel do Linkerd.

  1. No terminal, execute esse comando para instalar a extensão:

    linkerd viz install | kubectl apply -f -
    
  2. Visualize o painel de controle com o comando a seguir:

    linkerd viz dashboard
    

    Vá para a guia PORTAS e veja uma nova porta encaminhada com um processo linkerd viz dashboard em execução. Selecione Abrir no navegador para abrir o painel.

  3. No painel de controle do Linkerd, selecione Namespaces.

  4. Em Métricas HTTP, selecione padrão.

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

Testar a resiliência do Linkerd

Quando os contêineres reimplantados estiverem íntegros, use as seguintes etapas para testar o comportamento do aplicativo com o Linkerd:

  1. Verifique o status dos pods em execução com o comando a seguir:

    kubectl get pods --all-namespaces
    
  2. Pare todos os pods do serviço de produto:

    kubectl scale deployment productsbackend --replicas=0
    
  3. Navegue até o aplicativo Web eShop e tente visualizar os produtos. Há um atraso até ser exibida a mensagem de erro: "Há um problema ao carregar nossos produtos. Tente novamente mais tarde."

  4. Reinicie os pods do serviço de produto:

    kubectl scale deployment productsbackend --replicas=1
    
  5. O aplicativo agora deverá exibir os produtos.

O Linkerd segue uma abordagem de resiliência diferente da que você viu com a resiliência baseada em código. O Linkerd repetiu várias vezes a operação de maneira transparente em uma sequência rápida. O aplicativo não precisou ser alterado para dar suporte a esse comportamento.

Informações adicionais

Para obter mais informações sobre a configuração do Linkerd, confira os recursos a seguir: