Exercício - Implementar resiliência de infraestrutura com o Kubernetes
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:
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.
Você precisa editar esses arquivos para usar as imagens enviadas por push para o Docker Hub.
No espaço de código, abra o arquivo backend-deploy.yml.
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.
Repita estas etapas para o arquivo frontend-deploy.yml .
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.
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
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
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.
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:
Adicione a
linkerd.io/inject: enabled
anotação ao arquivo frontend-deploy.yml no mesmo local.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.
No terminal, execute este comando para instalar a extensão:
linkerd viz install | kubectl apply -f -
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.
No painel Linkerd, selecione Namespaces.
Em Métricas HTTP, selecione padrão.
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:
Verifique o status dos pods em execução com este comando:
kubectl get pods --all-namespaces
Pare todos os pods de serviço do produto:
kubectl scale deployment productsbackend --replicas=0
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."
Reinicie os pods de serviço do produto:
kubectl scale deployment productsbackend --replicas=1
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:
- Configurando novas tentativas - Documentação do Linkerd
- Configurando tempos limite - Documentação do Linkerd
- How we designed retries in Linkerd 2.2 - Linkerd blog (Como concebemos as repetições no Linkerd 2.2 – blogue do Linkerd)