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

Concluído

Na unidade anterior, você implementou resiliência adicionando código de tratamento de falhas usando a extensão de resiliência nativa do .NET. No entanto, esta alteração aplica-se apenas ao serviço que alterou. Atualizar um aplicativo grande com muitos serviços não seria trivial.

Em vez de usar resiliência baseada em código, essa unidade usa uma abordagem chamada resiliência baseada em infraestrutura que abrange todo o aplicativo. Irá:

  • Reimplante o aplicativo sem qualquer resiliência no Kubernetes.
  • Implante o Linkerd em seu cluster Kubernetes.
  • Configurar a aplicação de forma a utilizar o Linkerd para resiliência.
  • Explorar o comportamento da aplicação com o Linkerd.

Implementar novamente a aplicação

Antes de aplicar o Linkerd, reverta a aplicação para um estado anterior à adição da resiliência baseada no código. Para reverter, siga estes passos:

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

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

Instalar o Kubernetes

No seu espaço de código, instale o Kubernetes e o k3d. k3d é uma ferramenta que executa um cluster Kubernetes de nó único dentro de uma máquina virtual (VM) em sua máquina local. É útil para testar implantações do Kubernetes localmente e funciona bem dentro de um espaço de código.

Execute estes 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 da 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 implantadas no Kubernetes. Nesta unidade, você usa o Docker Hub como seu registro de contêiner.

Execute estes comandos para enviar suas imagens 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

Converta seu arquivo docker-compose em manifestos do Kubernetes

No momento, você define como seu aplicativo é executado no docker. O Kubernetes usa um formato diferente para definir como 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 espaço de código, abra o arquivo backend-deploy.yml.

  3. Altere esta linha:

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

    Substitua o espaço reservado [SEU NOME DE USUÁRIO DO DOCKER] pelo seu nome de usuário real do Docker.

  4. Repita estas 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 [SEU NOME DE USUÁRIO DO DOCKER] pelo seu nome de usuário real do Docker.

  6. Implante o aplicativo eShop no Kubernetes:

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

    Você deve 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ê deve 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 visualizar a eShop em execução no Kubernetes, selecione o ícone de globo ao lado da porta Front-End (32000).

Instalar linkerd

O contêiner de desenvolvimento precisa da CLI do Linkerd para ser instalado. Execute o seguinte comando para confirmar se os pré-requisitos do Linkerd estão satisfeitos:

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

É apresentada uma variação da seguinte saída:

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 CRDs (Custom Resource Definitions):

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 plano de controlo necessários.
  • O manifesto gerado é canalizado para kubectl apply, que instala esses recursos do plano de controle no cluster do Kubernetes.

A primeira linha da saída mostra que o plano de controlo foi instalado no seu próprio espaço de nomes do linkerd. A restante saída representa os objetos que estão a ser criados.

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 implementação do Linkerd

Execute o seguinte comando:

linkerd check

O comando anterior analisa as configurações da CLI do Linkerd e o plano de controlo. Se o Linkerd for configurado corretamente, será apresentada a seguinte saída:

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 √

Gorjeta

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

Configurar a aplicação para utilizar o Linkerd

O Linkerd está implantado, mas não está configurado. O comportamento da aplicação não se alterou.

O Linkerd não tem conhecimento dos internos de serviço e não consegue determinar se é apropriado repetir um pedido falhado. Por exemplo, seria má ideia repetir o pedido HTTP POST falhado de um pagamento. Um perfil de serviço é necessário por esse motivo. Um perfil de serviço é um recurso personalizado do Kubernetes que define rotas para o serviço. Também permite funcionalidades específicas para cada rota, tais como repetições e tempos limite. O Linkerd só efetua repetições para rotas que estejam configuradas no manifesto do perfil de serviço.

Para maior brevidade, implemente o Linkerd apenas nos serviços agregadores e de cupões. Para implementar o Linkerd nesses dois serviços, irá:

  • Modifique as implantações do eShop para que o Linkerd crie seu contêiner 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 da eShop

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

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

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

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

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

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

O manifesto do perfil de serviço para o serviço do 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 está configurado da seguinte forma:

  • Qualquer rota HTTP GET idempotente que corresponda ao padrão /api/Product possa ser repetida.
  • As novas tentativas não podem adicionar mais de 20% à carga de solicitação, além de outras 10 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

É apresentada a seguinte saída:

serviceprofile.linkerd.io/backend created

Instalar o monitoramento na malha de serviço

Linkerd tem extensões para lhe dar recursos extras. Instale a extensão de visualização e visualize o status do aplicativo no painel do Linkerd.

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

    linkerd viz install | kubectl apply -f -
    
  2. Veja o painel com este comando:

    linkerd viz dashboard
    

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

  3. No painel 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

Depois de os contentores implementados novamente estarem em bom estado de funcionamento, siga os seguintes passos para testar o comportamento da aplicação com o Linkerd:

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

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

    kubectl scale deployment productsbackend --replicas=0
    
  3. Aceda à aplicação Web eShop e tente ver os produtos. Há um atraso até a mensagem de erro, "Há um problema ao carregar nossos produtos. Por favor, tente novamente mais tarde."

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

    kubectl scale deployment productsbackend --replicas=1
    
  5. O aplicativo agora deve 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 a operação múltiplas vezes em rápida sucessão. 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, veja os seguintes recursos: