Le migliori pratiche per i pacchetti Helm

Helm è uno strumento di gestione pacchetti per Kubernetes che semplifica la gestione del ciclo di vita delle applicazioni. I pacchetti Helm sono denominati grafici e sono costituiti da file di configurazione e di modelli YAML. Al momento dell'esecuzione di un'operazione Helm, i grafici vengono visualizzati nei file manifesto Kubernetes per attivare le azioni appropriate del ciclo di vita dell'applicazione. Per l'integrazione più efficiente con Gestore del servizio di Microsoft Azure Operator, seguire queste procedure consigliate per lo sviluppo di grafici Helm.

Considerazioni su registryPath e imagePullSecrets

Ogni grafico Helm richiede in genere i parametri registryPath e imagePullSecrets. In genere, questi parametri vengono esposti nel file values.yaml. Inizialmente, Gestore del servizio di Microsoft Azure Operator dipendeva dagli editori che gestivano questi valori in modo rigoroso (approccio legacy), in modo da sostituire i valori di Azure appropriati durante la distribuzione. Tuttavia, non tutti gli editori possono essere facilmente conformarsi alla rigorosa gestione di questi valori. Alcuni grafici nascondono registryPath e/o imagePullSecrets dietro condizionali o altre restrizioni di valore, che non sono sempre state soddisfatte. Alcuni grafici dichiarano registryPath e/o imagePullSecrets come matrice anziché come stringa denominata prevista.

Per ridurre i requisiti di conformità per gli editori, Gestore del servizio di Microsoft Azure Operator ha introdotto due metodi migliorati: injectArtifactStoreDetail e il registro del cluster. Questi metodi più recenti non dipendono da registryPath né da imagePullSecrets, visualizzati nel pacchetto Helm. Questi metodi usano invece un webhook per inserire i valori di Azure appropriati direttamente nelle operazioni dei pod.

Riepilogo dei metodi per registryPath e imagePullSecrets

Tutti e tre i metodi sono attualmente supportati come descritto in questo articolo. Scegliere l'opzione migliore per la funzione di rete (NF) e il caso d'uso.

Eredità:

  • Richiede di parametrizzare registryPath e imagePullSecrets nei valori Helm e nei modelli di distribuzione per la sostituzione.
  • Ospita immagini in Registro Azure Container.

InjectArtifactStoreDetail:

  • Usa un webhook per inserire registryPath e imagePullSecrets direttamente nelle operazioni dei pod, con dipendenze minime da Helm.
  • Ospita immagini in Registro Azure Container.

Registro del cluster:

  • Usa un webhook per inserire registryPath e imagePullSecrets direttamente nelle operazioni dei pod, senza alcuna dipendenza da Helm.
  • Ospita immagini nell'estensione NFO (Network Function Operator) locale.

In tutti e tre i casi, Gestore del servizio di Microsoft Azure Operator sostituisce i valori di Azure per qualunque valore esposto nei modelli. L'unica differenza è il metodo di sostituzione.

Requisiti legacy per registryPath e imagePullSecrets

Gestore del servizio di Microsoft Azure Operator usa il servizio Gestione delle funzioni di rete di Azure per distribuire funzioni di rete in contenitori (CNF). Con il metodo legacy, Gestione delle funzioni di rete di Azure sostituisce i valori registryPath e imagePullSecrets del contenitore di Gestore del servizio di Microsoft Azure Operator nell'operazione Helm durante la distribuzione delle funzioni di rete.

Esempio del metodo legacy

Il modello di distribuzione Helm seguente illustra un esempio di come esporre 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 

Il modello values.yaml seguente illustra un esempio di come è possibile specificare i valori registryPath e imagePullSecrets:

global: 
   imagePullSecrets: [] 
   registryPath: "" 

Il file values.schema.json seguente illustra un esempio di come è possibile definire i valori registryPath 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" ], 
      } 
   } 
} 

Il payload della richiesta NFDV (Network Function Definition Version) seguente illustra un esempio di come è possibile specificare i valori registryPath e imagePullSecrets in fase di distribuzione:

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

Negli esempi precedenti:

  • Il valore registryPath viene impostato senza alcun prefisso, ad esempio https:// o oci://. Se necessario, definire un prefisso nel pacchetto Helm.
  • imagePullSecrets e registryPath devono essere specificati durante l'onboarding della NFDV.

Altre considerazioni

Quando si usa il metodo legacy, prendere in considerazione i suggerimenti seguenti.

Evitare riferimenti a un registro esterno

I riferimenti a un registro esterno possono causare problemi di convalida. Ad esempio, se deployment.yaml usa un percorso del registro hardcoded o riferimenti esterni al registro, la convalida si conclude con un errore.

Eseguire convalide manuali

Esaminare le immagini e le specifiche del contenitore per assicurarsi che le immagini abbiano un prefisso registryPath e che imagePullSecrets sia popolato con secretName:

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

Di seguito è riportato un altro esempio:

 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>

Usare un repository di immagini statiche e tag

Ogni grafico Helm deve contenere un repository di immagini statiche e tag. È possibile impostare i valori statici tramite uno dei metodi seguenti:

  • Nella riga image
  • In values.yaml, senza esporre questi valori nella NFDV

È necessario eseguire il mapping della NFDV a un set statico di grafici e immagini Helm. È possibile aggiornare i grafici e le immagini solo pubblicando una nuova NFDV, come illustrato negli esempi seguenti:

 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}}

Requisiti di injectArtifactStoreDetails per registryPath e imagePullSecrets

In alcuni casi, i grafici Helm di terze parti potrebbero non essere completamente conformi ai requisiti di Gestore del servizio di Microsoft Azure Operator per registryPath. In questi casi, è possibile usare injectArtifactStoreDetails per evitare di apportare modifiche alla conformità ai pacchetti Helm.

Quando injectArtifactStoreDetails è abilitato, viene usato un metodo webhook per inserire il codice registryPath e imagePullSecrets dinamico appropriato durante le operazioni del pod. Questo metodo esegue l'override dei valori configurati nel pacchetto Helm. È comunque necessario usare valori fittizi legali che fanno riferimento a registryPath e imagePullSecrets, in genere nella sezione global di values.yaml.

L'esempio values.yaml seguente illustra come specificare i valori registryPath e imagePullSecrets per la compatibilità con l'approccio injectArtifactStoreDetails:

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

Note

Se registryPath viene lasciato vuoto nel pacchetto Helm sottostante, la distribuzione del servizio di rete del sito (SNS) si conclude con un errore durante il download dell'immagine.

Usare il metodo injectArtifactStoreDetails

Per abilitare injectArtifactStoreDetails, impostare il parametro installOptions nella sezione roleOverrides della risorsa NF su true, come illustrato nell'esempio seguente:

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"}}}}}'
    ]
  }
}

Note

Il pacchetto del grafico Helm deve comunque esporre i valori registryPath e imagePullSecrets formattati correttamente.

Requisiti del registro del cluster per registryPath e imagePullSecrets

Con un registro del cluster, le immagini vengono copiate da Registro Azure Container in un repository Docker locale nel cluster Nexus Kubernetes. Si usa un metodo webhook per inserire in modo dinamico i valori registryPath e imagePullSecrets appropriati durante le operazioni del pod. Questo metodo esegue l'override dei valori configurati nel pacchetto Helm. È comunque necessario usare valori fittizi legali che fanno riferimento a registryPath e imagePullSecrets, in genere nella sezione global di values.yaml.

L'esempio values.yaml seguente spiega come specificare i valori registryPath e imagePullSecrets per la compatibilità con l'approccio del registro del cluster:

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

Note

Se registryPath viene lasciato vuoto nel pacchetto Helm sottostante, la distribuzione SNS si conclude durante il download dell'immagine.

Per altre informazioni sull'uso di un registro del cluster, vedere la documentazione sul concetto.

Consigli per le restrizioni di immutabilità

Le restrizioni di immutabilità impediscono modifiche a un file o a una directory. Ad esempio, non è possibile modificare o rinominare un file non modificabile. È consigliabile evitare di usare tag modificabili, ad esempio latest, dev o stable. Ad esempio, se deployment.yaml usa latest per .Values.image.tag, la distribuzione si conclude con errore.

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

Consigli per la dichiarazione CRD e la suddivisione dell'utilizzo

È consigliabile suddividere la dichiarazione e l'utilizzo delle definizioni delle risorse dei clienti (CRD) in grafici Helm separati per supportare gli aggiornamenti. Per informazioni dettagliate, vedere la documentazione Helm sulla separazione dei grafici.

Consigli per l'assegnazione di tag alla versione dell'immagine

Per garantire distribuzioni coerenti e prevedibili, è consigliabile seguire questa procedura per tutte le immagini del contenitore:

  • Evitare di usare :latest negli ambienti di produzione.
    • L'uso della versione più recente può causare un comportamento imprevisto perché l'immagine effettiva dietro la versione più recente può cambiare senza preavviso.
    • In un'installazione del registro del cluster, se il valore del tag cambia ma il nome del tag rimane invariato, il registro del cluster non scaricherà nuovamente l'immagine aggiornata.
    • Ciò può causare l'esecuzione di immagini obsolete o incoerenti.
  • Usare invece sempre tag non modificabili come :1.4.2
  • Assicurarsi che ogni compilazione produca un tag univoco, non sovrascrivere i tag esistenti.

Queste procedure consentono di prevenire i problemi di distribuzione e migliorare la tracciabilità, la sicurezza del ripristino dello stato precedente e la conformità alla sicurezza.

Raccomandazioni per l'ordinamento sequenziale di nfApplication

Per impostazione predefinita, le applicazioni CNF vengono installate o aggiornate in base all'ordine in cui vengono visualizzate nella NFDV. Per l'operazione di eliminazione, le applicazioni CNF vengono eliminate nell'ordine inverso specificato. Se è necessario definire un ordine specifico di applicazioni CNF diverse dall'impostazione predefinita, usare dependsOnProfile per definire una sequenza univoca per le operazioni di installazione, aggiornamento ed eliminazione.

Come usare dependsOnProfile

È possibile usare dependsOnProfile in NFDV per controllare la sequenza di esecuzioni Helm per le applicazioni CNF. Nell'esempio seguente:

  • Durante un'operazione di installazione, le applicazioni CNF vengono distribuite nell'ordine seguente: dummyApplication1, dummyApplication2, dummyApplication.
  • Durante un'operazione di aggiornamento, le applicazioni CNF vengono aggiornate nell'ordine seguente: dummyApplication2, dummyApplication1, dummyApplication.
  • Durante un'operazione di eliminazione, le applicazioni CNF vengono eliminate nell'ordine seguente: 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"
    }
}

Errori comuni con dependsOnProfile

Attualmente, se il dependsOnProfile codice fornito nella funzione NFDV non è valido, l'operazione NF ha esito negativo con un errore di convalida. Il messaggio per l'errore di convalida viene visualizzato nella risorsa di stato dell'operazione e ha un aspetto simile all'esempio seguente:

 {
  "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."
  }
}

Procedure consigliate per l'adozione di Helm 4

Helm è stato lo standard package manager per Kubernetes dalla versione iniziale nel 2016. La sua evoluzione ha seguito da vicino quella di Kubernetes stesso:

  • Helm v2 (2016–2019): ha introdotto la pacchettizzazione delle applicazioni basata su chart, ma si basava su un componente lato server (Tiller), che sollevava problemi di sicurezza e multi-tenant.
  • Helm v3 (2019-2025): Rimosso Tiller, passando a un modello solo client con maggiore sicurezza e usabilità. Questa versione è diventata lo standard del settore e ha accumulato miglioramenti incrementali, mantenendo al tempo stesso la retrocompatibilità.

Dopo quasi sei anni di Helm v3, il progetto accumulava il debito tecnico, le limitazioni dell'architettura e le sfide di sicurezza che non poteva affrontare senza introdurre modifiche di rilievo. Questa situazione ha portato al rilascio di Helm v4 alla fine del 2025.

Cosa rappresenta Helm 4

Helm 4 è un'evoluzione architetturale significativa anziché un aggiornamento incrementale. I suoi obiettivi principali sono:

  • Allinearsi ai modelli di distribuzione kubernetes moderni
  • Rimuovere i comportamenti precedenti di Helm v3
  • Migliorare l'estendibilità, la gestibilità e la sicurezza

Le modifiche chiave introdotte con Helm 4 includono:

  • Server-Side Apply (SSA): sostituisce l'approccio di merge a tre vie legacy e allinea le distribuzioni con la semantica di riconciliazione nativa di Kubernetes.
  • Sistema di plug-in riprogettata: introduce un'architettura più estendibile, inclusi i plug-in basati su WebAssembly facoltativi per migliorare l'isolamento e la flessibilità.
  • Miglioramento del rilevamento delle risorse: sfrutta i meccanismi di stato di Kubernetes più recenti, ad esempio kstatus, per fornire report sullo stato di distribuzione più accurati.
  • Modernizzazione interna: rimuove il debito tecnico e pone le basi per i futuri miglioramenti all'innovazione e alle prestazioni.

Importante, Helm 4 mantiene la compatibilità con i grafici Helm v3 esistenti, consentendo alle organizzazioni di adottare Gradualmente Helm 4 senza richiedere modifiche immediate ai grafici o agli artefatti di distribuzione.

Rilevanza per gli editori AOSM

Il team di AOSM prevede di supportare Helm 4 tramite due attività cardine principali:

  • Prima di tutto, il team di AOSM rilascia una versione NFO che include Helm 4.1.4 che opera in una "modalità di compatibilità". Questa modalità mantiene il comportamento di Helm 3.18, in modo che gli editori possano adottare Helm 4 senza modificare grafici o artefatti esistenti.
    • È possibile visualizzare in anteprima questa versione NFO oggi nel lab UKSouth.
  • In secondo luogo, il team di AOSM rilascia una versione NFO che rimuove le personalizzazioni di compatibilità e abilita il comportamento completo di Helm 4. Gli editori possono adottare questa versione quando sono pronti, tenendo presente che potrebbero essere necessarie modifiche ai grafici e agli artefatti.
    • Il team AOSM prevede questa versione di NFO per i test da parte del publisher nel 4º trimestre dell'anno solare 2026.

Gli editori continuano ad avere flessibilità nella selezione del comportamento di Helm durante l'installazione di NFO. Per impostazione predefinita, NFO è in "modalità di compatibilità", pur offrendo un'opzione di installazione per abilitare il comportamento completo di Helm 4. Questa funzionalità è con ambito cluster, ovvero tutte le distribuzioni all'interno di un cluster devono usare la stessa modalità operativa Helm.

Dettagli della modalità di compatibilità

Le impostazioni seguenti mantengono il comportamento di Helm 3 durante l'esecuzione di Helm 4 in "modalità compatibilità":

  • Convalida dello schema più restrittiva
    • Helm 4 introduce una convalida più rigorosa che rifiuta le sezioni tipate go, ad esempio []map[string]interface{}, durante la convalida delle matrici JSON. Questo comportamento può causare errori quando NFO inserisce i valori imagePullSecrets.
    • NFO aggiorna la logica di iniezione dei valori per utilizzare invece []interface{} e verifica percorsi di codice simili per garantire la compatibilità.
  • Server-Side Apply (SSA) abilitata per impostazione predefinita
    • Helm 4 convalida i manifesti di cui è stato eseguito il rendering sullo schema OpenAPI del cluster prima di applicare le risorse. I grafici contenenti definizioni di campo non valide tollerate in precedenza da Helm 3 potrebbero non riuscire a convalidare.
    • La modalità di compatibilità disabilita SSA durante le operazioni di installazione e aggiornamento per mantenere il comportamento di Helm 3.
  • Nuovo modello di attesa
    • Helm 4 usa per impostazione predefinita un modello di attesa basato su eventi che richiede autorizzazioni di controllo di Kubernetes. Questo comportamento può non riuscire sui cluster Nexus in cui le autorizzazioni RBAC necessarie non sono disponibili.
    • La modalità di compatibilità vincola il comportamento di attesa a LegacyStrategy, preservando la semantica di polling di Helm 3.
  • Ricreazione rimossa
    • Helm 4 rimuove il supporto per Upgrade.Recreate. Sebbene l'impatto di runtime sia basso, i valori configurati dal cliente nel CRD non avranno più alcun effetto.
    • La modalità di compatibilità mantiene il campo CRD per la compatibilità con le versioni precedenti, ma lo ignora durante l'esecuzione di operazioni Helm 4.
  • Validazione dello schema rispetto al metaschema
    • Helm 4 convalida values.schema.json rispetto al metaschema dello schema JSON. I grafici contenenti definizioni di schema non conformi vengono rifiutati prima che si verifichi la convalida dei valori. È noto che questo comportamento può influire su alcuni grafici di pubblicazione.
    • La modalità di compatibilità imposta SkipSchemaValidation=true durante le operazioni di installazione e aggiornamento.