Gerenciar uma versão do Helm

Concluído

Como usar funções em um modelo do Helm

A linguagem do modelo do Helm define funções que você usa para transformar valores do arquivo values.yaml. A sintaxe para uma função segue a estrutura {{ functionName arg1 arg2 ... }}. Vamos examinar a função quote como um exemplo para ver essa sintaxe em uso.

A função quote encapsula um valor entre aspas para indicar o uso de um string. Digamos que você defina o seguinte arquivo values.yaml:

apiVersion: v2
name: webapp
description: A Helm chart for Kubernetes
ingress:
  enabled: true

Você decide que deseja usar o valor ingress.enabled como um booliano ao determinar se um manifesto de entrada deve ser gerado. Para usar o valor de enabled como um booliano, você faz referência ao valor usando {{ .Values.ingress.enabled }}.

Posteriormente, você decide exibir o campo como uma cadeia de caracteres no arquivo templates/Notes.txt. Como as regras de coerção de tipo YAML podem levar a uma dificuldade para encontrar bugs em modelos, você decidiu seguir as diretrizes e ser explícito ao incluir cadeias de caracteres nos modelos. Por exemplo, enabled: false não é igual a enabled: "false".

Para exibir o valor como uma cadeia de caracteres, você usa {{ quote .Values.ingress.enabled }} para fazer referência ao valor booliano como uma cadeia de caracteres.

Como usar pipelines em um modelo do Helm

Você usa pipelines quando mais de uma função precisa agir em um valor. Um pipeline permite enviar um valor ou o resultado de uma função para outra função. Por exemplo, você pode reescrever a função quote acima como {{ .Values.ingress.enabled | quote }}. Observe como o | indica que o valor é enviado à função quote.

Confira outro exemplo. Suponha que você queira converter um valor em letras maiúsculas e colocá-lo entre aspas. Você poderá escrever a instrução como {{ .Values.ingress.enabled | upper | quote }}. Observe como o valor é processado pela função upper e então pela função quote.

A linguagem do modelo inclui mais de 60 funções que permitem expor, pesquisar e transformar valores e objetos em modelos.

Como usar o controle de fluxo condicional em um modelo do Helm

O controle de fluxo condicional permite que você decida a estrutura ou os dados incluídos no arquivo de manifesto gerado. Por exemplo, o ideal é incluir valores diferentes com base no destino de implantação ou no controle se um arquivo de manifesto for gerado.

O bloco if / else é uma estrutura de fluxo de controle desse tipo e está em conformidade com o layout a seguir:

{{ if | pipeline | }}
  # Do something
{{ else if | other pipeline | }}
  # Do something else
{{ else }}
  # Default case
{{ end }}

Suponha que você decida que o arquivo de manifesto de entrada para um gráfico é criado somente em casos específicos. O exemplo a seguir mostra como fazer isso usando uma instrução if:

{{ if .Values.ingress.enabled }}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{ end }}

Lembre-se de que você pode usar espaços reservados para preencher metadados no modelo. Os arquivos de modelo são analisados e avaliados sequencialmente pela linguagem do modelo de cima para baixo. No exemplo anterior, o mecanismo de modelo só gera o conteúdo do arquivo de manifesto se o valor .Values.ingress.enabled for true.

Quando o mecanismo de modelo processa a instrução, ele remove o conteúdo declarado da sintaxe {{ }} e deixa o espaço em branco restante. Essa sintaxe faz com que o mecanismo de modelo inclua uma nova linha para a linha de instrução if. Se você deixar o conteúdo do arquivo anterior como está, observará linhas vazias no YAML e o arquivo de manifesto de entrada será gerado.

O YAML atribui significado ao espaço em branco. É por isso que as guias, os espaços e os caracteres de nova linha são considerados importantes. Para corrigir o problema de espaço em branco indesejado, você pode reescrever o arquivo da seguinte maneira:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{- end }}

Observe o uso do caractere - como parte do {{- inicial e a sequência -}} final da instrução. O caractere - instrui o analisador a remover caracteres de espaço em branco. {{- remove o espaço em branco no início de uma linha e -}} no final de uma linha, incluindo o caractere de linha nova.

Como iterar em uma coleção de valores em um modelo do Helm

O YAML permite que você defina coleções de itens e use itens individuais como valores em seus modelos. O acesso a itens em uma coleção é possível usando um indexador. No entanto, a linguagem do modelo do Helm dá suporte à iteração de uma coleção de valores usando o operador range.

Suponha que você defina uma lista de valores em seu arquivo values.yaml para indicar hosts de entrada adicionais. Veja um exemplo dos valores:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

Você usa o operador range para permitir que o mecanismo de modelo itere em .Values.ingress.extraHosts. O snippet de código a seguir mostra um exemplo condensado usando o operadorrange:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  ...
spec:
  rules:
    ...
    {{- range .Values.ingress.extraHosts }}
    - host: {{ .name }}
      http:
        paths:
          - path: {{ .path }}
            ...
    {{- end }}
  ...
{{- end }}

Como controlar o escopo de valores em um modelo do Helm

Quando você tiver valores definidos várias camadas de profundidade, a sintaxe poderá se tornar demorada e complicada quando esses valores forem incluídos em um modelo. A ação with permite limitar o escopo de variáveis em um modelo.

Lembre-se de que o . usado em um modelo do Helm referencia o escopo atual. Por exemplo, o .Values instrui o mecanismo de modelo a localizar o objeto Valores no escopo atual. Suponha que você esteja usando o arquivo values.yaml de antes para criar um arquivo de manifesto do mapa de configuração:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

Em vez de acessar o valor de caminho de cada item usando {{ .Values.ingress.extraHosts.path }}, você pode usar a ação with. O seguinte snippet de código mostra um exemplo de como usar o operador range para gerar um arquivo de manifesto do mapa de configuração:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  {{ end }}

O {{- with .Values.ingress.extraHosts }} limita o escopo dos valores para à matriz .Values.ingress.extraHosts.

A ação with restringe o escopo. Você não pode acessar outros objetos do escopo pai. Suponha que você também queira acessar o {{ .Release.Name }} do gráfico no bloco de código with. Para acessar objetos pai, você precisa indicar o escopo raiz usando o caractere $ ou reescrever seu código. Veja o código atualizado para mostrar como incluir objetos pai usando o caractere $:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  release: {{ $.Release.Name}}
  {{ end }}

Observação

Há várias construções disponíveis na linguagem do modelo do Helm para controlar o fluxo. A unidade de resumo do módulo inclui uma seção com links para a documentação do Helm para saber mais.

Como definir dependências de gráfico no Helm

Um gráfico permite a declaração de dependências para dar suporte ao aplicativo principal e a parte de formulários da versão instalada.

A diagram shows how Helm deploys all subcharts as dependencies of the main chart to a Kubernetes cluster.

Você pode criar um subgráfico usando o comando helm create, especificando o local do novo gráfico na pasta /charts ou usar o comando helm dependency. Lembre-se de que a pasta /charts pode conter subgráficos implantados como parte da versão do gráfico principal.

O comando helm dependency permite que você gerencie dependências incluídas de um repositório do Helm. O comando usa metadados definidos na seção dependencies do arquivo de valores do gráfico. Você especifica o nome, o número de versão e o repositório no qual instalar o subgráfico. Veja um extrato de um arquivo values.yaml que tem um gráfico do MongoDB listado como uma dependência:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes
...
dependencies:
  - name: mongodb
    version: 10.27.2
    repository: https://marketplace.azurecr.io/helm/v1/repo

Depois que os metadados de dependência são definidos, você executa o comando helm dependency build para buscar o gráfico empacotado do tar. O comando de build de gráfico baixa o gráfico para a pasta charts/.

helm dependency build ./app-chart

Os subgráficos são gerenciados separadamente do gráfico principal e podem precisar de atualizações à medida que novas versões são disponibilizadas. O comando para atualizar subgráficos é helm dependency update. Esse comando buscará novas versões do subgráfico ao excluir pacotes desatualizados.

helm dependency update ./app-chart

Lembre-se de que a dependência do gráfico não está limitada a outros aplicativos. Você pode optar por reutilizar a lógica do modelo nos gráficos e criar uma dependência especificamente para gerenciar essa lógica como uma dependência de gráfico. Você obterá um exemplo dessa estratégia no próximo exercício.

Como atualizar uma versão do Helm

O Helm permite a atualização de versões como um delta de todas as alterações que se aplicam ao gráfico e suas dependências.

A diagram shows how the Helm upgrade command creates a delta of all changed items in a Helm chart to upgrade a release and create a new release revision on a Kubernetes cluster.

Por exemplo, digamos que a equipe de desenvolvimento do exemplo webapp nessa unidade faça alterações de código que afetam apenas a funcionalidade do site. A equipe faz as seguintes atualizações no arquivo Chart.yaml para refletir a nova versão do aplicativo:

  • Primeiro, a equipe de desenvolvimento atualiza a imagem de contêiner do aplicativo Web e marca a imagem como webapp: linux-v2 ao enviá-la para o registro de contêiner.
  • Então a equipe atualiza o valor dockerTag para linux-v2 e o valor da versão gráfico para 0.2.0 no arquivo de valores do gráfico.

Aqui está um exemplo do arquivo atualizado values.yaml:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes

type: application

version: 0.2.0
appVersion: 1.0.0

registry: "my-acr-registry.azurecr.io"
dockerTag: "linux-v2"
pullPolicy: "Always"

Em vez de desinstalar a versão atual, você usará o comando helm upgrade para atualizar a versão do Helm.

helm upgrade my-app ./app-chart

O Helm gera um delta das alterações feitas no gráfico do Helm quando você atualiza uma versão. Com isso, uma atualização do Helm atualizará apenas os componentes identificados no delta. No exemplo, somente o site é reimplantado.

Quando a atualização for concluída, você poderá examinar o histórico de implantação da versão usando o comando helm history com o nome da versão.

helm history my-app

O comando histórico retorna vários campos que descrevem a versão, conforme mostrado na seguinte saída de exemplo:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        deployed        aspnet-core-1.3.18      3.1.19          Install complete

Observe o campo revision no resultado. O Helm acompanha as informações de versão de todas as versões feitas para um gráfico do Helm. Quando você instala uma nova versão de um gráfico do Helm, a contagem de revisões aumenta em um e as informações da novas versão correspondem à dessa revisão.

Veja um exemplo da mesma execução do comando history seguida da instalação de uma nova versão do aplicativo Web:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

Como reverter uma versão do Helm

O Helm permite a reversão de uma versão atual para uma versão instalada anteriormente. Lembre-se de que o Helm controla as informações de versão de todas as versões de um gráfico do Helm.

Use o comando helm rollback para reverter para uma revisão de versão específica do Helm. Esse comando usa dois parâmetros. O primeiro parâmetro identifica o nome da versão e o segundo identifica o número de revisão da versão.

helm rollback my-app 2

O comando helm rollback reverterá a versão de liberação do aplicativo para a revisão especificada e atualizará o histórico de liberações do aplicativo. Uma execução de acompanhamento do comando helm history mostrará o número de revisão ativa mais recente como a entrada de versão mais recente.

Por exemplo, digamos que a equipe de desenvolvimento do exemplo webapp nessa unidade descubra um bug no aplicativo Web de rastreamento de drones e precisa reverter para uma versão anterior. Em vez de desinstalar a versão atual e instalar uma versão anterior, você pode reverter para a versão que está funcionando.

helm rollback my-app 1

Quando a reversão for concluída, você poderá examinar o histórico de implantação usando o comando helm history.

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        superseded      aspnet-core-1.3.18      3.1.19          Rolled back to 1
3               Mon Oct 11 17:38:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

Observe como o campo Descrição mostra o número de revisão da reversão para facilitar o controle das alterações.

Verifique seu conhecimento

1.

Digamos que você tenha uma solução de software com dois componentes críticos: um aplicativo Web e um serviço que processa pedidos online. Os dois componentes fazem parte de um pipeline de processamento de pedido online, mas não dependem um do outro. Qual estratégia seria mais adequada para a implantação desses dois aplicativos usando o Helm?

2.

Digamos que você tenha uma solução de software que tenha um site como um de seus componentes críticos. O site é o único componente que depende de um serviço de cache. Qual estratégia seria mais adequada para a implantação desses dois aplicativos usando o Helm?