Azure Kubernetes Service (AKS) でパブリック Standard Load Balancer を使用する

Azure Load Balancer は、受信と送信の両方のシナリオがサポートされる開放型システム間相互接続 (OSI) モデルのレイヤー 4 上で動作します。 これにより、ロード バランサーのフロントエンドに到着した受信フローが、バックエンド プールのインスタンスに分配されます。

パブリック ロード バランサーを AKS と統合すると、次の 2 つの目的を達成することができます。

  1. プライベート IP アドレスをそのアウトバウンド プールのパブリック IP アドレス部分に変換することによって、AKS 仮想ネットワーク内のクラスター ノードへのアウトバウンド接続を提供します。
  2. タイプがLoadBalancer の Kubernetes サービスを介してアプリケーションにアクセスできるようにするため、アプリケーションを容易にスケーリングし、高可用性サービスを作成できるようにします。

内部 (プライベート) ロード バランサーは、プライベート IP "のみ" がフロントエンドとして許可される場合に使用されます。 内部ロード バランサーは、仮想ネットワーク内でトラフィックを負荷分散させるために使用されます。 ハイブリッド シナリオでは、オンプレミスのネットワークからもロード バランサーのフロントエンドにアクセスできます。

この記事では、AKS でのパブリック ロード バランサーとの統合について説明します。 内部ロード バランサーの統合については、「AKS で内部ロード バランサーを使用する」を参照してください。

開始する前に

  • Azure Load Balancer は、BasicStandard の 2 つの SKU で使用できます。 Standard SKU は、既定では AKS クラスターを作成するときに使用します。 Standard SKU を使用すると、より大きなバックエンド プール、複数のノード プールAvailability Zones などの追加機能にアクセスでき、既定でセキュリティ保護されます。 AKS の場合、この Load Balancer SKU が推奨されます。 BasicStandard SKU の詳細については、「Azure Load Balancer の SKU の比較」をご覧ください。
  • LoadBalancerを持つ Kubernetes サービスでサポートされている注釈の完全なリストについては、「LoadBalancer 注釈」を参照してください。
  • この記事では、Standard SKU Azure Load Balancer を持つ AKS クラスターがあることを前提としています。 AKS クラスターが必要な場合は、Azure CLIAzure PowerShell、または Azure portal を使用して作成できます。
  • AKS は、エージェント ノードのライフサイクルと操作を管理します。 エージェント ノードに関連付けられている IaaS リソースの変更はサポートされていません。 サポートされていない操作の例として、ロード バランサー リソース グループに手動で変更を加えるというものがあります。

重要

独自のゲートウェイ、ファイアウォールまたはプロキシを使用してアウトバウンド接続を行いたい場合は、アウトバウンドの種類を UserDefinedRouting (UDR) として使用することで、ロード バランサーのアウトバウンド プールとそれぞれのフロントエンド IP の作成をスキップできます。 送信の種類では、クラスターのエグレス方法を定義します。既定の種類は、LoadBalancer です。

パブリック Standard Load Balancer を使用する

アウトバウンドのタイプとして LoadBalancer (既定) に設定して AKS クラスターを作成した後に、クラスターは、ロード バランサーを使用してサービスを公開できるようになります。

public-svc.yaml という名前のサービス マニフェストを作成します。これにより、 タイプが LoadBalancer のパブリック サービスが作成されます。

apiVersion: v1
kind: Service
metadata:
  name: public-svc
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: public-app

ロード バランサーの IP アドレスを指定する

特定の IP アドレスをロード バランサーで使用する場合は、次の 2 つの方法があります。

重要

ロード バランサー YAML マニフェストに LoadBalancerIP プロパティを追加することは、アップストリームの Kubernetes に続いて非推奨となっています。 現在の使用方法は変わらず、既存のサービスは変更せずに動作することが期待されますが、代わりにサービス注釈を設定することを強くお勧めします

  • サービス注釈の設定: IPv 4 アドレスの場合は service.beta.kubernetes.io/azure-load-balancer-ipv4、IPv 6 アドレスの場合は service.beta.kubernetes.io/azure-load-balancer-ipv6 を使用します。
  • LoadBalancerIP プロパティをロード バランサー YAML マニフェストに追加する: Service.Spec.LoadBalancerIP プロパティをロード バランサー YAML マニフェストに追加します。 このフィールドはアップストリームの Kubernetes に続いて非推奨となっており、デュアル スタックをサポートできません。 現在の使用方法は変わらず、既存のサービスは変更せずに動作することが期待されます。

サービス マニフェストを展開する

kubectl apply を使用してパブリック サービス マニフェストをデプロイし、YAML マニフェストの名前を指定します。

kubectl apply -f public-svc.yaml

Azure Load Balancer は、新しいサービスのフロントとなる新しいパブリック IP を使用して構成されます。 Azure Load Balancer では複数のフロントエンド IP を持つことができるため、デプロイされるそれぞれの新しいサービスによって、一意にアクセスされる新しい専用のフロントエンド IP が取得されます。

サービスが作成され、ロード バランサーが構成されたことを、次のコマンドを使用して確認します。

kubectl get service public-svc
NAMESPACE     NAME          TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)         AGE
default       public-svc    LoadBalancer   10.0.39.110    52.156.88.187   80:32068/TCP    52s

サービスの詳細を表示すると、ロード バランサー上のこのサービス用に作成されたパブリック IP アドレスが、EXTERNAL-IP 列に表示されます。 IP アドレスが "<保留中>" から実際のパブリック IP アドレスに変わるまで、数分かかることがあります。

サービスに関する詳細な情報を見るには、次のコマンドを使用します。

kubectl describe service public-svc

次の出力例は、kubectl describe service を実行した後の出力の圧縮バージョンです。 "LoadBalancer イングレス" には、サービスによって公開される外部 IP アドレスが表示されます。 IP には内部アドレスが表示されます。

Name:                        public-svc
Namespace:                   default
Labels:                      <none>
Annotations:                 <none>
Selector:                    app=public-app
...
IP:                          10.0.39.110
...
LoadBalancer Ingress:        52.156.88.187
...
TargetPort:                  80/TCP
NodePort:                    32068/TCP
...
Session Affinity:            None
External Traffic Policy:     Cluster
...

パブリック Standard Load Balancer を構成する

クラスターの作成時や、あるいはクラスターを更新することにより、標準パブリック ロード バランサーのさまざまな設定をカスタマイズできます。 これらのカスタマイズ オプションを使用すると、お客様のワークロードのニーズを満たすロード バランサーを作成できます。 Standard ロード バランサーを使用すると、次の操作を行うことができます。

  • マネージド アウトバウンド IP の数を設定またはスケーリングする。
  • 独自のカスタムアウトバウンド IP またはアウトバウンド IP プレフィックスを使用する。
  • クラスターの各ノードに割り当てられるアウトバウンド ポートの数をカスタマイズする。
  • アイドル状態の接続のタイムアウト設定を構成する。

重要

特定の時点では、1 つの送信 IP オプションのみ (マネージド IP、独自の IP を使用する、または IP プレフィックス) を使用できます。

受信プールの種類を変更する

AKS ノードをロード バランサー バックエンド プールで参照する場合は、IP 構成 (Azure Virtual Machine Scale Sets ベースのメンバーシップ) か IP アドレスのみ使用できます。 IP アドレス ベースのバックエンド プール メンバーシップを使用すると、サービスの更新とロード バランサーのプロビジョニングの効率が向上します (特にノード数が多い場合)。 IP ベースのバックエンド プールを使用した新しいクラスターのプロビジョニングと既存のクラスターの変換ができるようになりました。 NAT Gateway またはユーザー定義のルーティング エグレスの種類と組み合わせると、新しいノードとサービスのプロビジョニングのパフォーマンスが向上します。

2 つの異なるプール メンバーシップの種類を使用できます。

  • nodeIPConfiguration - レガシ Virtual Machine Scale Sets IP 構成ベースのプール メンバーシップの種類
  • nodeIP - IP ベースのメンバーシップの種類

要件

  • AKS クラスターはバージョン 1.23 以降である必要があります。
  • AKS クラスターは、標準ロード バランサーと仮想マシン スケール セットを使用している必要があります。

IP ベースの受信プール メンバーシップを使用して新しい AKS クラスターを作成する

az aks create \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-backend-pool-type=nodeIP

既存の AKS クラスターを更新することで、IP ベースの受信プール メンバーシップを使用する

警告

この操作により、クラスター内の受信サービス トラフィックが一時的に中断します。 多数のノードを持つ大規模なクラスターでは、影響時間が長くなります。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-backend-pool-type=nodeIP

マネージド送信パブリック IP の数のスケーリング

Azure Load Balancer は、仮想ネットワークからのアウトバウンドおよびインバウンド接続も提供します。 アウトバウンド規則を使用すると、パブリック Standard ロード バランサーのネットワーク アドレス変換の構成を簡素化できます。

アウトバウンド規則は、負荷分散規則およびインバウンド NAT 規則と同じ構文に従います。

フロントエンド IP + パラメーター + バックエンド プール

アウトバウンド規則では、フロントエンドに変換され、バックエンド プールによって識別されるすべての仮想マシンの送信 NAT を構成します。 パラメーターを使用すると、アウトバウンド NAT アルゴリズムをより制御できます。

パブリック IP アドレスが 1 つのアウトバウンド規則を使用できますが、アウトバウンド規則がアウトバウンド NAT のスケーリングに適しているのは、構成の負担を軽減するからです。 複数の IP アドレスを使用して大規模なシナリオを計画したり、アウトバウンド規則を使用して SNAT の枯渇しやすいパターンを緩和したりすることもできます。 フロントエンドが提供する IP アドレスごとに、ロード バランサーで SNAT ポートとして使用される 64,000 個の一時的なポートが提供されます。

既定で作成されるマネージド アウトバウンド パブリック IP で Standard SKU ロード バランサーを使用する場合、--load-balancer-managed-outbound-ip-count パラメーターを使用して、マネージド送信パブリック IP の数をスケーリングすることができます。

次のコマンドを使用して、既存のクラスターを更新します。 また、このパラメーターは、マネージド アウトバウンド パブリック IP を複数持つように設定することもできます。

重要

Azure portal を使用してアウトバウンド規則に変更を加えることはお勧めしません。 これらの変更を行うときは、Load Balancer リソースに直接ではなく、AKS クラスターを経由して行う必要があります。

Load Balancer リソースに対して直接行われたアウトバウンド規則の変更は、クラスターが停止、開始、アップグレード、スケーリングされたときなど、調整されるたびに削除されます。

Azure CLI を、例に示すように使用します。 az aks CLI コマンドを使用して行なったアウトバウンド規則の変更は、クラスターのダウンタイムに関係なく永続的です。

詳細については、「Azure Load Balancer のアウトバウンド規則」を参照してください。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-managed-outbound-ip-count 2

上の例では、myResourceGroupmyAKSCluster クラスターに対して、管理対象の送信パブリック IP の数が 2 に設定されます。

クラスター作成時に、--load-balancer-managed-outbound-ip-count パラメーターを追加し、それを希望する値に設定することでマネージド アウトバウンド パブリック IP の初期数を設定することも可能です。 管理対象の送信パブリック IP の既定数は 1 です。

独自の送信パブリック IP またはプレフィックスを提供する

Standard SKU ロード バランサーを使用する場合、AKS クラスターにより AKS で管理されるインフラストラクチャ リソース グループに、パブリック IP が自動的に作成され、それがロード バランサーの送信プールに既定で割り当てられます。

AKS によって作成されたパブリック IP は、AKS によって管理されるリソースです。つまり、AKS はそのパブリック IP のライフサイクルを管理し、パブリック IP リソースに対するユーザーの直接の操作を必要としません。 代わりに、クラスターの作成時に独自のカスタム パブリック IP またはパブリック IP プレフィックスを割り当てることもできます。 また、既存のクラスターのロード バランサーのプロパティでカスタム IP を更新することもできます。

独自のパブリック IP またはプレフィックスを使用するための要件は以下の通りです。

  • ユーザーはカスタム パブリック IP アドレスを作成して所有する必要があります。 管理の競合が発生するため、AKS によって作成されるマネージド パブリック IP アドレスを「独自のカスタム IP」として再使用することはできません。
  • 送信 IP にアクセスするためのアクセス許可が AKS クラスター ID (サービス プリンシパルまたはマネージド ID) に付与されていることを確認する必要があります (必要なパブリック IP アクセス許可リストに従います)。
  • 送信 IP または送信 IP プレフィックスを構成するために必要な前提条件と制約を満たしていることをご確認ください。

クラスターを独自の送信パブリック IP で更新する

az network public-ip show コマンドを使用すると、パブリック IP の ID が一覧表示されます。

az network public-ip show --resource-group myResourceGroup --name myPublicIP --query id -o tsv

上のコマンドでは、myResourceGroup リソース グループの myPublicIP パブリック IP の IP が表示されます。

お使いのパブリック IP でクラスターを更新するには、 load-balancer-outbound-ips パラメーターを指定した az aks update コマンドを使用します。

次の例では、前のコマンドで得られた ID を指定した load-balancer-outbound-ips パラメーターを使用しています。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-outbound-ips <publicIpId1>,<publicIpId2>

独自の送信パブリック IP プレフィックスでクラスターを更新する

Standard SKU ロード バランサーと共に、エグレス用のパブリック IP プレフィックスを使用することもできます。 次の例では、az network public-ip prefix show コマンドを使用し、パブリック IP プレフィックスの ID が一覧表示されます。

az network public-ip prefix show --resource-group myResourceGroup --name myPublicIPPrefix --query id -o tsv

上のコマンドでは、myResourceGroup リソース グループの myPublicIPPrefix パブリック IP プレフィックスの IP が表示されます。

次の例では、load-balancer-outbound-ip-prefixes パラメーターと前のコマンドからの ID が使用されています。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-outbound-ip-prefixes <publicIpPrefixId1>,<publicIpPrefixId2>

独自のパブリック IP またはプレフィックスでクラスターを作成する

クラスターを作成するとき、エグレス エンドポイントを許可リストに追加するといったシナリオをサポートする目的でエグレス用に独自の IP アドレスや IP プレフィックスを導入することができます。 クラスター作成時に独自のパブリック IP と IP プレフィックスを定義するには、前のコマンドに示したのと同じパラメーターを追加します。

load-balancer-outbound-ips パラメーターを指定した az aks create コマンドを使用して、お使いのパブリック IP で新しいクラスターを作成します。

az aks create \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-outbound-ips <publicIpId1>,<publicIpId2>

load-balancer-outbound-ip-prefixes パラメーターを指定した az aks create コマンドを使用して、お使いのパブリック IP プレフィックスで新しいクラスターを作成します。

az aks create \
    --resource-group myResourceGroup \
    --load-balancer-outbound-ip-prefixes <publicIpPrefixId1>,<publicIpPrefixId2>

割り当てられた送信ポートを構成する

重要

小規模な宛先セットへの多数の接続を確立できるアプリケーション (データベースに接続するフロントエンド アプリケーションの多くのインスタンスなど) がクラスター上にある場合、SNAT ポートの枯渇に遭遇しやすいシナリオが考えられます。 SNAT ポートの枯渇は、アプリケーションが別のアプリケーションまたはホストへの接続を確立するために使用する送信ポートを使い果たした場合に発生します。 SNAT ポートの枯渇が懸念される場合は、ロード バランサーで割り当てられるアウトバウンド ポートとアウトバウンド フロントエンド IP を増やすことを強くお勧めします。

SNAT の詳細については、「送信接続に SNAT を使用する」を参照してください。

既定では、AKS によってロード バランサーの AllocatedOutboundPorts0 に設定されています。これにより、クラスターの作成時に、バックエンド プールのサイズに基づく送信ポートの自動割り当てが有効になります。 たとえば、クラスターのノード数が 50 以下の場合、各ノードには 1024 個のポートが割り当てられます。 クラスター内のノードの数が増えるほど、ノードあたりの使用可能なポート数が少なくなります。

重要

ノード サイズが 50 以下 (1 から 50) の場合にフロントエンド IP が追加されるかどうかに関係なく、1024 ポートのハード制限があります。

AKS クラスター ロード バランサーの AllocatedOutboundPorts 値を表示するには、az network lb outbound-rule list を使用します。

NODE_RG=$(az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv)
az network lb outbound-rule list --resource-group $NODE_RG --lb-name kubernetes -o table

次の出力例は、バックエンド プールのサイズに基づく送信ポートの自動割り当てがクラスターに対して有効になっている場合を示しています。

AllocatedOutboundPorts    EnableTcpReset    IdleTimeoutInMinutes    Name             Protocol    ProvisioningState    ResourceGroup
------------------------  ----------------  ----------------------  ---------------  ----------  -------------------  -------------
0                         True              30                      aksOutboundRule  All         Succeeded            MC_myResourceGroup_myAKSCluster_eastus  

クラスターの作成時または更新時に AllocatedOutboundPorts と送信 IP アドレスに特定の値を構成するには、load-balancer-outbound-portsload-balancer-managed-outbound-ip-countload-balancer-outbound-ipsload-balancer-outbound-ip-prefixes のいずれかを使用します。 アウトバウンド ポートとアウトバウンド IP アドレスのいずれかに特定の値を設定したり、既存の値を増やしたりする前に、適切な数のアウトバウンド ポートと IP アドレスを計算する必要があります。 この計算を最も近い整数に丸めるには、次の式 64,000 ports per IP / <outbound ports per node> * <number of outbound IPs> = <maximum number of nodes in the cluster> を使用します。

アウトバウンド ポートと IP の数を計算し、値を設定するときは、以下の内容に留意してください。

  • ノードあたりのアウトバウンド ポートの数は、設定する値に基づいて固定されます。
  • 送信ポートの値は必ず 8 の倍数とします。
  • IP を追加しても、どのノードにもポートが追加されるわけではありませんが、クラスター内のより多くのノードのための容量が提供されます。
  • 必ずアップグレードの一環として追加される可能性があるノード (maxSurge 値で指定されたノードの数を含む) を考慮してください。

次の例は、設定した値が送信ポートと IP アドレスの数にどのような影響を与えるかを示しています。

  • 既定値が使用され、クラスターに 48 個のノードがある場合、各ノードでは 1024 個のポートを使用できます。
  • 既定値が使用され、クラスターのノードが 48 個から 52 個にスケーリングされている場合、各ノードで使用できるポートは 1024 個から 512 個に更新されます。
  • アウトバウンド ポートの数が 1,000 に設定され、アウトバウンド IP 数が 2 に設定されている場合、クラスターでは最大 128 個のノードをサポートできます: 64,000 ports per IP / 1,000 ports per node * 2 IPs = 128 nodes
  • アウトバウンド ポートの数が 1,000 に設定され、アウトバウンド IP 数が 7 に設定されている場合、クラスターでは最大 448 個のノードをサポートできます: 64,000 ports per IP / 1,000 ports per node * 7 IPs = 448 nodes
  • アウトバウンド ポートの数が 4,000 に設定され、アウトバウンド IP 数が 2 に設定されている場合、クラスターでは最大 32 個のノードをサポートできます: 64,000 ports per IP / 4,000 ports per node * 2 IPs = 32 nodes
  • アウトバウンド ポートの数が 4,000 に設定され、アウトバウンド IP 数が 7 に設定されている場合、クラスターでは最大 112 個のノードをサポートできます: 64,000 ports per IP / 4,000 ports per node * 7 IPs = 112 nodes

重要

送信ポートと IP の数を計算した後、アップグレード中のノードのサージを処理するための追加の送信ポート容量があることを確認します。 アップグレードやその他の操作に必要な追加ノードに、十分な余剰ポートを割り当てることが重要です。 既定では、AKS でアップグレード操作に 1 つのバッファー ノードが使用されます。 maxSurge 値を使用する場合、ノードあたりの送信ポート数に maxSurge 値を乗算して、必要なポートの数を求めます。 たとえば、最大 100 ノードがあり、最大サージ値が 2 のクラスターで、ノードあたり 4,000 のポートと 7 個の IP アドレスが必要であるとします。

  • 2 サージ ノード * ノードあたり 4,000 ポート = 8,000 ポート (アップグレード中のノードのサージに必要な数)。
  • 100 ノード * ノードあたり 4,000 ポート = 400,000 ポート (クラスターに必要な数)。
  • 7 個の IP * IP あたり 64,000 ポート = 448,000 ポート (クラスターで使用可能な数)。

上の例では、クラスターの余剰容量が 48,000 ポート存在することを示しています。これは、アップグレード中のノードのサージに必要な 8,000 ポートを処理するのに十分です。

値を計算して検証したら、クラスターの作成時または更新時に、load-balancer-outbound-portsload-balancer-managed-outbound-ip-countload-balancer-outbound-ipsload-balancer-outbound-ip-prefixes のいずれかを使用してこれらの値を適用できます。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-managed-outbound-ip-count 7 \
    --load-balancer-outbound-ports 4000

ロード バランサーのアイドル タイムアウトを構成する

SNAT ポート リソースがなくなると、既存のフローによって SNAT ポートが解放されない限り、送信フローは失敗します。 Load Balancer は、フローが終了すると SNAT ポートを回収します。また、AKS で構成されたロード バランサーは、30 分間のアイドル タイムアウトを使用して、アイドル フローから SNAT ポートを回収します。

さらに、トランスポート (たとえば、TCP keepalivesapplication-layer keepalives) を使用して、アイドル フローを更新し、必要に応じて、このアイドル タイムアウトをリセットすることもできます。 このタイムアウトは、次の例で示すように構成することができます。

az aks update \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --load-balancer-idle-timeout 4

存続期間の短い接続が多数存在することが想定される場合で、存続期間の長い接続に、アイドル時間が長くなる可能性のあるものがない場合 (kubectl proxykubectl port-forward を使用するなどの場合) は、"4 分間" のような短いタイムアウト値を使用することを検討してください。 TCP キープアライブを使用するときは、接続の一方の側で有効にすれば十分です。 たとえば、フローのアイドル タイマーをリセットするには、TCP keepalives をサーバー側でのみ有効にすれば十分です。 両側で開始する必要はありません。 データベースのクライアント/サーバー構成など、アプリケーション レイヤーにも同様の概念があります。 サーバー側で、アプリケーション固有のキープアライブのどのようなオプションが存在するかを確認します。

重要

AKS では、既定で、アイドル時の "TCP リセット" が有効になっています。 この構成を維持し、ご自分のシナリオでのアプリケーションの動作をより予測可能にするために活用することをお勧めします。

TCP RST は、ESTABLISHED 状態の TCP 接続時のみ送信されます。 詳細については、こちらを参照してください。

IdleTimeoutInMinutes を既定の 30 分とは異なる値に設定する場合は、ワークロードで送信接続が必要な時間を考慮します。 また、AKS の外部で使用される Standard SKU ロード バランサーの既定のタイムアウト値が 4 分であることを考慮します。 特定の AKS ワークロードをより正確に反映するように IdleTimeoutInMinutes の値を設定すると、使用されなくなった接続と関連付けられることによる SNAT の枯渇を減らすのに役立ちます。

警告

AllocatedOutboundPortsIdleTimeoutInMinutes の値を変更すると、ロード バランサーに対するアウトバウンド規則の動作が大きく変化する可能性があるので、安易に変更することは避けてください。 これらの値を更新する場合は、まず SNAT のトラブルシューティングに関するセクションを確認し、ロード バランサーのアウトバウンド規則Azure のアウトバウンド接続に関する記事を確認して、変更の影響を完全に理解するようにしてください。

受信トラフィックを特定の IP 範囲に制限する

次のマニフェストでは loadBalancerSourceRanges を使用して、受信外部トラフィックの新しい IP 範囲を指定します。

apiVersion: v1
kind: Service
metadata:
  name: azure-vote-front
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: azure-vote-front
  loadBalancerSourceRanges:
  - MY_EXTERNAL_IP_RANGE

この例では、MY_EXTERNAL_IP_RANGE の範囲からの受信外部トラフィックのみを許可するように規則を更新します。 MY_EXTERNAL_IP_RANGE を内部サブネットの IP アドレスに置き換えると、トラフィックはクラスターの内部 IP のみに制限されます。 トラフィックがクラスターの内部 IP に制限されている場合、Kubernetes クラスターの外部のクライアントはロード バランサーにアクセスできません。

Note

  • 受信外部トラフィックは、ロード バランサーから AKS クラスターの仮想ネットワークに流れます。 この仮想ネットワークには、ロード バランサーからのすべての受信トラフィックを許可するネットワーク セキュリティ グループ (NSG) があります。 この NSG は LoadBalancer という種類のサービス タグを使用して、ロード バランサーからのトラフィックを許可します。
  • バージョン v1.25 以上のクラスターのサービスの LoadBalancer IP にアクセスする必要があるポッドがある場合は、ポッド CIDR を loadBalancerSourceRanges に追加する必要があります。

インバウンド接続時にクライアントの IP を維持する

既定では、Kubernetes および AKS 内の LoadBalancer 型のサービスは、ポッドへの接続時にクライアントの IP アドレスを保持しません。 ポッドに配信されるパケットの送信元 IP は、ノードのプライベート IP になります。 クライアントの IP アドレスを維持するには、サービス定義で service.spec.externalTrafficPolicylocal に設定する必要があります。 次のマニフェストに例を示します。

apiVersion: v1
kind: Service
metadata:
  name: azure-vote-front
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
  - port: 80
  selector:
    app: azure-vote-front

Kubernetes 注釈によるカスタマイズ

次の注釈は、種類が LoadBalancer の Kubernetes サービスでサポートされており、INBOUND フローだけに適用されます。

Annotation 説明
service.beta.kubernetes.io/azure-load-balancer-internal true または false ロード バランサーが内部である必要があるかどうかを指定します。 設定されていない場合は、既定でパブリックになります。
service.beta.kubernetes.io/azure-load-balancer-internal-subnet サブネットの名前 内部ロード バランサーをバインドする必要があるサブネットを指定します。 設定されていない場合、既定で、クラウド構成ファイルで構成されているサブネットに設定されます。
service.beta.kubernetes.io/azure-dns-label-name パブリック IP 上の DNS ラベルの名前 パブリック サービスの DNS ラベル名を指定します。 空の文字列に設定すると、パブリック IP の DNS エントリは使用されません。
service.beta.kubernetes.io/azure-shared-securityrule true または false ネットワーク セキュリティ グループの Azure 拡張 セキュリティ規則を利用して、共有される可能性のある Azure セキュリティ規則を使用してサービスの公開を指定し、サービスの公開を増やします。
service.beta.kubernetes.io/azure-load-balancer-resource-group リソース グループの名前 クラスター インフラストラクチャと同一のリソース グループ (ノード リソース グループ) 内にないロード バランサーのパブリック IP のリソース グループを指定します。
service.beta.kubernetes.io/azure-allowed-service-tags 許可されるサービス タグの一覧 許可されるサービス タグをコンマで区切った一覧を指定します。
service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout TCP アイドル タイムアウト (分) ロード バランサーで TCP 接続のアイドル タイムアウトが発生するまでの時間を分数で指定します。 既定値は 4 で、これが最小値です。 最大値は 30 です。 この値は、整数にする必要があります。
service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset true または false ロード バランサーがアイドル タイムアウト時に TCP リセットを無効にするかどうかを指定します。
service.beta.kubernetes.io/azure-load-balancer-ipv4 IPv4 アドレス ロード バランサーに割り当てる IPv4 アドレスを指定します。
service.beta.kubernetes.io/azure-load-balancer-ipv6 IPv6 アドレス ロード バランサーに割り当てる IPv6 アドレスを指定します。

ロード バランサーの正常性プローブをカスタマイズする

Annotation 説明
service.beta.kubernetes.io/azure-load-balancer-health-probe-interval 正常性プローブの間隔
service.beta.kubernetes.io/azure-load-balancer-health-probe-num-of-probe 正常性プローブの異常な応答の最小数
service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path 正常性プローブの要求パス
service.beta.kubernetes.io/port_{port}_no_lb_rule true/false {port} はサービス ポート番号です。 true に設定すると、このポートの lb ルールまたは正常性プローブ ルールは生成されません。 正常性チェック サービスをパブリック インターネットに公開しないでください (例: istio/envoy 正常性チェック サービス)
service.beta.kubernetes.io/port_{port}_no_probe_rule true/false {port} はサービス ポート番号です。 true に設定すると、このポートの正常性プローブ規則は生成されません。
service.beta.kubernetes.io/port_{port}_health-probe_protocol 正常性プローブ プロトコル {port} はサービス ポート番号です。 サービス ポート {port} の正常性プローブのための明示的なプロトコル。設定されている場合は port.appProtocol をオーバーライドします。
service.beta.kubernetes.io/port_{port}_health-probe_port サービス マニフェスト内のポート番号またはポート名 {port} はサービス ポート番号です。 サービス ポート {port} の正常性プローブの明示的なポート。既定値をオーバーライドします。
service.beta.kubernetes.io/port_{port}_health-probe_interval 正常性プローブの間隔 {port} はサービス ポート番号です。
service.beta.kubernetes.io/port_{port}_health-probe_num-of-probe 正常性プローブの異常な応答の最小数 {port} はサービス ポート番号です。
service.beta.kubernetes.io/port_{port}_health-probe_request-path 正常性プローブの要求パス {port} はサービス ポート番号です。

こちらに記載されているように、ロード バランサー サービスがサポートするプロトコルは Tcp、Http、Https の 3 つです。

現在、正常性プローブの既定のプロトコルは、トランスポート プロトコル、アプリ プロトコル、注釈、外部トラフィック ポリシーが異なれば、サービスによって異なります。

  1. ローカル サービスの場合、HTTP と /healthz が使われます。 正常性プローブは、実際のバックエンド サービスではなく、NodeHealthPort に対してクエリを実行します
  2. クラスター TCP サービスの場合は、TCP が使われます。
  3. クラスター UDP サービスの場合、正常性プローブはありません。

Note

PLS 統合と PLS プロキシ プロトコルが有効なローカル サービスの場合、既定の HTTP+/healthz 正常性プローブは機能しません。 そのため、このシナリオをサポートするために、クラスター サービスと同じ方法で正常性プローブをカスタマイズできます。

v1.20 以降、正常性プローブの動作を決定するためにサービスの注釈 service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path が導入されました。

  • クラスター <=1.23 の場合、service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path も設定されている場合にのみ、spec.ports.appProtocol はプローブ プロトコルとして使われます。
  • クラスター >1.24 の場合、spec.ports.appProtocol がプローブ プロトコルとして使われ、/ が既定のプローブ要求パスとして使われます (service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path を使って別の要求パスに変更できます)。

TCP を使う場合または spec.ports.appProtocol が空の場合、要求パスは無視されることに注意してください。 具体的には次のとおりです。

loadbalancer sku externalTrafficPolicy spec.ports.Protocol spec.ports.AppProtocol service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path LB プローブ プロトコル LB プローブ要求パス
standard ローカル 任意 任意 任意 http /healthz
standard cluster udp 任意 任意 null null
standard cluster tcp (無視されます) tcp null
standard cluster tcp tcp (無視されます) tcp null
standard cluster tcp http/https TCP(<=1.23) または http/https(>=1.24) null(<=1.23) または /(>=1.24)
standard cluster tcp http/https /custom-path http/https /custom-path
standard cluster tcp サポートされていないプロトコル /custom-path tcp null
基本 ローカル 任意 任意 任意 http /healthz
基本 cluster tcp (無視されます) tcp null
基本 cluster tcp tcp (無視されます) tcp null
基本 cluster tcp http TCP(<=1.23) または http/https(>=1.24) null(<=1.23) または /(>=1.24)
基本 cluster tcp http /custom-path http /custom-path
基本 cluster tcp サポートされていないプロトコル /custom-path tcp null

v1.21 以降、正常性プローブの構成をカスタマイズする 2 つのサービス注釈 service.beta.kubernetes.io/azure-load-balancer-health-probe-intervalload-balancer-health-probe-num-of-probe が導入されました。 service.beta.kubernetes.io/azure-load-balancer-health-probe-interval が設定されていない場合、既定値の 5 が適用されます。 load-balancer-health-probe-num-of-probe が設定されていない場合、既定値の 2 が適用されます。 また、プローブの合計は 120 秒未満にする必要があります。

ポートのカスタムの Load Balancer 正常性プローブ

サービスのポートごとに、異なる正常性プローブ構成が必要になる場合があります。 これは、サービスの設計 (複数のポートを制御する単一の正常性エンドポイントなど) や Kubernetes の機能 (MixedProtocolLBService など) が理由である可能性があります。

次の注釈を使うと、サービス ポートごとのプローブ構成をカスタマイズできます。

ポート固有の注釈 グローバル プローブ注釈 使用法
service.beta.kubernetes.io/port_{port}_no_lb_rule N/A (グローバルに相当するものはありません) true に設定すると、LB ルールとプローブ ルールは生成されません
service.beta.kubernetes.io/port_{port}_no_probe_rule N/A (グローバルに相当するものはありません) true に設定すると、プローブ ルールは生成されません
service.beta.kubernetes.io/port_{port}_health-probe_protocol N/A (グローバルに相当するものはありません) このサービス ポートの正常性プローブ プロトコル (Http、Https、Tcp など) を設定します
service.beta.kubernetes.io/port_{port}_health-probe_port N/A (グローバルに相当するものはありません) このサービス ポートの正常性プローブ ポートを設定します (例: 15021)
service.beta.kubernetes.io/port_{port}_health-probe_request-path service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path Http または Https の場合は、正常性プローブ要求パスを設定します。 既定値は / です
service.beta.kubernetes.io/port_{port}_health-probe_num-of-probe service.beta.kubernetes.io/azure-load-balancer-health-probe-num-of-probe 超えた場合にポートを異常と見なすプローブの連続エラー回数
service.beta.kubernetes.io/port_{port}_health-probe_interval service.beta.kubernetes.io/azure-load-balancer-health-probe-interval プローブの試行の間隔

次のマニフェストでは、ポート httpsserver に注釈が指定されているため、ポート httpsserver に対するプローブ ルールは httpserver に対するものとは異なります。

apiVersion: v1
kind: Service
metadata:
  name: appservice
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-health-probe-num-of-probe: "5"
    service.beta.kubernetes.io/port_443_health-probe_num-of-probe: "4"
spec:
  type: LoadBalancer
  selector:
    app: server
  ports:
    - name: httpserver
      protocol: TCP
      port: 80
      targetPort: 30102
    - name: httpsserver
      protocol: TCP
      appProtocol: HTTPS
      port: 443
      targetPort: 30104

このマニフェストで、https ポートは別のノード ポートを使い、/healthz (kube-proxy の healthz エンドポイント) のポート 10256 で HTTP 準備チェックを行います。

apiVersion: v1
kind: Service
metadata:
  name: istio
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/port_443_health-probe_protocol: "http"
    service.beta.kubernetes.io/port_443_health-probe_port: "10256"
    service.beta.kubernetes.io/port_443_health-probe_request-path: "/healthz"
spec:
  ports:
    - name: https
      protocol: TCP
      port: 443
      targetPort: 8443
      nodePort: 30104
      appProtocol: https
  selector:
    app: istio-ingressgateway
    gateway: istio-ingressgateway
    istio: ingressgateway
  type: LoadBalancer
  sessionAffinity: None
  externalTrafficPolicy: Local
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  allocateLoadBalancerNodePorts: true
  internalTrafficPolicy: Cluster

このマニフェストで、https ポートは別の正常性プローブ エンドポイントを使い、/healthz/ready のポート 30000 で HTTP 正常性チェックを行います。

apiVersion: v1
kind: Service
metadata:
  name: istio
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/port_443_health-probe_protocol: "http"
    service.beta.kubernetes.io/port_443_health-probe_port: "30000"
    service.beta.kubernetes.io/port_443_health-probe_request-path: "/healthz/ready"
spec:
  ports:
    - name: https
      protocol: TCP
      port: 443
      targetPort: 8443
      appProtocol: https
  selector:
    app: istio-ingressgateway
    gateway: istio-ingressgateway
    istio: ingressgateway
  type: LoadBalancer
  sessionAffinity: None
  externalTrafficPolicy: Local
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  allocateLoadBalancerNodePorts: true
  internalTrafficPolicy: Cluster

SNAT のトラブルシューティング

同じ宛先 IP アドレスとポートに対して多数の TCP アウトバウンド接続または UDP アウトバウンド接続が開始されることがわかっている場合、送信接続エラーが発生する場合、または SNAT ポート (PAT によって使用される一時的なポート) が不足しているとサポートから知らされた場合、一般的な軽減策としていくつかの選択肢があります。 それらをよく吟味して、実際のシナリオに最適な選択肢を判断してください。 それらを 1 つまたは複数組み合わせることが状況改善に役立つ場合もあります。 詳細については、アウトバウンド接続のトラブルシューティング ガイドに関するページをご確認ください。

SNAT が枯渇する根本的な原因は、多くの場合、アウトバウンド接続の確立方法と管理方法、または構成可能なタイマーの既定値に対する変更のアンチパターンです。 このセクションの内容を慎重に検討してください。

手順

  1. 接続のアイドル状態が長時間続いているかどうか、および既定のアイドル タイムアウトに基づいてそのポートが解放されているかどうかを確認します。 そうである場合は、ご使用のシナリオのタイムアウト値を既定の 30 分より短くする必要があります。
  2. 対象のアプリケーションでアウトバウンド接続がどのようにつくられているかを調査しましょう (たとえば、コード レビューやパケット キャプチャ)。
  3. このアクティビティが予期される動作であるかどうか、またはアプリケーションが誤動作しているかどうかを判断します。 Azure Monitor でメトリックログを使用して、調査結果を実証します。 たとえば、SNAT 接続メトリックの "失敗" カテゴリを使用します。
  4. 適切なパターンに従っているかどうかを評価します。
  5. SNAT ポートの枯渇が、アウトバウンド IP アドレスを増やし、割り当てアウトバウンド ポート数を増やすことで軽減されるかどうかを評価します。

設計パターン

接続の再利用と接続プールを、可能な場合に利用してください。 これらのパターンは、リソース枯渇の問題を回避するのに役立ち、結果として予測可能な動作をもたらします。 これらのパターンのプリミティブは、多くの開発ライブラリとフレームワークに含まれています。

  • アトミック要求 (接続ごとに 1 つの要求) は、一般には設計の選択肢として適切ではありません。 そのようなアンチパターンにより規模が制限され、パフォーマンスと信頼性が低下します。 代わりに、HTTP/S 接続を再利用し、接続と関連付けられている SNAT ポートの数を減らします。 TLS を利用すると、ハンドシェイク、オーバーヘッド、暗号化操作による代償が減るため、アプリケーションのスケールとパフォーマンスが向上します。
  • クラスター外、またはカスタム DNS を使用している場合、または coreDNS 上でカスタム アップストリーム サーバーを使用している場合は、クライアントが DNS リゾルバーの結果をキャッシュしていないときに、DNS で大量の個別フローが発生する可能性があることにご注意ください。 カスタム DNS サーバーを使用する代わりに、まず coreDNS をカスタマイズして、適切なキャッシュ値を定義してください。
  • UDP フロー (DNS 参照など) によって、アイドル タイムアウト時に、SNAT ポートが割り当てられます。 アイドル時間が長くなると、SNAT ポートにかかる圧力がそれだけ高くなります。 短いアイドル タイムアウト (たとえば 4 分) を使用します。
  • 接続プールを使用し、接続ボリュームを形成します。
  • 警告なしで TCP フローを破棄し、TCP タイマーに依存してフローを消去することは決してしないでください。 TCP で明示的に接続を閉じなかった場合、中間システムとエンドポイントで状態が割り当てられたままになり、他の接続に SNAT ポートを利用できなくなります。 このパターンによって、アプリケーション エラーと SNAT 枯渇がトリガーされる可能性があります。
  • OS レベルの TCP 終了関連のタイマー値は、影響が専門的にわからない場合、変更しないでください。 TCP スタックの復旧中、接続のエンドポイントで期待値が一致しない場合、アプリケーションのパフォーマンスが低下する可能性があります。 タイマーの変更が必要になる場合、通常、基になる設計に問題があることを示しています。 次の推奨事項をご確認ください。

ロード バランサーを Basic SKU から Standard SKU に移行する

既存のクラスターに Basic SKU ロード バランサーが与えられている場合、Standard SKU ロード バランサーへ移行するときに注意すべき重大な違いがあります。

たとえば、クラスターを移行するための blue/green デプロイの作成は、load-balancer-sku のタイプのクラスターを考えると一般的な方法であり、クラスターの作成時にのみ定義することが可能です。 ただし、Basic SKU ロード バランサーは Basic SKU IP アドレスを使用し、Standard SKU ロード バランサーと互換性がありません。 Standard SKU ロード バランサーには Standard SKU IP アドレスが必要です。 ロード バランサー SKU をアップグレードするためにクラスターを移行するとき、互換性のある IP アドレス SKU を持つ新しい IP アドレスが必要となります。

クラスターの移行方法に関して他に注意すべき事項については、移行時の考慮事項に関するドキュメントを参照してください。

制限事項

Standard SKU を使用するロード バランサーをサポートする AKS クラスターを作成し、管理する場合、次の制限が適用されます。

  • AKS クラスターからのエグレス トラフィックを許可するために、パブリック IP または IP プレフィックスが少なくとも 1 つ必要です。 パブリック IP または IP プレフィックスは、コントロール プレーンとエージェント ノードの間の接続を維持し、前のバージョンの AKS との互換性を維持するために必要です。 Standard SKU ロード バランサーでパブリック IP または IP プレフィックスを指定するための次のオプションがあります:
    • 独自のパブリック IP を指定する。
    • 独自のパブリック IP プレフィックスを指定する。
    • 最大 100 までの数字を指定し、それだけの数の Standard SKU パブリック IP を、AKS クラスターと同じリソース グループで作成することを AKS クラスターに許可します。 このリソース グループは、通常、名前の先頭に MC_ が付いています。 AKS により、パブリック IP が Standard SKU ロード バランサーに割り当てられます。 既定では、パブリック IP、パブリック IP プレフィックス、または IP の数が指定されていない場合、同じリソース グループでパブリック IP が 1 つ自動的に作成されます。 また、パブリック アドレスを許可する必要があり、IP 作成を禁止する Azure ポリシーは作成しないようにする必要があります。
  • AKS によって作成されるパブリック IP は、独自のカスタム パブリック IP アドレスとして再使用することはできません。 ユーザーはすべてのカスタム IP アドレスを作成および管理する必要があります。
  • ロード バランサー SKU は、AKS クラスターの作成時にのみ定義できます。 AKS クラスターが作成された後にロード バランサー SKU を変更することはできません。
  • 1 つのクラスターで使用できるロード バランサー SKU (Basic または Standard) の種類は 1 つのみです。
  • Standard SKU ロード バランサーでは、Standard SKU IP アドレスのみがサポートされています。

次のステップ

Kubernetes サービスについて学習するには、Kubernetes サービスのドキュメントを参照してください。

内部ロード バランサーをインバウンド トラフィックで使用する方法の詳細については、AKS の内部ロード バランサーに関するドキュメントを参照してください。