Azure Kubernetes Service (AKS) でのノードのセキュリティ強化 (プレビュー)

Node Hardening は、Linux ノード プールのオプトイン機能であり、ワークロードによってノードに CPU、メモリ、またはディスク圧迫が発生したときに、ノードの安定性を保護します。 クラスターで「ノードの強化」を有効にすると、AKS は、各ノードが Kubernetes コンポーネントおよびホストサービス向けにリソースを予約・割り当てる方法、リソースが不足した際に kubelet がポッドを強制退去させる方法を変更します。

この記事では、ノードのセキュリティ強化の変更点について説明し、強化された既定値を標準の AKS の既定値と比較し、機能を有効、検証、カスタマイズ、無効化する方法について説明します。

Important

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿のまま" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は運用環境での使用を目的としていません。 詳細については、次のサポート記事を参照してください。

ノードのセキュリティ強化の利点

ビジー状態またはバースト状態のノードでは、ワークロードは kubelet、コンテナー ランタイム、およびホスト サービスに必要なリソースを消費してしまう可能性があります。 その場合、ノードが応答しなくなったり、NotReady 状態を報告したり、ポッドを突然終了させたりすることがあります。 ノードのセキュリティ強化は、次の方法でこれらのリスクを軽減します。

  • 強制予約: デフォルトでは、AKS は kube-reserved の値を、スケジューラがポッドに割り当て可能な容量を計算するためにのみ使用します。 また、Kubelet では、Node Hardening を使用して、Linux コントロール グループ (cgroups) を介して kube-reserved 容量と system-reserved 容量を適用します。 kubelet と containerd は専用の kubereserved.slice cgroup で実行されるため、ポッドがノードを飽和状態にした場合でも、予約された CPU 割り当てとメモリが保持されます。
  • ホストサービス専用の容量: 「Node Hardening」では、system.slice で実行されるホスト OS サービス用に、システム予約領域が追加されます。
  • より多くのメモリの余裕: 使用可能なメモリのハードエビクションしきい値はノードメモリに応じて変動するため、kubelet はノードのメモリが極端に少なくなる前にポッドを削除します。
  • グレースフル エビクション: ソフト エビクションしきい値を使用すると、メモリまたはディスク領域が不足しているときに、kubelet は終了猶予期間を設けてポッドをグレースフルにエビクションできます。 ポッドを直ちに終了させるハードエビクションは、最終手段として機能します。
  • ポッド密度でスケーリングする予約: kube-reserved メモリの算出値は、ノードあたりの最大ポッド数が増えるにつれて増加します。これは、より多くのポッドを実行する際の kubelet と containerd のオーバーヘッドを考慮したものです。

ノードのセキュリティ強化を有効にしたときの変更点

次の表では、Kubernetes 1.29 以降を実行している Linux ノードの標準の既定値と、ノードのセキュリティ強化が有効になっているときに AKS が適用する既定値を比較します。

リソース予約

Setting ノードのセキュリティ強化なし Nodeの セキュリティ強化
Kube 予約 CPU CPU コアの数に基づく。 詳細については、「CPU の予約」を参照してください。 変更なし
Kube 予約メモリ min(20 × maxPods + 50, 25% of node memory) MiB min(35 × maxPods + max(250, 2% of node memory), 25% of node memory) MiB
Kube 予約済みプロセス ID (PID) 1000 予約済みではありません
システム予約 CPU None 100m
システム予約済みメモリ None 200 MiB、さらにノード メモリの完全な 32 GiB ごとに 100 MiB、さらに Azure CNI を使用するクラスターでは 100 MiB
システム予約済みエフェメラルストレージ None 1Gi

エビクションのしきい値

Setting ノードのセキュリティ強化なし ノードのセキュリティ強化
ハード エビクション: memory.available 100Mi メモリが 8 GiB 以下のノードの場合は 250Mi、8 GiB を超え 32 GiB 未満のノードの場合は 375Mi、32 GiB 以上のノードの場合は 512Mi
ハード エビクション: nodefs.available と nodefs.inodesFree 10% と 5% 変更なし
ハード エビクション: pid.available 2000 設定されていません
ソフト エビクション: memory.available None 500Mi、750Mi、1Giは、ハード エヴィクションと同じノード メモリ レベルを使用し、30 秒の猶予期間を設けます
ソフト エビクション: nodefs.available と nodefs.inodesFree None 12% と 7%、それぞれ 2 分間の猶予期間付き
ソフトエビクション中の最大ポッド終了猶予期間 設定されていません 60 秒

Cgroup の適用

Setting ノードのセキュリティ強化なし ノードのセキュリティ強化
強制ノード割り当て可能 pods pods、 kube-reserved、および system-reserved
Kubelet と containerd の cgroup system.slice(制限なし) kubereserved.slice のメモリは kube-reserved メモリに制限され、CPU の共有は kube-reserved CPU に比例する
ホスト サービス cgroup system.slice(制限なし) system.slice、メモリはシステム予約メモリに制限され、CPU 共有はシステム予約の CPU に比例します

ノードのセキュリティ強化により多くの容量が予約されるため、ノードではポッドの割り当て可能な容量が少なくなります。 たとえば、4 つの vCPU と 16 GiB のメモリを持つノードで、Azure CNI を使用する場合、ノードのセキュリティ強化を有効にすると、次のように割り当て可能な容量が削減されます。

  • ノードあたりのデフォルトの最大値は 250 ポッドで、メモリは約 570 MiB、CPU は 100 ミリコア、エフェメラル ストレージは 1 GiB です。
  • ノードあたり最大値は 30 ポッドで、メモリは約 1.3 GiB、CPU は 100 ミリコア、エフェメラル ストレージは 1 GiB です。

ソフト エビクションのしきい値は、割り当て可能な容量を減少させません。 これらは、kubelet がポッドの退避を開始したときにのみ変更されます。

考慮事項

ノードのセキュリティ強化を有効にする前に、次の考慮事項に留意してください。

  • ノードのセキュリティ強化はクラスター レベルで有効にし、クラスター内のすべての Linux ノード プールに適用されます。 個々のノード プールに対して有効にすることはできません。また、Windowsノード プールには影響しません。
  • ノードでは割り当て可能な容量が少ないため、ノードのセキュリティ強化を有効にする前にノードに収まるポッドが後で収まらない可能性があります。 ポッドのリソース要求とノード プールのサイズを確認します。
  • system.slice内のホスト サービスは、システム予約メモリと同じハード メモリ制限を共有します。 セキュリティ、監視、ログ転送などのエージェントを、ノード上で systemd サービスとして独自に実行している場合、それらのエージェントはこの制限の対象となります。 運用環境で Node Hardening を使用する前に、メモリ使用量と安定性を確認してください。
  • ノード プールのカスタム kubelet 構成で設定した値は、対応するノードのセキュリティ強化の既定値をオーバーライドします。 詳細については、「ノードのセキュリティ強化設定をカスタマイズする」を参照してください。
  • ノードのセキュリティ強化を後で無効にした場合、既存のノード プールは、ノードが再イメージ化された後も、強化されたソフト エビクション設定を保持します。 これらの設定を削除するには、新しいノード プールを作成する必要があります。 詳細については、「ノードのセキュリティ強化を無効にする」を参照してください。
  • 機能がプレビュー段階にある間は、既定値が変更される可能性があります。 まず、運用環境以外のクラスターから始め、代表的なノード負荷条件下でワークロードの検証を行ってください。

Prerequisites

  • Azure サブスクリプション。 お持ちでない場合は、 無料アカウントを作成してください。
  • Linux ノード プールを持つ AKS クラスター、またはそのようなクラスターを作成するためのアクセス許可。
  • aks-preview Azure CLI 拡張機能および CustomNodeConfigPreview 機能フラグについては、以下のセクションで説明します。

aks-preview Azure CLI 拡張機能をインストールする

  1. aks-preview コマンドを使用して、az extension add拡張機能をインストールします。

    az extension add --name aks-preview
    
  2. az extension update コマンドを使用して、拡張機能の最新バージョンに更新します。

    az extension update --name aks-preview
    

CustomNodeConfigPreview フィーチャーフラグを登録する

  1. CustomNodeConfigPreview コマンドを使用して、az feature register機能フラグを登録します。

    az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    

    状態が [登録済み] と表示されるまでに数分かかります。

  2. az feature show コマンドを使用して、登録状態を確認します。

    az feature show --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    
  3. 状態がRegisteredと表示されたら、 コマンドを使用して、az provider register リソース プロバイダーの登録を更新します。

    az provider register --namespace "Microsoft.ContainerService"
    

ノードのセキュリティ強化を有効にする

プレビュー期間中、Node Hardening は既定では有効になっていません。

新しいクラスターでノードのセキュリティ強化を有効にする

az aks create コマンドと --enable-node-hardening パラメーターを使用して、ノードのセキュリティ強化を有効にしたクラスターを作成します。

このコマンドには、 aks-preview 拡張機能と CustomNodeConfigPreview 機能フラグが必要です。 詳細については、「前提条件」を参照してください。

az aks create \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening \
    --generate-ssh-keys

変更を確認するには、「ノードのセキュリティ強化設定の確認」を参照してください。

既存のクラスターでノードのセキュリティ強化を有効にする

--enable-node-hardening コマンドで az aks update パラメーターを使用して、既存のクラスターでノードのセキュリティ強化を有効にします。

このコマンドには、 aks-preview 拡張機能と CustomNodeConfigPreview 機能フラグが必要です。 詳細については、「前提条件」を参照してください。

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening

変更を確認するには、「ノードのセキュリティ強化設定の確認」を参照してください。

ノードのセキュリティ強化設定を確認する

  1. az aks get-credentials コマンドを使用して、クラスターの資格情報を取得します。

    az aks get-credentials --resource-group <resource-group-name> --name <cluster-name>
    
  2. kubelet 構成エンドポイントにクエリを実行して、ノードの有効な kubelet 予約とエビクション設定を確認します。

    kubectl get --raw "/api/v1/nodes/<node-name>/proxy/configz" | jq '.kubeletconfig | {kubeReserved, systemReserved, evictionHard, evictionSoft, evictionSoftGracePeriod, evictionMaxPodGracePeriod, enforceNodeAllocatable}'
    

    強化されたノードでは、 systemReserved と evictionSoft には値が含まれており、 enforceNodeAllocatable には kube-reserved と system-reservedが含まれます。

  3. ノードのキャパシティとその割り当て可能なリソースを比較します。

    kubectl get node <node-name> -o jsonpath='{.status.capacity}{"\n"}{.status.allocatable}{"\n"}'
    

    強化されたノードでは、割り当て可能な CPU、メモリ、エフェメラル ストレージは容量よりも低くなります。 この差分は、リソース予約の kube-reserved および system-reserved の値に、エヴィクションしきい値のハードエヴィクションしきい値を加えた値に等しくなります。 たとえば、Azure CNI を使用する 4 vCPU と 16 GiB のメモリを持つノードでは、割り当て可能な CPU は容量より 240 ミリコア低くなります。kube 予約 CPU は 140 ミリコア、システム予約 CPU は 100 ミリコアです。

ノードのセキュリティ強化設定をカスタマイズする

カスタム kubelet 構成を使用して、Linux ノード プールの kube-reserved および eviction の既定値をオーバーライドできます。 これらの設定には、 CustomNodeConfigPreview 機能フラグが必要です。 クラスターでノードのセキュリティ強化が有効になっているかどうかに関係なく、これらを使用できます。 AKS はシステム予約値と cgroup の適用を管理し、それらをカスタマイズすることはできません。

各設定は、リソース予約 または エビクションしきい値 テーブルの行を上書きします。 Kube で予約された項目は、kubeReserved 設定に対応します。 ハードエビクション行は、hardEvictionThreshold 設定に対応します。 ソフトエビクション行は、softEvictionThreshold と softEvictionGracePeriod の設定に対応します。 Pod の最大終了猶予期間は evictionMaxPodGracePeriodInSeconds に相当します。

次の設定を構成できます。

Setting Overrides Description
kubeReserved.cpuMillicores Kube用に予約済みのCPU Kubernetes システム デーモン用に予約された CPU (ミリコア)。
kubeReserved.memoryMB Kube用に予約されたメモリ Kubernetes システム デーモン用に予約されたメモリ (MiB)。
hardEvictionThreshold.memoryAvailable ハード エビクション: memory.available 利用可能なメモリに関するハード エビクションのしきい値。
hardEvictionThreshold.nodeFsAvailable ハード エビクション: nodefs.available 使用可能なノード ファイルシステム領域のハード エビクションしきい値。
hardEvictionThreshold.nodeFsInodesFree ハード エビクション: nodefs.inodesFree 空きノード ファイルシステム inode のハードエビクションしきい値。
softEvictionThreshold.memoryAvailable ソフト エビクション: memory.available 利用可能なメモリに関するソフト エビクションのしきい値。
softEvictionThreshold.nodeFsAvailable ソフト エビクション: nodefs.available 使用可能なノード ファイルシステム領域のソフトエビクションしきい値。
softEvictionThreshold.nodeFsInodesFree ソフト エビクション: nodefs.inodesFree フリーノード ファイル システムのiノードに対するソフト エビクションのしきい値。
softEvictionGracePeriod.memoryAvailable ソフトエビクション: memory.available 猶予期間 kubelet がポッドを退避させるまでに、利用可能なメモリがソフトしきい値を下回った状態を維持しなければならない時間。
softEvictionGracePeriod.nodeFsAvailable ソフトエビクション: nodefs.available 猶予期間 kubelet がポッドを退避する前に、利用可能なノードのファイルシステム空き容量がソフトしきい値を下回った状態を維持しなければならない期間。
softEvictionGracePeriod.nodeFsInodesFree ソフトエビクション: nodefs.inodesFree 猶予期間 kubelet がポッドを退避する前に、フリーノード ファイルシステムのノードがソフトしきい値を下回った状態を維持する必要がある期間。
evictionMaxPodGracePeriodInSeconds ソフトエビクション時の最大ポッド終了猶予期間 ソフト エビクション中に、kubelet がポッドの終了を許可する最大秒数。
  • 各設定で使用できる値、最小値、および検証規則については、AKS のカスタム ノード構成パラメーターを参照してください。
  • 各エビクション信号について、ソフト エビクションのしきい値とその対応する猶予期間の両方を設定し、各ソフト エビクションのしきい値が、その信号のハード エビクションのしきい値よりも大きくなることを確認します。
  1. カスタマイズする設定を含む kubelet 構成ファイル ( nodehardening-kubelet.json など) を作成します。 次の例では、構成可能なすべての値を設定します。 kube-reserved を 200 ミリコアの CPU と 1,024 MiB のメモリに設定します。 使用可能なメモリの 512Mi、使用可能なファイルシステム領域の 10%、および空き inode の 5% のハードエビクションしきい値を設定します。 30 秒、2 分、2 分の猶予期間で、1Gi、12%、7% のソフト退去しきい値を設定します。 また、60 秒の最大ポッド終了猶予期間も設定します。

    {
      "kubeReserved": {
        "cpuMillicores": 200,
        "memoryMB": 1024
      },
      "hardEvictionThreshold": {
        "memoryAvailable": "512Mi",
        "nodeFsAvailable": "10%",
        "nodeFsInodesFree": "5%"
      },
      "softEvictionThreshold": {
        "memoryAvailable": "1Gi",
        "nodeFsAvailable": "12%",
        "nodeFsInodesFree": "7%"
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "30s",
        "nodeFsAvailable": "2m",
        "nodeFsInodesFree": "2m"
      },
      "evictionMaxPodGracePeriodInSeconds": 60
    }
    
  2. --kubelet-config コマンドで az aks nodepool add パラメーターを使用して、構成ファイルを使用する Linux ノード プールを作成します。

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./nodehardening-kubelet.json
    

    --kubelet-config コマンドで az aks create パラメーターを使用して、クラスターの初期ノード プールに構成を適用することもできます。

ノードのセキュリティ強化を無効にする

az aks update パラメーターを指定して --disable-node-hardening コマンドを使用し、ノードのセキュリティ強化を無効にします。

このコマンドには、 aks-preview 拡張機能と CustomNodeConfigPreview 機能フラグが必要です。 詳細については、「前提条件」を参照してください。

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --disable-node-hardening

ノードのセキュリティ強化を無効にすると、クラスター レベルの設定はオフになりますが、既存のノードはすぐには変更されません。 既存のノードは、たとえばノード イメージのアップグレード中に再イメージ化されるまで、すべての強化された設定を保持します。 ノードが再イメージ化された後、次の変更が適用されます。

  • AKS の標準設定に戻しました: Kube 予約およびシステム予約リソース、ハード エビクションしきい値、cgroup の適用。 ノードの割り当て可能な容量は、それに応じて増加します。
  • 保持される項目: ソフトエビクションのしきい値、ソフトエビクションの猶予期間、およびソフトエビクション中の最大ポッド終了猶予期間。

カスタム kubelet 構成は、クラスターまたはノード プールを作成する場合にのみ設定できるため、既存のノード プールから保持されているソフト エビクション設定を削除することはできません。 それらを削除するには、それらを明示的に設定解除する新しいノード プールを作成し、ワークロードを新しいノード プールに移動してから、古いノード プールを削除します。

  1. たとえば remove-soft-eviction.json のような kubelet 構成ファイルを作成します。 次の例では、すべてのソフトエビクションしきい値と猶予期間を空の文字列に設定し、その信号のソフトエビクションをオフにします。 また、ポッドの終了の最大猶予期間を 0 に設定します。これは、標準の AKS の既定値です。

    {
      "softEvictionThreshold": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "evictionMaxPodGracePeriodInSeconds": 0
    }
    
  2. --kubelet-config コマンドで az aks nodepool add パラメーターを使用して、構成ファイルを使用する Linux ノード プールを作成します。

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./remove-soft-eviction.json
    
  3. ワークロードを新しいノード プールに移動し、古いノード プールを削除します。 詳細については、「 AKS でのノード プールのサイズ変更」を参照してください。

ノードの設定を確認するには、ノードのセキュリティ強化設定の確認を参照してください。 新しいノード プール内のノードでは、 evictionSoft は空です。