Helm パッケージのベスト プラクティス

Helm は、アプリケーション ライフサイクル管理を簡素化するのに役立つ Kubernetes のパッケージ マネージャーです。 Helm のパッケージはチャートと呼ばれ、YAML 構成ファイルとテンプレート ファイルから構成されています。 このチャートは、Helm 操作の実行時に Kubernetes マニフェスト ファイルにレンダリングされ、適切なアプリケーション ライフサイクル アクションがトリガーされます。 Azure Operator Service Manager と最も効率的に統合するには、Helm チャートを開発するときに推奨されるベスト プラクティスに従ってください。

registryPath と imagePullSecrets に関する考慮事項

一般に、すべての Helm チャートには registryPath パラメーターと imagePullSecrets パラメーターが必要です。 最も一般的には、 values.yaml ファイル内でこれらのパラメーターを公開します。 最初は、これらの値を厳密な方法 (レガシ アプローチ) で管理する発行元に依存する Azure Operator Service Manager が、デプロイ時に適切な Azure 値に置き換えられます。 ただし、これらの値の厳密な管理に準拠することは、すべての発行元にとって簡単なわけではありません。 一部のチャートでは、条件によって、registryPath や imagePullSecrets、または常に適合するわけではない他の値の制限が隠蔽されます。 一部のグラフでは、registryPath や imagePullSecrets を、想定される名前付き文字列としてではなく配列として宣言します。

発行元におけるコンプライアンス要件を減らすために、Azure Operator Service Manager では、 injectArtifactStoreDetail とクラスター レジストリという 2 つの改善された方法が導入されています。 これらの新しい方法は、Helm パッケージの中に含まれる registryPath や imagePullSecrets には依存しません。 代わりに、これらのメソッドは webhook を使用して、適切な Azure 値をポッド操作に直接挿入します。

registryPath と imagePullSecrets のメソッドのサマリー

現在、以下に説明されている通りに、3 つの方法がサポートされています。 ネットワーク機能 (NF) とユース ケースに最適なオプションを選択してください。

レガシ:

  • 置き換えのために、Helm 値とデプロイ テンプレート内で、registryPath と imagePullSecrets のパラメーター化を要求します。
  • Azure Container Registry のイメージをホストします。

InjectArtifactStoreDetail:

  • Webhook を使用して、Helm への依存関係を最小限にしつつ、registryPath と imagePullSecrets をポッド操作に直接挿入します。
  • Azure Container Registry のイメージをホストします。

クラスター レジストリ:

  • Webhook を使用して、Helm に依存せず、registryPath と imagePullSecrets をポッド操作に直接挿入します。
  • ローカル ネットワーク機能オペレーター (NFO) 拡張機能内で、イメージをホストします。

3 つのケースすべてにおいて、Azure Operator Service Manager は、Azure 値をテンプレートで公開される値に置き換えます。 異なっているのは、その置換方法だけです。

registryPath と imagePullSecrets 向けのレガシ要件

Azure Operator Service Manager では、Azure Network Function Manager サービスを使用して、コンテナー化されたネットワーク機能 (CNF) をデプロイします。 レガシの方法では、Azure Network Function Manager はネットワーク機能のデプロイ中に、Azure Operator Service Manager コンテナーの registryPath と imagePullSecrets 値を Helm 操作内で置換します。

レガシ メソッドの例

次の Helm 展開テンプレートでは、registryPath と 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 

次の values.yaml テンプレートは、 registryPath 値と imagePullSecrets 値を指定する方法の例を示しています。

global: 
   imagePullSecrets: [] 
   registryPath: "" 

次の values.schema.json ファイルは、registryPath と 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" ], 
      } 
   } 
} 

次のネットワーク機能定義バージョン (NFDV) 要求ペイロードは、デプロイ時に registryPath 値と imagePullSecrets 値を指定する方法の例を示しています。

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

前の例で:

  • registryPath 値は、https:// や oci:// などのプレフィックスなしで設定します。 プレフィックスは、必要に応じて Helm パッケージ内で定義します。
  • imagePullSecrets および registryPath は、NFDV のオンボード中に指定する必要があります。

その他の考慮事項

レガシの方法を使用する場合には、次の推奨事項を考慮してください。

外部レジストリへの参照を避ける

外部レジストリへの参照は、検証の問題を引き起こす可能性があります。 たとえば、deployment.yaml がハードコーディングされたレジストリ パスまたは外部レジストリ参照を使用していると、検証は失敗します。

手動検証を実行する

イメージとコンテナーの仕様をレビューして、イメージに registryPath のプレフィックスがあり、 imagePullSecrets には secretName が設定されていることを確認します。

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

別の例:

 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>

静的イメージ リポジトリとタグを使用する

各 Helm チャートには、静的イメージ リポジトリとタグが含まれている必要があります。 静的な値は、次のいずれかの方法で設定します。

  • image 行内において
  • values.yaml では、NFDV でこれらの値を公開せずに

NFDV は、Helm チャートとイメージの静的なセットにマップする必要があります。 次の例に示すように、グラフおよびイメージは、新しい NFDV を発行することによってのみ更新するようにします。

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

registryPath と imagePullSecrets における injectArtifactStoreDetails 要件

場合によっては、サード パーティの Helm チャートが、registryPath の Azure Operator Service Manager 要件に完全に準拠していない場合があります。 このような場合は、injectArtifactStoreDetails を使用して、Helm パッケージへの準拠が変更されるのを回避できます。

injectArtifactStoreDetails を有効にすると、Webhook メソッドを使用して、ポッド操作中に適切な registryPath と imagePullSecrets を動的に挿入できます。 このメソッドにより、Helm パッケージで構成されている値がオーバーライドされます。 通常、registryPath の imagePullSecrets セクションにおいては、global と values.yaml が参照されている正当なダミー値を使用する必要があります。

次の values.yaml 例は、registryPath と imagePullSecrets の値を指定して、injectArtifactStoreDetails アプローチとの互換性を確保する方法を示しています。

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

Note

基になる Helm パッケージで registryPath を空白のままにすると、イメージのダウンロード中にサイト ネットワーク サービス (SNS) のデプロイが失敗します。

injectArtifactStoreDetails メソッドの使用

injectArtifactStoreDetails を有効にするには、次の例に示すように、NF リソースの installOptions セクションの roleOverrides パラメーターを true に設定します。

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

依然として、Helm チャート パッケージでは、適切に書式設定された registryPath と imagePullSecrets 値を公開する必要があります。

registryPath と imagePullSecrets のクラスター レジストリ要件

クラスター レジストリを使用すると、Azure Container Registry から Nexus Kubernetes クラスター上のローカル Docker リポジトリに、イメージがコピーされます。 webhook メソッドを使用して、ポッド操作中に適切な registryPath 値と imagePullSecrets 値を動的に挿入します。 このメソッドにより、Helm パッケージで構成されている値がオーバーライドされます。 通常、registryPath の imagePullSecrets セクションにおいては、global と values.yaml が参照されている正当なダミー値を使用する必要があります。

次の values.yaml 例は、クラスター レジストリアプローチとの互換性のために registryPath 値と imagePullSecrets 値を指定する方法を示しています。

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

Note

基になる Helm パッケージで registryPath を空白のままにすると、イメージのダウンロード中に、SNS のデプロイが失敗します。

クラスター レジストリの使用方法の詳細については、概念ドキュメントを参照してください。

不変性制限に関する推奨事項

ファイルやディレクトリの変更は、不変性制限によって防止されます。 たとえば、不変ファイルの内容や名前を変更することはできません。 latest、dev、stable などの不変タグの使用は避けてください。 たとえば、deployment.yaml が latest に対し .Values.image.tag を使用している場合、デプロイが失敗します。

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

CRD 宣言と使用の分割に関する推奨事項

更新をサポートするために、顧客リソース定義 (CRD) の宣言と使用状況を、別々の Helm チャートに分割することをお勧めします。 詳細については、チャートの分離に関する Helm のドキュメントを参照してください。

イメージ バージョンのタグ付けに関する推奨事項

一貫性があり予測可能なデプロイを確保するために、すべてのコンテナー イメージに対して次のことをお勧めします。

  • 運用環境では :latest の使用は避けてください。
    • latest の背後にある実際のイメージは予告なしに変更される可能性があるため、latest を使用すると予期しない動作が発生する可能性があります。
    • クラスター レジストリの設定中において、タグ値が変更されていてもタグ名が同じままの場合には、クラスター レジストリは更新されたイメージを再ダウンロードしません。
    • これにより、古いイメージや矛盾したイメージが実行される可能性があります。
  • 代わりに、常に次のような不変タグを使用します。 :1.4.2
  • すべてのビルドで一意のタグを確実に生成して、既存のタグを上書きしないようにします。

これらのプラクティスは、デプロイの問題を防ぎ、追跡性やロールバックの安全性、さらにセキュリティコンプライアンスを向上させるのに役立ちます。

nfApplication の順次順序付けの推奨事項

既定では、CNF アプリケーションは NFDV に表示される順序に基づいてインストールまたは更新されます。 削除操作の場合、CNF アプリケーションは指定されたのと逆の順序で削除されます。 CNF アプリケーションの順序を既定とは異なる形で定義する必要がある場合は、dependsOnProfile を使用して、インストール、更新、および削除操作の一意のシーケンスを定義します。

dependsOnProfile の使用方法

NFDV の dependsOnProfile を使用して、CNF アプリケーションの Helm 実行順序を制御できます。 この例では、次のようになります。

  • インストール操作中、CNF アプリケーションは、dummyApplication1、dummyApplication2、dummyApplication の順序でデプロイされます。
  • 更新操作中、CNF アプリケーションは、dummyApplication2、dummyApplication1、dummyApplication の順序で更新されます。
  • 削除操作中、CNF アプリケーションは、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"
    }
}

dependsOnProfile に関する一般的なエラー

現時点では、NFDV で指定された dependsOnProfile コードが無効な場合、NF 操作は検証エラーで失敗します。 検証エラーのメッセージが操作状態リソースに、次のように表示されます。

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

Helm 4 を採用するためのベスト プラクティス

Helm は、2016 年の最初のリリース以降、Kubernetes の標準パッケージ マネージャーです。 その進化は、Kubernetes 自体を密接に追跡しています。

  • Helm v2 (2016-2019): グラフベースのアプリケーション パッケージが導入されましたが、サーバー側コンポーネント (Tiller) に依存していました。このコンポーネントにより、セキュリティとマルチテナントの問題が発生しました。
  • Helm v3 (2019-2025): Tiller を削除し、セキュリティと使いやすさを向上させたクライアント専用モデルに移行しました。 このバージョンは業界標準となり、下位互換性を維持しながら、段階的な機能強化を蓄積しました。

Helm v3 の 6 年近くが経過した後、プロジェクトは技術的負債、アーキテクチャの制限、セキュリティの課題を蓄積しました。この課題に対処するには、破壊的変更を導入する必要はありません。 この状況により、2025 年後半に Helm v4 がリリースされました。

Helm 4 が表すもの

Helm 4 は、増分アップグレードではなく、アーキテクチャの大幅な進化です。 主な目標は次のとおりです。

  • 最新の Kubernetes デプロイ パターンに合わせる
  • 従来の Helm v3 動作を削除する
  • 拡張性、保守容易性、およびセキュリティを向上させる

Helm 4 で導入された主な変更点は次のとおりです。

  • Server-Side Apply (SSA): 旧来の 3-way マージ アプローチに置き換わり、デプロイメントを Kubernetes ネイティブの reconciliation セマンティクスに整合させます。
  • 再設計されたプラグイン システム: 分離性と柔軟性を向上させるために、オプションの WebAssembly ベースのプラグインを含む、より拡張可能なアーキテクチャが導入されました。
  • リソース追跡の強化: kstatus などの新しい Kubernetes 状態メカニズムを利用して、より正確なデプロイ状態レポートを提供します。
  • 内部の最新化: 技術的負債を排除し、将来のイノベーションとパフォーマンス向上の基盤を築きます。

重要なのは、Helm 4 は既存の Helm v3 グラフとの互換性を維持するため、組織はチャートやデプロイ成果物をすぐに変更することなく、徐々に Helm 4 を採用できます。

AOSM パブリッシャーとの関連性

AOSM チームは、次の 2 つの重要なマイルストーンを通じて Helm 4 をサポートする予定です。

  • まず、AOSM チームは、"互換モード" で動作する Helm 4.1.4 を含む NFO バージョンをリリースします。このモードでは Helm 3.18 の動作が保持されるため、発行元は既存のグラフや成果物を変更せずに Helm 4 を採用できます。
    • UKSouth ラボでは、この NFO バージョンをプレビューできます。
  • 次に、AOSM チームは、互換性のカスタマイズを削除し、Helm 4 の完全な動作を有効にする NFO バージョンをリリースします。 パブリッシャーは、準備ができたら、グラフと成果物の変更が必要になる可能性があることを理解して、このバージョンを採用できます。
    • AOSM チームは、Q4 CY2026 でパブリッシャー テスト用にこの NFO バージョンを計画しています。

パブリッシャーは、NFO のインストール中に Helm の動作を選択する際の柔軟性を引き続き備えます。 NFO は既定で "互換モード" ですが、Helm 4 の完全な動作を有効にするインストール オプションが提供されます。 この機能はクラスター スコープです。つまり、クラスター内のすべてのデプロイで同じ Helm 操作モードを使用する必要があります。

互換モードの詳細

次の設定では、Helm 4 を "互換モード" で実行するときの Helm 3 の動作が保持されます。

  • スキーマの検証の厳格
    • Helm 4 では、JSON 配列を検証するときに、[]map[string]interface{} など、Go 型のスライスを拒否するより厳密な検証が導入されています。 この動作により、NFO が imagePullSecrets 値を挿入するときにエラーが発生する可能性があります。
    • NFO は、代わりに []interface{} を使用するように値の挿入ロジックを更新し、互換性を確保するために同様のコード パスを監査します。
  • Server-Side Apply (SSA) はデフォルトで有効
    • Helm 4 は、リソースを適用する前に、クラスターの OpenAPI スキーマに対してレンダリングされたマニフェストを検証します。 Helm 3 が以前に許容していた無効なフィールド定義を含むグラフは、検証に失敗する可能性があります。
    • 互換モードでは、Helm 3 の動作を維持するために、インストール操作とアップグレード操作中に SSA が無効になります。
  • 新しい待機モデル
    • Helm 4 の既定値は、Kubernetes ウォッチアクセス許可を必要とするイベントドリブン待機モデルです。 この動作は、必要な RBAC アクセス許可が使用できない Nexus クラスターで失敗する可能性があります。
    • 互換モードは、待機動作を LegacyStrategy にピン留めし、Helm 3 ポーリング セマンティクスを維持します。
  • 削除された項目を再作成
    • Helm 4 では、Upgrade.Recreate のサポートが削除されます。 ランタイムへの影響は低いと予想されますが、CRD で顧客が構成した値は、それ以外の場合は影響を与えなくなります。
    • 互換モードでは、下位互換性のために CRD フィールドが保持されますが、Helm 4 操作の実行時には無視されます。
  • スキーマ メタスキーマの検証
    • Helm 4 は、JSON スキーマ メタスキーマに対して values.schema.json を検証します。 非準拠スキーマ定義を含むグラフは、値の検証が行われる前に拒否されます。 この動作は、一部の発行元グラフに影響することがわかっています。
    • 互換モードでは、インストールおよびアップグレード操作中に SkipSchemaValidation=true が設定されます。