Young Leaves

Azure Basion 経由でプライベートなAzure Kubernetes Service クラスターに接続する

今回は2025年8月6日にパブリックプレビューとなったAzure Bastion を使ったプライベートなAzure Kubernetes Service (以下AKS) クラスターへの接続機能について説明します。本機能は2025年8月現在でパブリックプレビュー機能のため、今後のアップデートにより仕様や設定方法がされる場合もあります。

実施環境

Azure CLI

2.75.0

Kubernetes (AKS)

1.32.6

前提条件

  • Azure CLI のインストールおよび拡張機能の aks-preview がインストールされていること
  • ローカルPC で kubectl コマンドを実行できること

Azure Bastion とAKS の統合

2025年8月6日のAzure Updates でAzure Bastion を経由したプライベートなAKS クラスターへ接続できる機能がパブリックプレビューとなりました。

Public Preview : Azure Bastion integration with AKS

この機能を利用することで、Azure Bastion 経由で閉域網のAKS に接続できるため、VPN やKubernetes 操作用の踏み台サーバーが不要となります。既に他のシステムでAzure Bastion を利用している場合、接続先をAzure Bastion 経由にまとめることもできます。Azure Bastion にトンネリングを行うため、AKS クラスター接続時のアクティビティログで誰がいつトンネリングして接続したか、をAzure Bastion でまとめることもできます。

今回の構成

今回は仮想ネットワーク内にプライベートなAKS クラスターとAzure Bastion を作成し、Azure Bastion 経由で kubectl コマンドを実行できるようにします。

リソースグループ、プライベートAKS クラスターの作成

初めにリソースグループとプライベートなAKS クラスターを作成します。Bastion のAKS 統合はパブリック FQDN が無効の AKS クラスターをサポートしていないため注意してください。

# リソースグループを作成する
az group create --name rg-privakstest --location japaneast

# 仮想ネットワークとサブネットの作成
# AKSとBastionで利用するサブネットを作成する
az network vnet create \
    --resource-group rg-privakstest \
    --name vnet-privakstest \
    --address-prefix 10.0.0.0/16 \
    --subnet-name snet-aks \
    --subnet-prefix 10.0.1.0/24

az network vnet subnet create \
    --resource-group rg-privakstest \
    --vnet-name vnet-privakstest \
    --name AzureBastionSubnet \
    --address-prefix 10.0.2.0/26

# プライベートのAKSクラスターを作成する
az aks create \
    --resource-group rg-privakstest \
    --name aks-privakstest \
    --node-count 1 \
    --load-balancer-sku standard \
    --enable-private-cluster \
    --network-plugin azure \
    --vnet-subnet-id $(az network vnet subnet show --resource-group rg-privakstest --vnet-name vnet-privakstest --name snet-aks --query id -o tsv | tr -d '\r') \
    --dns-service-ip 10.2.0.10 \
    --service-cidr 10.2.0.0/24 \
    --generate-ssh-keys

この状態でAKS 接続用の資格情報を取得し、ローカルPC からクラスターに接続しようとするとエラーとなります。

# AKS接続用の資格情報を取得する
az aks get-credentials --resource-group rg-privakstest --name aks-privakstest

# AKSのノード情報を確認する
kubectl get nodes
E0810 17:00:53.346747    1209 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io:443/api?timeout=32s\": dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host"
E0810 17:00:53.422087    1209 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io:443/api?timeout=32s\": dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host"
E0810 17:00:53.503976    1209 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io:443/api?timeout=32s\": dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host"
E0810 17:00:53.569485    1209 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io:443/api?timeout=32s\": dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host"
E0810 17:00:53.583456    1209 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io:443/api?timeout=32s\": dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host"
Unable to connect to the server: dial tcp: lookup aks-privak-rg-privakstest-0e2e47-5lj5q4xd.b9191ca4-b92d-4a24-a990-11480b660f47.privatelink.japaneast.azmk8s.io on 10.255.255.254:53: no such host

Azure Bastion の作成

プライベートなAKS クラスターに接続できないことを確認できましたら、今回追加した機能を試すためにAzure Bastion を作成します。

# パブリックIPアドレスを作成する
az network public-ip create \
    --resource-group rg-privakstest \
    --name pip-privakstest \
    --sku Standard \
    --location japaneast \
    --allocation-method Static

# Azure Bastion の作成
# BastionのAKS統合はStandard SKU以上が必要なためStandardで実施する
az network bastion create \
    --name bas-privakstest \
    --resource-group rg-privakstest \
    --vnet-name vnet-privakstest \
    --public-ip-address pip-privakstest \
    --location japaneast \
    --sku Standard

Azure Bastion 作成後、Azure Portal から対象のBastion を選択し、「Settings > Configuration」からNative Client Support を有効化します。Azure CLI ではNative Client Support を有効化するオプションが現時点でないため、Azure Portal から設定またはAzure Portal でBastion 作成時に設定する必要があります。

AKS クラスターへのトンネリングを作成、動作確認

Azure Bastion の準備後、AKS クラスターへのトンネリングを作成します。トンネリングを行うにはAzure Bastion へのRead 権限が必要となるため、Read 権限がない場合は対象ユーザーに権限を付与してください。

# Azure BastionからAKSクラスターへのトンネリングを作成する
# Bastionのportが表示されるためメモする
az aks bastion \
    --resource-group rg-privakstest \
    --name aks-privakstest \
    --bastion $(az network bastion show --resource-group rg-privakstest --name bas-privakstest --query id -o tsv | tr -d '\r') \
    --port 50001 \
    --admin 

# Bastion経由でプライベートなAKSにコマンドを実行する
# localhostのportはトンネリングで設定したportを指定する
kubectl get nodes --server=https://localhost:50001

実行すると、プライベートなAKS クラスターのNode 情報が取得できています。

kdkwakaba@TEST-PC:~$ kubectl get nodes --server=https://localhost:50001
NAME                                STATUS   ROLES    AGE   VERSION
aks-nodepool1-14465271-vmss000000   Ready    <none>   87m   v1.32.6

kubectl のserver オプションを毎回入力するのが面倒な場合は、.kube/config に記載されたAKS の資格情報にサーバーの https://localhost:50001 を設定することでオプションを省略できます。

Run command との違い

AKS にはクラスターに対しコマンドを実行できる Run command 機能があります。この機能を利用するとプライベートなAKS クラスターでもコマンドを実行することができます。ただし、Run command には以下の制約があります。

  • Run command を実行するにはAzure Portal への接続またはAzure CLI かPowerShell のコマンド作成が必要となる
  • Run command はコマンドの実行ごとにPod を作成するため長期間の操作に向かない
  • Run command で作成されるPod はCPU 500m、メモリ1Gi のため負荷の高い操作に向かない
  • API 出力の最大は512KB のため、出力結果の多い場合に実行結果の一部が正常に表示されないこともある

一時的なコマンドの実行やスクリプトを流したい時にはRun command でもよいですが、長時間作業を行いたいなど条件の必要な場合にはAzure Bastion のAKS 統合を利用するのも一つです。

Azure Bastion のコストについて

Azure Bastion のAKS 統合を利用するにはStandard SKU 以上が必要となります。小規模のAKS 単体みたいなケースだとAzure Bastion を常時配置することで料金が高くなるため、複数のシステムでAzure Bastion を利用しているケースでAKS も併せて接続させたい、みたいなユースケースでの利用でコストを抑えましょう。

リソースのクリーンアップ

動作確認後、リソースをクリーンアップします。

# リソースグループを削除する
az group delete --name rg-privakstest

まとめ

  • Azure Bastion のAKS 統合はAzure Bastion のNative Client Support 機能を使い、Bastion 経由でプライベートなAKS クラスターに接続できる
  • Azure Bastion のNative Client Support 機能を利用するため、Standard SKU 以上が必要
  • 一時的なコマンド実行であればRun command 機能もあるが、長時間の作業や負荷の高い作業で利用するのは一つ
  • Azure Bastion でVM 接続からAKS クラスター接続までまとめるとコストを抑えられる

参考資料