在 Azure Kubernetes Service (AKS) 中使用執行個體層級的公共 IP

AKS 節點不需要各自擁有公共 IP 位址即可進行通訊。 不過,某些情境可能需要節點集區中的節點取得各自專用的公共 IP 位址。 常見情境之一是遊戲工作負載,其中主控台需要直接連線至雲端虛擬機器,以將躍點數降到最低。 此情境可透過在 AKS 中使用節點公共 IP 來達成。

首先,建立新的資源群組。

az group create --name <resourceGroup> --location <region>

建立新的 AKS 叢集,並為您的節點附加公共 IP。 節點集區中的每個節點都會收到一個唯一的公共 IP。 您可以透過查看虛擬機器擴展集的執行個體來驗證這一點。

az aks create \
    --resource-group <resourceGroup> \
    --name <aksClusterName> \
    --location <region> \
    --enable-node-public-ip \
    --generate-ssh-keys

對於現有的 AKS 叢集,您也可以新增節點集區,並為節點附加公共 IP。

az aks nodepool add --resource-group <resourceGroup> --cluster-name <aksClusterName> --name <newNodePool> --enable-node-public-ip

使用公共 IP 首碼

使用公共 IP 首碼具有多項優點。 AKS 支援在建立新叢集或新增節點集區時,透過 --node-public-ip-prefix-id 旗標傳遞資源 ID,讓節點使用現有公共 IP 首碼中的位址。

首先,使用 az network public-ip prefix create 建立公共 IP 首碼:

az network public-ip prefix create --length 28 --location <region> --name <publicIPPrefixName> --resource-group <resourceGroup>

檢視輸出,並記下首碼的 id

{
  ...
  "id": "/subscriptions/<subscription-id>/resourceGroups/<resourceGroup>/providers/Microsoft.Network/publicIPPrefixes/<publicIPPrefixName>",
  ...
}

最後,在建立新叢集或新增節點集區時,使用--node-public-ip-prefix-id 旗標並傳入首碼的資源 ID:

az aks create \
    --resource-group <resourceGroup> \
    --name <aksClusterName> \
    --location <region> \
    --enable-node-public-ip \
    --node-public-ip-prefix-id /subscriptions/<subscription-id>/resourceGroups/<resourceGroup>/providers/Microsoft.Network/publicIPPrefixes/<publicIPPrefixName> \
    --generate-ssh-keys

使用雙堆疊公用 IP 前綴(預覽)

你可以透過使用雙堆疊公共 IP 前綴,為節點池中的每個節點指派 IPv4 和 IPv6 公共 IP 位址。 這種方式允許你自帶公共 IP 前綴,並確保每個節點分別接收一個 IPv4 位址和一個 IPv6 位址。

此功能對於需要透過 IPv4 與 IPv6 直接進出連接的工作負載,或在需要 IPv6 相容性的環境中運作的應用程式非常有用。

重要事項

AKS 預覽功能採自助式、需自行選擇啟用的方式提供。 預覽版會以「現狀」和「可供使用時」提供,不受服務等級協定和有限瑕疵擔保所保護。 AKS 預覽版的部分功能由客戶支援部門盡力提供部分支援。 因此,這些功能不適合生產使用。 如需詳細資訊,請參閱下列支援文章:

需求

若要使用雙堆疊公共 IP 前綴搭配節點公共 IP,請確保符合以下先決條件:

  • 你的叢集被設定為雙堆疊叢集,同時支援 IPv4 和 IPv6 IP 家族。
  • 您的叢集使用 Azure CNI 搭配覆疊網路。
  • 你有一個 IPv4 公共 IP 前綴和一個 IPv6 公共 IP 前綴,都是在你的 AKS 叢集所在的區域內建立的。
  • 這兩個公共 IP 前綴皆使用標準 SKU。
  • AKS 叢集身份擁有管理公共 IP 前綴的權限。 如果前綴屬於不同的資源群組,請將該資源群組的網路貢獻者角色指派到叢集識別碼中。

註冊預覽功能

節點公共 IP 的雙重堆疊 (IPv4 和 IPv6) 公共 IP 前綴支援目前已提供預覽版。 在使用此功能之前,您必須安裝或更新 Azure CLI 擴充套件,並在訂閱中註冊NodePublicIPv6PrefixPreview功能標誌。

安裝或更新 aks-preview 擴充功能:

az extension add --name aks-preview --upgrade

註冊所需的預覽功能:

az feature register --namespace Microsoft.ContainerService --name NodePublicIPv6PrefixPreview

功能註冊可能需要數分鐘才能完成。 要查詢註冊狀態,請執行:

az feature show --namespace Microsoft.ContainerService --name NodePublicIPv6PrefixPreview --query "properties.state"

等兩個功能都顯示已註冊狀態後再繼續。

註冊功能旗標後,請重新整理資源提供者,以確保套用變更:

az provider register --namespace Microsoft.ContainerService

註冊完成後,你可以建立或更新叢集,使用雙堆疊公共 IP 前綴來設定節點的公共 IP。

建立公共 IP 前綴

使用 Azure CLI 建立 IPv4 和 IPv6 的公開 IP 前綴。

針對 IPv4:

az network public-ip prefix create \
  --resource-group <resourceGroup> \
  --name <ipv4PrefixName> \
  --location <region> \
  --length 28 \
  --sku Standard \
  --version IPv4

針對 IPv6:

az network public-ip prefix create \
  --resource-group <resourceGroup> \
  --name <ipv6PrefixName> \
  --location <region> \
  --length 124 \
  --sku Standard \
  --version IPv6

建立前綴後,注意兩個前綴的資源 ID。

建立一個帶有雙堆疊節點公有 IP 前綴的新叢集

建立新的 AKS 叢集時,請使用 --node-public-ip-prefix-ids 參數指定 IPv4 和 IPv6 的公共 IP 前綴。

az aks create \
  --resource-group <resourceGroup> \
  --name <aksClusterName> \
  --location <region> \
  --enable-node-public-ip \
  --ip-families IPv4,IPv6 \
  --network-plugin azure \
  --network-plugin-mode overlay \
  --node-public-ip-prefix-ids "<ipv4PrefixResourceId>,<ipv6PrefixResourceId>" \
  --generate-ssh-keys

--node-public-ip-prefix-ids 參數接受以逗號分隔的公共 IP 前綴資源 ID 清單。 清單必須包含一個 IPv4 前綴和一個 IPv6 前綴。

新增一個帶有雙堆疊節點公共 IP 前綴的節點池

你也可以在現有的雙堆疊叢集中加入帶有雙堆疊節點公有 IP 前綴的節點池。

az aks nodepool add \
  --resource-group <resourceGroup> \
  --cluster-name <aksClusterName> \
  --name <nodePoolName> \
  --enable-node-public-ip \
  --node-public-ip-prefix-ids "<ipv4PrefixResourceId>,<ipv6PrefixResourceId>"

Limitations

雙堆疊公用 IP 前綴有以下限制:

  • 你必須同時提供 IPv4 和 IPv6 前綴。 不支援僅限 IPv6 的設定。
  • 節點的公共 IP 設定是不可變的。 要更改公共 IP 前綴,你必須建立新的節點池並遷移工作負載。
  • 每個節點會被分配一個單一的 IPv6 公共 IP 位址。
  • 此功能不支援 AKS 自動配置或節點自動配置。
  • 不支援多網卡節點池。
  • 支援叢集自動擴展器,但請確保設定的最大節點數不會超過公共 IP 前綴的可用 IP 位址數量,因為每個節點需要從前綴中取得一個 IP。

尋找節點的公共 IP

您可以透過多種方式找到節點的公共 IP:

重要事項

節點資源群組包含節點及其公共 IP。 在執行命令以尋找節點公共 IP 時,請使用節點資源群組。

az vmss list-instance-public-ips --resource-group <MC_region_aksClusterName_region> --name <virtualMachineScaleSetName>

在節點公共 IP 上使用公共 IP 標記

公共 IP 標籤可用於節點的公共 IP 上,以利用 Azure 路由偏好功能 ,該功能在 指定區域內可用。

需求

  • 需要 AKS 版本 1.29 或更新版本。

使用路由喜好設定 internet 建立新叢集

az aks create \
    --name <aksClusterName> \
    --location <region> \
    --resource-group <resourceGroup> \
    --enable-node-public-ip \
    --node-public-ip-tags RoutingPreference=Internet \
    --generate-ssh-keys

新增具有路由喜好設定 internet 的節點集區

az aks nodepool add --cluster-name <aksClusterName> \
  --name <nodePoolName> \
  --location <region> \
  --resource-group <resourceGroup> \
  --enable-node-public-ip \
  --node-public-ip-tags RoutingPreference=Internet

允許主機連接埠連線,並將節點集區新增至應用程式安全性群組

使用節點公共 IP 並在其主機位址上裝載服務的 AKS 節點,需要新增 NSG 規則以允許流量。 在節點集區組態中新增所需的連接埠,會在叢集網路安全性群組中建立對應的允許規則。

如果使用自備虛擬網路的叢集,其子網路上已套用網路安全性群組,則必須在該網路安全性群組中新增允許規則。 您可以將節點集區新增至應用程式安全性群組 (ASG),以將規則限制在特定節點集區。 若已指定允許的主機連接埠,系統會在受控資源群組中預設建立受控 ASG。 也可以在節點集區參數中指定 NSG 的資源 ID,將節點新增至一或多個自訂 ASG。

主機連接埠規格格式

指定要允許的連接埠清單時,請使用以逗號分隔的清單,項目格式為 port/protocolstartPort-endPort/protocol

範例:

  • 80/tcp
  • 80/tcp,443/tcp
  • 53/udp,80/tcp
  • 50000-60000/tcp

需求

  • 需要 AKS 版本 1.29 或更新版本。

建立包含允許連接埠與應用程式安全性群組的新叢集

az aks create \
    --resource-group <resourceGroup> \
    --name <aksClusterName> \
    --nodepool-name <nodePoolName> \
    --nodepool-allowed-host-ports 80/tcp,443/tcp,53/udp,40000-60000/tcp,40000-50000/udp\
    --nodepool-asg-ids "<asgId>,<asgId>" \
    --generate-ssh-keys

新增包含允許連接埠與應用程式安全性群組的節點集區

az aks nodepool add \
  --resource-group <resourceGroup> \
  --cluster-name <aksClusterName> \
  --name <nodePoolName> \
  --allowed-host-ports 80/tcp,443/tcp,53/udp,40000-60000/tcp,40000-50000/udp \
  --asg-ids "<asgId>,<asgId>"

更新節點集區的允許連接埠與應用程式安全性群組

az aks nodepool update \
  --resource-group <resourceGroup> \
  --cluster-name <aksClusterName> \
  --name <nodePoolName> \
  --allowed-host-ports 80/tcp,443/tcp,53/udp,40000-60000/tcp,40000-50000/udp \
  --asg-ids "<asgId>,<asgId>"

為 Pod 工作負載自動指派主機連接埠 (預覽版)

當節點上已設定公共 IP 時,可以使用主機連接埠,讓 Pod 直接接收流量,而無須設定負載平衡器服務。 這在遊戲等情境中特別實用,因為節點 IP 與連接埠具有暫時性的特性並不會造成問題,配對服務可在連線時,透過已知的主機名稱提供正確的主機與連接埠。 不過,由於在同一主機上只能有一個程序接聽相同的連接埠,使用主機連接埠的應用程式可能會導致排程問題。 為避免此問題,AKS 提供在排程時由系統動態指派可用連接埠的能力,以防止衝突。

警告

Pod 主機連接埠流量會受到叢集中預設 NSG 規則的封鎖。 此功能應搭配在節點集區上允許主機連接埠使用,才能讓流量順利通過。

重要事項

AKS 預覽功能採自助式、需自行選擇啟用的方式提供。 預覽版會以「現狀」和「可供使用時」提供,不受服務等級協定和有限瑕疵擔保所保護。 AKS 預覽版的部分功能由客戶支援部門盡力提供部分支援。 因此,這些功能不適合生產使用。 如需詳細資訊,請參閱下列支援文章:

需求

  • 需要 AKS 版本 1.29 或更新版本。

註冊 PodHostPortAutoAssignPreview 功能旗標

使用 PodHostPortAutoAssignPreview 命令註冊 功能旗標,如下列範例所示:

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

該狀態需要幾分鐘的時間才會顯示已註冊。 使用 az feature show 命令驗證註冊狀態:

az feature show --namespace "Microsoft.ContainerService" --name "PodHostPortAutoAssignPreview"

當狀態顯示為已註冊 時,請使用 az provider register 命令重新整理 Microsoft.ContainerService 資源提供者的註冊:

az provider register --namespace Microsoft.ContainerService

自動為 Pod 指派主機連接埠

觸發主機連接埠自動指派的方式,是部署未指定任何主機連接埠的工作負載,並套用 kubernetes.azure.com/assign-hostports-for-containerports 註解,同時提供需要指派主機連接埠的連接埠清單。 註解的值應指定為以逗號分隔的清單,項目格式如 port/protocol,其中連接埠為 Pod 規格中定義的個別連接埠號碼,通訊協定為 tcpudp

系統會從 40000-59999 的範圍指派連接埠,且在整個叢集中保持唯一。 指派的連接埠也會新增至 Pod 內的環境變數,讓應用程式能判斷實際指派的連接埠。 環境變數名稱格式如下 (以下為範例):<deployment name>_PORT_<port number>_<protocol>_HOSTPORT,例如 mydeployment_PORT_8080_TCP_HOSTPORT: 41932

以下為 echoserver 部署的範例,顯示 8080 與 8443 連接埠的主機連接埠對應:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver-hostport
  labels:
    app: echoserver-hostport
spec:
  replicas: 3
  selector:
    matchLabels:
      app: echoserver-hostport
  template:
    metadata:
      annotations:
        kubernetes.azure.com/assign-hostports-for-containerports: 8080/tcp,8443/tcp
      labels:
        app: echoserver-hostport
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: echoserver-hostport
          image: k8s.gcr.io/echoserver:1.10
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
            - name: https
              containerPort: 8443
              protocol: TCP

套用部署後,hostPort 項目會出現在各個 Pod 的 YAML 中:

$ kubectl describe pod echoserver-hostport-75dc8d8855-4gjfc
<cut for brevity>
Containers:
  echoserver-hostport:
    Container ID:   containerd://d0b75198afe0612091f412ee7cf7473f26c80660143a96b459b3e699ebaee54c
    Image:          k8s.gcr.io/echoserver:1.10
    Image ID:       k8s.gcr.io/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229                                                                                                      Ports:          8080/TCP, 8443/TCP
    Host Ports:     46645/TCP, 49482/TCP
    State:          Running
      Started:      Thu, 12 Jan 2023 18:02:50 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      echoserver-hostport_PORT_8443_TCP_HOSTPORT:  49482
      echoserver-hostport_PORT_8080_TCP_HOSTPORT:  46645

後續步驟