Melhores práticas do pacote Helm

O Helm é um gerenciador de pacotes para o Kubernetes que ajuda a simplificar o gerenciamento do ciclo de vida do aplicativo. Os pacotes Helm são chamados charts e consistem em ficheiros de configuração YAML e de modelos. Após a execução de uma operação Helm, os gráficos são renderizados em arquivos de manifesto do Kubernetes para acionar as ações apropriadas do ciclo de vida do aplicativo. Para obter a integração mais eficiente com o Gerente de serviço do operador do Microsoft Azure, siga estas práticas recomendadas ao desenvolver gráficos Helm.

Considerações para registryPath e imagePullSecrets

Cada gráfico Helm geralmente requer registryPath e imagePullSecrets parâmetros. Mais comumente, você expõe esses parâmetros no values.yaml arquivo. No início, o Gerente de serviço do operador do Microsoft Azure dependia de os publicadores gerirem estes valores de forma rigorosa (abordagem legada), para que fossem substituídos pelos valores adequados do Azure durante a implementação. Mas nem todas as editoras poderiam facilmente cumprir com a gestão rigorosa desses valores. Alguns gráficos escondem registryPath e/ou imagePullSecrets atrás de condicionais, ou outras restrições de valor, que nem sempre foram atendidas. Alguns gráficos declaram registryPath e/ou imagePullSecrets como um array em vez de uma cadeia com nome, como era esperado.

Para reduzir os requisitos de conformidade nos editores, o Gerente de serviço do operador do Microsoft Azure introduziu dois métodos aprimorados: injectArtifactStoreDetail e o registro de cluster. Estes métodos mais recentes não dependem de registryPath nem de imagePullSecrets aparecerem no pacote Helm. Em vez disso, estes métodos utilizam um webhook para inserir diretamente valores apropriados do Azure nas operações dos pods.

Resumo do método para registryPath e imagePullSecrets

Todos os três métodos são atualmente suportados conforme descrito neste artigo. Escolha a melhor opção para a sua função de rede (NF) e caso de uso.

Legado:

  • Exige a parametrização de registryPath e imagePullSecrets nos valores do Helm e nos modelos de implementação para substituição de valores.
  • Hospeda imagens no Registro de Contêiner do Azure.

InjectArtifactStoreDetail:

  • Utiliza um webhook para injetar registryPath e imagePullSecrets diretamente nas operações no pod, com dependência mínima do Helm.
  • Hospeda imagens no Registro de Contêiner do Azure.

Registo do cluster:

  • Usa um webhook para injetar registryPath e imagePullSecrets diretamente nas operações do pod, sem depender do Helm.
  • Hospeda imagens na extensão NFO (operador de função de rede) local.

Em todos os três casos, o Gerente de serviço do operador do Microsoft Azure substitui os valores do Azure por quaisquer valores que você exponha nos modelos. A única diferença é o método de substituição.

Requisitos herdados para registryPath e imagePullSecrets

O Gerente de serviço do operador do Microsoft Azure usa o serviço Gerenciador de Funções de Rede do Azure para implantar CNFs (funções de rede conteinerizadas). Com o método legado, o Gestor de Funções de Rede do Azure substitui os valores registryPath e imagePullSecrets do contentor do Gerente de serviço do operador do Microsoft Azure na operação Helm durante a implementação das funções de rede.

Exemplo do método herdado

O modelo de implantação do Helm a seguir mostra um exemplo de como você deve expor registryPath e imagePullSecrets:

apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: nginx-deployment 
  labels: 
    app: nginx 
spec: 
  replicas: 3 
  selector: 
    matchLabels: 
      app: nginx 
  template: 
    metadata: 
      labels: 
        app: nginx 
    spec: 
      {{- if .Values.global.imagePullSecrets }} 
      imagePullSecrets: {{ toYaml .Values.global.imagePullSecrets | nindent 8 }} 
      {{- end }} 
      containers: 
      - name: contosoapp 
        image:{{ .Values.global.registryPath }}/contosoapp:1.14.2 
        ports: 
        - containerPort: 80 

O modelo a seguir values.yaml mostra um exemplo de como você pode fornecer os registryPath valores e imagePullSecrets :

global: 
   imagePullSecrets: [] 
   registryPath: "" 

O arquivo a seguir values.schema.json mostra um exemplo de como você pode definir os registryPath valores e imagePullSecrets :

{ 
  "$schema": "http://json-schema.org/draft-07/schema#", 
  "title": "StarterSchema", 
  "type": "object", 
  "required": ["global"], 
  "properties": { 
      "global" : {
          "type": "object",
          "properties": {
              "registryPath": {"type": "string"}, 
              "imagePullSecrets": {"type": "string"}, 
          }
          "required": [ "registryPath", "imagePullSecrets" ], 
      } 
   } 
} 

A seguinte carga útil do pedido de versão da definição de função de rede (NFDV) mostra um exemplo de como pode fornecer os valores registryPath e imagePullSecrets na implementação:

"registryValuesPaths": [ "global.registryPath" ], 
"imagePullSecretsValuesPaths": [ "global.imagePullSecrets" ], 

Nos exemplos anteriores:

  • O registryPath valor é definido sem qualquer prefixo, como https:// ou oci://. Se necessário, defina um prefixo no pacote Helm.
  • imagePullSecrets e registryPath devem ser fornecidos durante o processo de onboarding do NFDV.

Outras considerações

Considere as recomendações a seguir ao usar o método herdado.

Evitar referências a um registo externo

As referências a um registo externo podem causar problemas de validação. Por exemplo, se deployment.yaml usar um caminho de registro codificado ou referências de registro externas, ele falhará na validação.

Executar validações manuais

Verifique as imagens e as especificações do contentor para garantir que as imagens têm o prefixo registryPath e que imagePullSecrets é preenchido com secretName:

 helm template --set "global.imagePullSecrets[0].name=<secretName>" --set "global.registry.url=<registryPath>" <release-name> <chart-name> --dry-run

Eis outro exemplo:

 helm install --set "global.imagePullSecrets[0].name=<secretName>" --set "global.registry.url=<registryPath>" <release-name> <chart-name> --dry-run
 kubectl create secret <secretName> regcred --docker-server=<registryPath> --dockerusername=<regusername> --docker-password=<regpassword>

Usar um repositório de imagens estáticas e tags

Cada gráfico Helm deve conter um repositório de imagens estáticas e tags. Você define os valores estáticos por meio de um dos seguintes métodos:

  • Na image linha
  • Em values.yaml, sem expor estes valores no NFDV

Um NFDV deve ser mapeado para um conjunto estático de gráficos e imagens do Helm. Você atualiza os gráficos e imagens somente publicando um novo NFDV, conforme mostrado nos exemplos a seguir:

 image: "{{ .Values.global.registryPath }}/contosoapp:1.14.2"
 image: "{{ .Values.global.registryPath }}/{{ .Values.image.repository }}:{{ .Values.image.tag}}"
 
YAML values.yaml
image:
  repository: contosoapp
  tag: 1.14.2
 image: http://myUrl/{{ .Values.image.repository }}:{{ .Values.image.tag}}

injectArtifactStoreRequisitos de detalhes para registryPath e imagePullSecrets

Em alguns casos, os gráficos Helm de terceiros podem não ser totalmente compatíveis com os requisitos do Gerente de serviço do operador do Microsoft Azure para registryPath. Nesses casos, você pode usar injectArtifactStoreDetails para evitar fazer alterações de conformidade nos pacotes Helm.

Com injectArtifactStoreDetails ativado, você usa um método webhook para injetar o adequado registryPath e imagePullSecrets dinamicamente durante as operações do pod. Esse método substitui os valores configurados no pacote Helm. Continua a ser necessário usar valores fictícios legalmente válidos onde registryPath e imagePullSecrets são referenciados, geralmente na secção global de values.yaml.

O exemplo seguinte values.yaml mostra como pode fornecer os valores registryPath e imagePullSecrets para compatibilidade com a abordagem injectArtifactStoreDetails:

global: 
   registryPath: "azure.io"
   imagePullSecrets: ["abc123"] 

Nota

Se registryPath for deixado em branco no pacote Helm subjacente, a implantação do serviço de rede do site (SNS) falhará durante o download da imagem.

Usando o método injectArtifactStoreDetails

Para habilitar injectArtifactStoreDetails, defina o parâmetro installOptions na secção roleOverrides do recurso NF como true, conforme mostrado no exemplo seguinte:

resource networkFunction 'Microsoft.HybridNetwork/networkFunctions@2023-09-01' = {
  name: nfName
  location: location
  properties: {
    nfviType: 'AzureArcKubernetes'
    networkFunctionDefinitionVersionResourceReference: {
      id: nfdvId
      idType: 'Open'
    }
    allowSoftwareUpdate: true
    nfviId: nfviId
    deploymentValues: deploymentValues
    configurationType: 'Open'
    roleOverrideValues: [
      // Use inject artifact store details feature on test app 1
      '{"name":"testapp1", "deployParametersMappingRuleProfile":{"helmMappingRuleProfile":{"options":{"installOptions":{"atomic":"false","wait":"false","timeout":"60","injectArtifactStoreDetails":"true"},"upgradeOptions": {"atomic": "false", "wait": "true", "timeout": "100", "injectArtifactStoreDetails": "true"}}}}}'
    ]
  }
}

Nota

O pacote do chart do Helm deve continuar a expor os valores registryPath e imagePullSecrets devidamente formatados.

Requisitos do registo de cluster para "registryPath" e "imagePullSecrets"

Com um registro de cluster, as imagens são copiadas do Registro de Contêiner do Azure para um repositório Docker local no cluster Nexus Kubernetes. Utiliza um método de webhook para injetar dinamicamente os valores registryPath e imagePullSecrets adequados durante as operações do pod. Esse método substitui os valores configurados no pacote Helm. Continua a ser necessário usar valores fictícios legalmente válidos onde registryPath e imagePullSecrets são referenciados, geralmente na secção global de values.yaml.

O exemplo seguinte values.yaml mostra como pode fornecer os valores registryPath e imagePullSecrets para ser compatível com a abordagem de registo de clusters:

global: 
   registryPath: "azure.io"
   imagePullSecrets: ["abc123"] 

Nota

Se registryPath for deixado vazio no pacote Helm subjacente, a implementação do SNS falha durante a transferência da imagem.

Para obter mais informações sobre como usar um registro de cluster, consulte a documentação do conceito.

Recomendações para restrições de imutabilidade

As restrições de imutabilidade impedem alterações em um arquivo ou diretório. Por exemplo, um arquivo imutável não pode ser alterado ou renomeado. Você deve evitar o uso de tags mutáveis, como latest, devou stable. Por exemplo, se deployment.yaml usar latest para .Values.image.tag, a implantação falhará.

 image: "{{ .Values.global.registryPath }}/{{ .Values.image.repository }}:{{ .Values.image.tag}}"

Recomendações para declaração CRD e divisão de uso

Recomendamos dividir a declaração e o uso das definições de recursos do cliente (CRDs) em gráficos Helm separados para oferecer suporte a atualizações. Para obter informações detalhadas, consulte a documentação do Helm sobre a separação de gráficos.

Recomendações para marcação de versão de imagem

Para garantir implantações consistentes e previsíveis, recomendamos o seguinte para todas as imagens de contêiner:

  • Evite usar :latest em ambientes de produção.
    • Utilizar a tag latest pode causar comportamentos inesperados, porque a imagem efetiva associada à tag latest pode mudar sem aviso prévio.
    • Em uma configuração de registro de cluster, se o valor da tag for alterado, mas o nome da tag permanecer o mesmo, o registro de cluster não baixará novamente a imagem atualizada.
    • Isso pode levar à execução de imagens desatualizadas ou inconsistentes.
  • Em vez disso, usa sempre etiquetas imutáveis como :1.4.2
  • Certifique-se de que cada compilação produza uma tag exclusiva, não substitua tags existentes.

Essas práticas ajudam a evitar problemas de implantação e melhoram a rastreabilidade, a segurança de reversão e a conformidade de segurança.

Recomendações para a ordenação sequencial da aplicação nfApplication.

Por padrão, os aplicativos CNF são instalados ou atualizados com base na ordem em que aparecem no NFDV. Para a operação de exclusão, os aplicativos CNF são excluídos na ordem inversa especificada. Se você precisar definir uma ordem específica de aplicativos CNF diferente do padrão, use dependsOnProfile para definir uma sequência exclusiva para operações de instalação, atualização e exclusão.

Como usar dependsOnProfile

Você pode usar dependsOnProfile no NFDV para controlar a sequência de execuções do Helm para aplicações CNF. No exemplo que se segue:

  • Durante uma operação de instalação, os aplicativos CNF são implantados na seguinte ordem: dummyApplication1, dummyApplication2, dummyApplication.
  • Durante uma operação de atualização, as aplicações CNF são atualizadas pela seguinte ordem: dummyApplication2, dummyApplication1, dummyApplication.
  • Durante uma operação de eliminação, os pedidos CNF são eliminados pela seguinte ordem: dummyApplication2, dummyApplication1, dummyApplication.
{
    "location": "eastus",
    "properties": {
        "networkFunctionTemplate": {
            "networkFunctionApplications": [
                {
                  "dependsOnProfile": {
                        "installDependsOn": [
                            "dummyApplication1",
                            "dummyApplication2"
                        ],
                        "uninstallDependsOn": [
                            "dummyApplication1"
                        ],
                        "updateDependsOn": [
                            "dummyApplication1"
                        ]
                    },
                    "name": "dummyApplication"
                },
                {
                  "dependsOnProfile": {
                        "installDependsOn": [
                        ],
                        "uninstallDependsOn": [
                            "dummyApplication2"
                        ],
                        "updateDependsOn": [
                            "dummyApplication2"
                        ]
                    },
                    "name": "dummyApplication1"
                },
                {
                    "dependsOnProfile": null,
                    "name": "dummyApplication2"
                }
            ],
            "nfviType": "AzureArcKubernetes"
        },
        "networkFunctionType": "ContainerizedNetworkFunction"
    }
}

Erros comuns com dependsOnProfile

Atualmente, se o dependsOnProfile código fornecido no NFDV for inválido, a operação NF falhará com um erro de validação. A mensagem para o erro de validação aparece no recurso de status da operação e é semelhante ao exemplo a seguir:

 {
  "id": "/providers/Microsoft.HybridNetwork/locations/EASTUS2EUAP/operationStatuses/ca051ddf-c8bc-4cb2-945c-a292bf7b654b*C9B39996CFCD97AB3A121AE136ED47F67BB13946C573EF90628C47628BC5EF5F",
  "name": "ca051ddf-c8bc-4cb2-945c-a292bf7b654b*C9B39996CFCD97AB3A121AE136ED47F67BB13946C573EF90628C47628BC5EF5F",
  "resourceId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/xinrui-publisher/providers/Microsoft.HybridNetwork/networkfunctions/testnfDependsOn02",
  "status": "Failed",
  "startTime": "2023-07-17T20:48:01.4792943Z",
  "endTime": "2023-07-17T20:48:10.0191285Z",
  "error": {
    "code": "DependenciesValidationFailed",
    "message": "CyclicDependencies: Circular dependencies detected at hellotest."
  }
}

Melhores práticas para adotar o Helm 4

O Helm tem sido o gestor de pacotes padrão do Kubernetes desde o seu lançamento inicial em 2016. A sua evolução acompanhou de perto o próprio Kubernetes:

  • Helm v2 (2016–2019): Introduziu o empacotamento de aplicações baseado em gráficos, mas dependia de um componente do lado do servidor (Tiller), o que criou preocupações de segurança e multitenência.
  • Helm v3 (2019–2025): Remoção do Tiller, passando para um modelo apenas cliente com melhor segurança e usabilidade. Esta versão tornou-se o padrão da indústria e acumulou melhorias incrementais mantendo a compatibilidade retroativa.

Após quase seis anos com o Helm v3, o projeto acumulou dívida técnica, limitações arquitetónicas e desafios de segurança que não conseguiu resolver sem introduzir alterações significativas. Esta situação levou ao lançamento do Helm v4 no final de 2025.

O que Helm 4 Representa

Helm 4 é uma evolução arquitetónica significativa em vez de uma atualização incremental. Os seus principais objetivos são:

  • Alinhar com os padrões modernos de implementação do Kubernetes
  • Remover comportamentos legados do Helm v3
  • Melhorar a extensibilidade, a manutenibilidade e a segurança

As principais alterações introduzidas com o Helm 4 incluem:

  • Server-Side Apply (SSA): Substitui a abordagem legada de fusão tripla e alinha as implementações com a semântica nativa de reconciliação do Kubernetes.
  • Sistema de plugins redesenhado: Introduz uma arquitetura mais extensível, incluindo plugins opcionais baseados em WebAssembly para maior isolamento e flexibilidade.
  • Melhor rastreamento de recursos: Aproveita mecanismos de estado mais recentes do Kubernetes, como o kstatus, para fornecer relatórios de estado de implementação mais precisos.
  • Modernização interna: Elimina a dívida técnica e lança as bases para futuras inovações e melhorias de desempenho.

Importa referir que o Helm 4 mantém a compatibilidade com os gráficos existentes do Helm v3, permitindo que as organizações adotem o Helm 4 gradualmente sem necessidade de alterações imediatas aos mapas ou artefactos de implantação.

Relevância para as editoras AOSM

A equipa da AOSM planeia apoiar a Helm 4 através de dois marcos principais:

  • Primeiro, a equipa da AOSM lança uma versão NFO que inclui o Helm 4.1.4 a operar num "modo de compatibilidade". Este modo preserva o comportamento do Helm 3.18, permitindo que os editores adotem o Helm 4 sem modificar gráficos ou artefactos existentes.
    • Pode hoje testar esta versão NFO em versão de pré-visualização no laboratório UKSouth.
  • Em segundo lugar, a equipa da AOSM lança uma versão NFO que remove as personalizações de compatibilidade e permite o comportamento completo do Helm 4. Os editores podem adotar esta versão quando estiverem prontos, sabendo que podem ser necessárias alterações no gráfico e nos artefactos.
    • A equipa da AOSM planeia esta versão NFO para testes por editores no quarto trimestre do ano fiscal de 2026.

Os editores continuam a ter flexibilidade ao selecionar o comportamento do Helm durante a instalação do NFO. O NFO utiliza por predefinição o "modo de compatibilidade", disponibilizando uma opção de instalação para ativar o comportamento completo do Helm 4. Esta capacidade aplica-se ao nível do cluster, o que significa que todas as implementações dentro de um cluster têm de utilizar o mesmo modo de funcionamento do Helm.

Detalhes do modo de compatibilidade

As seguintes definições preservam o comportamento do Helm 3 ao executar o Helm 4 em "modo de compatibilidade":

  • Validação de esquemas mais rigorosa
    • O Helm 4 introduz uma validação mais rigorosa que rejeita fatias tipo Go, como a interface{} []map[string], ao validar arrays JSON. Este comportamento pode causar falhas quando o NFO injeta valores imagePullSecrets.
    • O NFO atualiza a lógica de injeção de valor para usar a interface{} []em vez disso e audita caminhos de código semelhantes para garantir compatibilidade.
  • Aplicação do lado do servidor (SSA) ativada por predefinição
    • O Helm 4 valida os manifestos renderizados contra o esquema OpenAPI do cluster antes de aplicar recursos. Gráficos contendo definições de campo inválidas que o Helm 3 tolerava anteriormente podem falhar na validação.
    • O modo de compatibilidade desativa o SSA durante as operações de instalação e atualização para preservar o comportamento do Helm 3.
  • Novo modelo de espera
    • O Helm 4 adota por defeito um modelo de espera orientado a eventos que requer permissões de visualização do Kubernetes. Este comportamento pode falhar em clusters Nexus onde as permissões RBAC necessárias não estão disponíveis.
    • O modo de compatibilidade fixa o comportamento de espera em LegacyStrategy, preservando a semântica de sondagem do Helm 3.
  • Recriação removida
    • O Helm 4 deixa de suportar Upgrade.Recreate. Embora se espere que o impacto em tempo de execução seja baixo, os valores configurados pelo cliente no CRD deixariam de ter qualquer efeito.
    • O modo de compatibilidade preserva o campo CRD para retrocompatibilidade, mas ignora-o ao executar operações Helm 4.
  • Validação do metaesquema do esquema
    • O Helm 4 valida o values.schema.json em conformidade com o metaesquema do JSON Schema. Os gráficos contendo definições de esquemas não conformes são rejeitados antes de ocorrer a validação dos valores. Sabe-se que este comportamento afeta algumas tabelas de editoras.
    • O modo de compatibilidade define SkipSchemaValidation=true durante as operações de instalação e atualização.