Blog Post

Desenvolvedores BR
8 MIN READ

AKS & HELM

wdossantos's avatar
wdossantos
Icon for Microsoft rankMicrosoft
Nov 13, 2023

O Helm é um gerenciador de pacotes para Kubernetes que ajuda a instalar, gerenciar e atualizar aplicativos Kubernetes. O Helm usa pacotes chamados “charts” que contêm todos os recursos necessários para implantar um aplicativo no Kubernetes.

Algumas das operações comuns que você pode executar usando o helm incluem:

  • helm install: instala um chart no cluster do Kubernetes.
  • helm upgrade: atualiza um chart já instalado no cluster do Kubernetes.
  • helm delete: remove um chart do cluster do Kubernetes.
  • helm lint: verifica se o chart é válido.
  • helm template: gera o pacote.

Principais vantagens

  1. Instalação de uma aplicação conteinerizada no k8s de forma simplificada com apenas um comando
  2. Versionamento de releases
  3. Aproveitamento dos mesmos arquivos de recursos em vários ambientes
  4. Helm é um projeto no CNCF - Cloud Native Computing Foundation

Como eu instalo o Helm no Windows para interagir com um cluster AKS?

Para instalar o Helm no Windows e interagir com um cluster AKS, você pode seguir os seguintes passos:

  1. Baixe o instalador do Helm para Windows a partir do site oficial: https://get.helm.sh/helm-v3.7.1-windows-amd64.zip
  2. Extraia o conteúdo do arquivo ZIP para uma pasta de sua escolha.
  3. Adicione a pasta onde o Helm foi extraído ao PATH do Windows
  • helm version

Passo 1: Criar arquivos Helm

Comece criando uma estrutura de diretórios e arquivos para o Helm.

helm create helm-weather

O comando “helm create” é uma maneira conveniente de iniciar a criação de um novo chart Helm e fornece uma estrutura inicial para você começar a definir como os recursos do Kubernetes serão implantados e configurados usando o Helm. Você pode então personalizar e expandir essa estrutura de acordo com as necessidades do seu aplicativo ou serviço.

depois de rodar o comando “helm create” serão criados os seguintes elementos

  1. Diretório helm-weather: Este diretório é a raiz do seu chart Helm. Ele conterá todos os outros arquivos e diretórios relacionados ao chart.

  2. Arquivo Chart.yaml: Este arquivo YAML contém informações sobre o chart, como nome, versão, descrição e outros metadados.

  3. Diretório charts: Este diretório é usado para armazenar dependências de charts, caso o chart “helm-weather” dependa de outros charts.

  4. Diretório templates: Este diretório é onde você pode definir os modelos de recursos do Kubernetes que serão gerados quando você instalar o chart. Os modelos podem ser escritos em YAML e geralmente são usados para criar recursos como pods, serviços, configurações, etc.

  5. Arquivo values.yaml: Este arquivo contém os valores padrão que serão usados nos modelos do chart. Você pode substituir esses valores ao instalar o chart para personalizar a implantação.

  6. Arquivo charts/README.md: Este é um arquivo de documentação que fornece informações sobre o chart, como seu propósito e como usá-lo.

  7. Arquivo README.md: Este é um arquivo de documentação geral para o chart Helm.

Passo 2: Criar uma API Web

Agora, crie um projeto de API Web usando o .NET Core:

dotnet new webapi -o api-weather

Passo 3: Criar a imagem da aplicação

Adicione um Dockerfile para a sua aplicação. Você pode usar o Visual Studio Code e a extensão Docker para facilitar a criação do arquivo Docker. O Dockerfile pode ter o seguinte conteúdo:

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base  
WORKDIR /app  
EXPOSE 5001  
  
ENV ASPNETCORE\_URLS=http://+:5001  
  
\# Creates a non-root user with an explicit UID and adds permission to access the /app folder  
\# For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers  
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app  
USER appuser  
  
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:7.0 AS build  
ARG configuration=Release  
WORKDIR /src  
COPY \["api-weather.csproj", "./"\]  
RUN dotnet restore "api-weather.csproj"  
COPY . .  
WORKDIR "/src/."  
RUN dotnet build "api-weather.csproj" -c $configuration -o /app/build  
  
FROM build AS publish  
ARG configuration=Release  
RUN dotnet publish "api-weather.csproj" -c $configuration -o /app/publish /p:UseAppHost=false  
  
FROM base AS final  
WORKDIR /app  
COPY --from=publish /app/publish .  
ENTRYPOINT \["dotnet", "api-weather.dll"\]

Passo 4: Enviar a imagem para o ACR

Agora, você pode enviar a imagem Docker para o Azure Container Registry (ACR) usando o Azure CLI ou o Docker:

Usando o Azure CLI:

az acr build -t api-sampe01 --registry acrhelm01  .

Ou usando o Docker:

az acr login -n acrhelm01  
  
docker build -t api-sampe01 .  
docker tag api-sampe01 acrhelm01.azurecr.io/api-sampe01:001  
docker push acrhelm01.azurecr.io/api-sampe01:001

Passo 5: Validar os arquivos Helm

Acesse o diretório helm-weather e valide os arquivos Helm:

cd helm-weather  
helm template ./ --debug

Passo 6: Gerar o pacote Helm

Agora, gere o pacote Helm (arquivo tar.gz) a partir do diretório:

helm package ./ -d charts

Passo 7: Acesso ao cluster AKS

Certifique-se de que você tenha acesso ao cluster AKS onde deseja implantar o aplicativo. Você pode usar o Azure CLI para configurar o acesso:

az aks get-credentials --resource-group akshelmspoc --name akshelm01

Passo 8: Instalar o pacote no Cluster

Agora, você pode implantar o pacote Helm no seu cluster AKS:

helm upgrade helm-weather .\\charts\\helm-weather-0.1.0.tgz --namespace sample01  --create-namespace --install

Passo 9: Verificar o resultado

Após a implantação, você pode verificar o status dos recursos no cluster AKS usando o seguinte comando:

kubectl get all -n sample01

Você também pode analisar os detalhes de um pod específico:

kubectl describe pod helm-weather-7767995446-jchs6 -n sample01

Podemos ver a imagem do nginx:

Name:             helm-weather-7767995446-jchs6  
Namespace:        sample01  
Priority:         0  
Service Account:  helm-weather  
Node:             aks-agentpool-30542430-vmss000002/10.224.0.5  
Start Time:       Wed, 27 Sep 2023 11:15:53 -0300  
Labels:           app.kubernetes.io/instance=helm-weather  
                  app.kubernetes.io/name=helm-weather  
                  pod-template-hash=7767995446  
Annotations:      cni.projectcalico.org/containerID: 2273b655dd36ca0d3daaa722cab5a3ce8fd60b463f47fa249be62d9ec75ec6de  
                  cni.projectcalico.org/podIP: 10.244.1.8/32  
                  cni.projectcalico.org/podIPs: 10.244.1.8/32  
Status:           Running  
IP:               10.244.1.8  
IPs:  
  IP:           10.244.1.8  
Controlled By:  ReplicaSet/helm-weather-7767995446  
Containers:  
  helm-weather:  
    Container ID:   containerd://d07e997d2413a4ca353ce5b3cd6939426127920850c5ede5c740e82d1786065c  
    Image:          nginx:1.16.0  
    Image ID:       docker.io/library/nginx@sha256:3e373fd5b8d41baeddc24be311c5c6929425c04cabf893b874ac09b72a798010  
    Port:           80/TCP  
    Host Port:      0/TCP  
    State:          Running  
      Started:      Wed, 27 Sep 2023 11:15:57 -0300  
    Ready:          True  
    Restart Count:  0  
    Liveness:       http-get http://:http/ delay=0s timeout=1s period=10s #success=1 #failure=3  
    Readiness:      http-get http://:http/ delay=0s timeout=1s period=10s #success=1 #failure=3  
    Environment:    <none>  
    Mounts:  
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vq2xl (ro)  
Conditions:  
  Type              Status  
  Initialized       True  
  Ready             True  
  ContainersReady   True  
  PodScheduled      True  
Volumes:  
  kube-api-access-vq2xl:  
    Type:                    Projected (a volume that contains injected data from multiple sources)  
    TokenExpirationSeconds:  3607  
    ConfigMapName:           kube-root-ca.crt  
    ConfigMapOptional:       <nil>  
    DownwardAPI:             true  
QoS Class:                   BestEffort  
Node-Selectors:              <none>  
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s  
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s  
Events:  
  Type    Reason     Age    From               Message  
  ----    ------     ----   ----               -------  
  Normal  Scheduled  4m22s  default-scheduler  Successfully assigned sample01/helm-weather-7767995446-jchs6 to aks-agentpool-30542430-vmss000002  
  Normal  Pulling    4m21s  kubelet            Pulling image "nginx:1.16.0"  
  Normal  Pulled     4m18s  kubelet            Successfully pulled image "nginx:1.16.0" in 3.022874455s (3.022881155s including waiting)  
  Normal  Created    4m18s  kubelet            Created container helm-weather  
  Normal  Started    4m18s  kubelet            Started container helm-weather

Passo 10: Configurar o arquivo values.yaml

Edite o arquivo values.yaml para especificar a imagem Docker e as verificações de liveness e readiness:

image:  
  repository: acrhelm01.azurecr.io/api-sampe01  
  pullPolicy: IfNotPresent  
  # Overrides the image tag whose default is the chart appVersion.  
  tag: "001"

Configurar o livenessProbe e o readinessProbe

no arquivo deployment.yaml

livenessProbe:  
  httpGet:  
    path: {{ .Values.livenessProbe.httpGet.path }}  
    port: {{ .Values.livenessProbe.httpGet.port }}  
readinessProbe:  
  httpGet:  
    path: {{ .Values.readinessProbe.httpGet.path }}  
    port: {{ .Values.readinessProbe.httpGet.port }}

e no arquivo de values.yaml

livenessProbe:  
   httpGet:  
    path: /WeatherForecast  
    port: 5001  
  
readinessProbe:  
   httpGet:  
    path: /WeatherForecast  
    port: 5001

Em resumo, essas configurações permitem que os operadores personalizem os valores das configurações do aplicativo quando implantam o chart Helm. As configurações padrão são definidas no arquivo values.yaml, mas podem ser substituídas por valores específicos de implantação, dependendo das necessidades do ambiente em que o chart é implantado. Isso é útil para garantir que o aplicativo seja implantado com configurações adequadas para cada implantação.

Configurar o Servico ClusterIP

no arquivo service.yaml

targetPort: {{ .Values.service.targetPort }}

e no arquivo values.yaml

service:  
  type: LoadBalancer  
  port: 80  
  targetPort: 5001

Valida

helm template ./ --debug

gera outro pacote

helm package ./ -d charts --version 0.1.1

Passo 11: Atualizar o Deploy

Se você fizer alterações nos valores do Helm, atualize o deploy:

helm upgrade helm-weather .\\charts\\helm-weather-0.1.1.tgz --namespace sample01  --create-namespace --install

Passo 12: Verificar os Pods

Verifique o estado dos pods após a atualização:

kubectl get all -n sample01

subiu

NAME                                READY   STATUS    RESTARTS   AGE  
pod/helm-weather-57488847d8-jdxmz   1/1     Running   0          34m  
  
NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE  
service/helm-weather   ClusterIP   10.0.201.39   <none>        80/TCP    128m  
  
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE  
deployment.apps/helm-weather   1/1     1            1           128m  
  
NAME                                      DESIRED   CURRENT   READY   AGE  
replicaset.apps/helm-weather-568c9ddbd    0         0         0       101m  
replicaset.apps/helm-weather-57488847d8   1         1         1       34m  
replicaset.apps/helm-weather-646c667ccd   0         0         0       115m  
replicaset.apps/helm-weather-7767995446   0         0         0       128m  
replicaset.apps/helm-weather-7fcd86b448   0         0         0       109m

Também podemos automatizar esse processo usando o Azure devops, para isso vamos precisar de duas services connections:

  1. docker registry
  2. Azure Resource manager

e das tasks de:

  1. Docker
  2. HelmDeploy
  3. HelmInstaller
  4. HelmDeploy

mais ou menos isso

trigger:  
\- none  
  
stages:  
\- stage: Build  
  displayName: Build Artifact  
  jobs:  
  - job: Build  
    pool:  
      vmImage: ubuntu-latest  
    displayName: Build Artifact  
    steps:  
    - task: Docker@2  
      inputs:  
        containerRegistry: 'acrhelm01'  
        repository: 'api-weather'  
        command: 'buildAndPush'  
        Dockerfile: 'sample01/api-weather/Dockerfile'  
        tags: '$(Build.BuildId)'  
    - bash: |  
            helm template ./sample01/helm-weather  
      failOnStderr: true  
      displayName: 'Helm template - renderiza o template, validacao previa'  
    - task: HelmDeploy@0  
      inputs:  
        command: 'package'  
        chartPath: '././sample01/helm-weather'  
        chartVersion: '$(Build.BuildId)'  
  
    - task: CopyFiles@2  
      inputs:  
        Contents: |  
          helm-weather/\*\*/\*.tgz  
        TargetFolder: '$(Build.ArtifactStagingDirectory)'  
    - task: PublishPipelineArtifact@1  
      inputs:  
        targetPath: '$(Build.ArtifactStagingDirectory)'  
        artifact: 'drop'  
        publishLocation: 'pipeline'  
  
              
\- stage: Deploy  
  displayName: Deploy  
  dependsOn: Build  
  condition: succeeded()  
  jobs:  
  - deployment: DeployWeb  
    displayName: deploy Web App  
    pool:  
      vmImage: 'Ubuntu-latest'  
    environment: 'aks'  
    strategy:  
      runOnce:  
        deploy:  
          steps:  
          - download: current  
            artifact: drop  
          - task: HelmInstaller@1  
            displayName: 'Helm install'  
            inputs:  
              helmVersionToInstall: 3.11.2  
          - task: HelmDeploy@0  
            inputs:  
              connectionType: 'Azure Resource Manager'  
              azureSubscription: 'akshelmpoc'  
              azureResourceGroup: 'akshelmspoc'  
              kubernetesCluster: 'akshelm01'  
              namespace: 'sample01'  
              command: 'upgrade'  
              chartType: 'FilePath'  
              chartPath: '$(Pipeline.Workspace)/drop/helm-weather-$(Build.BuildID).tgz'  
              chartVersion: '$(Build.BuildId)'  
              releaseName: 'helm-weather'  
              overrideValues: 'image.repository=acrhelm01.azurecr.io/api-weather,image.tag=$(Build.BuildID)'

verificar

 kubectl get all -n sample01

 

NAME                                READY   STATUS    RESTARTS   AGE
pod/helm-weather-77594b48c5-ql96l 1/1 Running 0 24s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/helm-weather LoadBalancer 10.0.65.168 20.85.198.43 80:30330/TCP 6m45s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/helm-weather 1/1 1 1 6m44s

NAME DESIRED CURRENT READY AGE
replicaset.apps/helm-weather-568c9ddbd 0 0 0 6m45s
replicaset.apps/helm-weather-57488847d8 0 0 0 6m45s
replicaset.apps/helm-weather-646c667ccd 0 0 0 6m45s
replicaset.apps/helm-weather-6b5486b6d6 0 0 0 6m45s
replicaset.apps/helm-weather-77594b48c5 1 1 1 25s
replicaset.apps/helm-weather-7767995446 0 0 0 6m45s
replicaset.apps/helm-weather-7fcd86b448 0 0 0 6m45s

 

http://20.85.198.43/WeatherForecast

Conclusão

Com isso, você configurou com sucesso a implantação de uma aplicação de API web no Azure Kubernetes Service usando Helm e o Azure Container Registry. Além disso, você também automatizou o processo usando o Azure DevOps para maior eficiência

Referências

  1. Helm
  2. Desenvolver no Serviço de Kubernetes do Azure (AKS) com o Helm — Azure Kubernetes Service | Microsoft Learn
Updated Nov 13, 2023
Version 1.0
No CommentsBe the first to comment