APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Application Gateway for Containersがプレビュー公開されました

はじめに

こんにちは、ACS事業部の吉川です。

Azure Kubernetes Service(AKS)でIngressを使いたいとき、皆さんはどんなIngress Controllerをお使いでしょうか?
Ingress NGINX ControllerApplication Gateway Ingress Controller?それとも、Istio
このたび新たな選択肢として、Application Gateway for Containers というものがプレビュー公開されましたのでご紹介したいと思います。

azure.microsoft.com

AGICの問題点

以前より、AzureのL7ロードバランサーサービスであるApplication GatewayをAKSのIngressとして利用する Application Gateway Ingress Controller(AGIC) が公式のアドオンとして公開されています。
しかし、AGICにはいくつか問題があり、最たるものとしては Podの状態更新がApplication Gatewayに伝達されるまでに長い時間がかかる、というものです。GitHub上の以下のIssueにて意見が交わされています。

github.com

冒頭挙げたApplication Gateway for Containersのプレビューのお知らせサイト内に、Achieve near-to-real-time convergence times to reflect add/remove of pods, routes, probes, and other load balancing configuration within Kubernetes yaml configuration. と記載があることから、この問題を解消する新たなアーキテクチャとなったことが期待できます。

構成

公式ドキュメントに構成の簡単な概要図がありましたので引用します。

引用元: What is Application Gateway for Containers? (preview)

AKSクラスター内に ALBコントローラー というものをデプロイし、それがIngress/Gateway APIを通じてApplication Gateway for Containersの実体をコントロールする、という構成のようです。
アイコンを見て察する方もいるかもしれませんが、従来の Application Gatewayとは全くの別物 です。

試してみる

まずはAKSを作成しましょう。
Application Gateway for Containers(長いので以下AGfCと表現します)ではAzure ADワークロードIDが必須なので、それ用のオプションを追加しています。Azure ADワークロードIDについては以下を参照ください。

techblog.ap-com.co.jp

また、現時点ではAGfCは限られたリージョンでのみプレビュー公開されています。残念ながら日本リージョンには対応していないため、ここではEast USリージョンで作成しています。

# リソース名/リージョンの定義
RG_NAME="rg-sample"
VNET_NAME="vnet-sample"
AKS_SNET_NAME="snet-aks"
AKS_NAME="aks-sample"
LOCATION="eastus"

# リソースグループ作成
az group create --location $LOCATION --name $RG_NAME

# VNet/サブネットの作成
az network vnet create -n $VNET_NAME -g $RG_NAME -l $LOCATION \
  --address-prefixes 192.168.0.0/16
az network vnet subnet create -n $AKS_SNET_NAME \
  --vnet-name $VNET_NAME -g $RG_NAME \
  --address-prefixes 192.168.0.0/24

# AKSクラスター作成
AKS_SUBNET_ID=$(az network vnet subnet show -n $AKS_SNET_NAME \
  --vnet-name $VNET_NAME -g $RG_NAME --query id -o tsv)
az aks create -g $RG_NAME -n $AKS_NAME -l $LOCATION \
  --enable-oidc-issuer --enable-workload-identity \
  --node-count 1 --network-plugin azure --vnet-subnet-id $AKS_SUBNET_ID

# kubectlのインストール
sudo az aks install-cli

# AKSの認証情報取得
az aks get-credentials -g $RG_NAME -n $AKS_NAME

次に、ALBコントローラーが使用するマネージドIDを作成します。このマネージドIDはどこに作っても構わないと思いますが、AKSクラスターを作った際にできる MC_ で始まる名前のリソースグループ内に作成しています。

# リソース名の定義
MANAGED_ID_NAME="azure-alb-identity"

# MC_リソースグループ情報の取得
AKS_RG_NAME=$(az aks show --resource-group $RG_NAME --name $AKS_NAME --query "nodeResourceGroup" -o tsv)
AKS_RG_ID=$(az group show --name $AKS_RG_NAME --query id -o tsv)

# マネージドID作成
az identity create --resource-group $AKS_RG_NAME --name $MANAGED_ID_NAME

# マネージドIDにMC_リソースグループの閲覧者ロールを割り当て
sleep 60
MANAGED_ID_PID=$(az identity show -g $AKS_RG_NAME -n $MANAGED_ID_NAME --query principalId -o tsv)
az role assignment create --assignee-object-id $MANAGED_ID_PID --assignee-principal-type ServicePrincipal \
  --scope $AKS_RG_ID --role "acdd72a7-3385-48ef-bd42-f606fba81ae7"

作成したマネージドIDにワークロードIDのフェデレーション設定を行います。

AKS_OIDC_ISSUER="$(az aks show -n $AKS_NAME -g $RG_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
az identity federated-credential create --name "azure-alb-identity" \
     --identity-name $MANAGED_ID_NAME \
     --resource-group $AKS_RG_NAME \
     --issuer $AKS_OIDC_ISSUER \
     --subject "system:serviceaccount:azure-alb-system:alb-controller-sa"

Helmを使って、AKSクラスターに ALBコントローラー をデプロイします。

MANAGED_ID_CID=$(az identity show -g $AKS_RG_NAME -n $MANAGED_ID_NAME --query clientId -o tsv)
helm install alb-controller oci://mcr.microsoft.com/application-lb/charts/alb-controller \
      --version 0.4.023961 \
      --set albController.podIdentity.clientID=$MANAGED_ID_CID

ALBコントローラーは azure-alb-system という名前空間にデプロイされます。Podが2種類デプロイされるので、READYになったことを確認しましょう。

$ kubectl get pods -n azure-alb-system
NAME                                        READY   STATUS    RESTARTS   AGE
alb-controller-6f58b647cb-rpp7n             1/1     Running   0          7m40s
alb-controller-bootstrap-5f8c757676-ctpmk   1/1     Running   0          7m40s

続いて、AGfC および フロントエンド を作成します。このフロントエンドが実際の接続を受け付けるインスタンスの定義のようです。外部からのアクセスを受け付けるためのFQDNもフロントエンドに紐づきます。

なお、このAGfCとフロントエンドの作成については、ALBコントローラーに動的に作成させるというオプションもあります。

learn.microsoft.com

今回は事前に作成したAGfCリソースを利用する Bring Your Ownデプロイ の手順で進めます。

learn.microsoft.com

# CLI拡張機能の有効化
az extension add --name alb

# リソース名の定義
AGFC_NAME="alb-sample"
AGFC_FRONTEND_NAME="frontend-sample"

az network alb create -g $RG_NAME -n $AGFC_NAME
az network alb frontend create -g $RG_NAME -n $AGFC_FRONTEND_NAME --alb-name $AGFC_NAME

作成したAGfCのフロントエンドとサブネットを紐づけます。

# リソース名の定義
AGFC_SNET_NAME="snet-agfc"
ASSOCIATION_NAME="association-sample"

# サブネットの作成
az network vnet subnet create -n $AGFC_SNET_NAME \
  --vnet-name $VNET_NAME -g $RG_NAME \
  --address-prefixes 192.168.1.0/24

# サブネットの委任
az network vnet subnet update -n $AGFC_SNET_NAME \
  --vnet-name $VNET_NAME -g $RG_NAME \
  --delegations 'Microsoft.ServiceNetworking/trafficControllers'
AGFC_SNET_ID=$(az network vnet subnet show -n $AGFC_SNET_NAME \
  --vnet-name $VNET_NAME -g $RG_NAME --query id -o tsv)

# サブネットの紐づけ
az network alb association create -g $RG_NAME -n $AGFC_FRONTEND_NAME \
  --alb-name $AGFC_NAME --subnet $AGFC_SNET_ID

ALBコントローラーのマネージドIDに必要なロールを割り当てます。

# AGfCが存在するリソースグループの「Azure Traffic Controller Configuration Manager」ロールを割り当て
RG_ID=$(az group show --name $RG_NAME --query id -o tsv)
az role assignment create --assignee-object-id $MANAGED_ID_PID --assignee-principal-type ServicePrincipal \
  --scope $RG_ID --role "fbc52c3f-28ad-4303-a892-8a056630b8f1" 

# AGfC用サブネットのネットワーク共同作成者ロールを割り当て
az role assignment create --assignee-object-id $MANAGED_ID_PID --assignee-principal-type ServicePrincipal \
  --scope $AGFC_SNET_ID --role "4d97b98b-1d4f-4787-a291-c67834d212e7"

これでAGfCを利用するための設定は完了です。
ポータルからリソースの状態が以下のように確認できるので参考にしてみてください。

フロントエンドの設定を見ると、hoge.fuga.alb.azure.com というFQDNが払い出されていることが確認できます。

サブネットの接続デバイスを見ると、tcgw というインスタンスがいくつか接続されているのが確認できます。

Ingressとして使用する

前項までの設定でAGfCをIngressとして利用できるようになりました。早速試してみましょう。

テスト用にnginxのDeploymentを起動しておきます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: nginx
kubectl apply -f nginx-deployment.yaml

続いてIngressを作成します。
マニフェストのアノテーションに

  • AGfC のリソースID
  • AGfC のフロントエンド名 (今回の例だと frontend-sample

を設定する必要があります。リソースIDは以下のコマンドで確認しておきましょう。

az network alb show -g $RG_NAME -n $AGFC_NAME --query id -o tsv

確認した値を使ってマニフェストを作成してデプロイします。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-sample
  annotations:
    alb.networking.azure.io/alb-id: <AGfCのリソースID>
    alb.networking.azure.io/alb-frontend: <フロントエンド名>
spec:
  ingressClassName: azure-alb-external
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
kubectl apply -f ingress.yaml

これでIngressの状態を見ると、ADDRESSの欄にポータルで確認したFQDNが表示されていることが確認できます。

kubectl get ing
NAME             CLASS                HOSTS   ADDRESS               PORTS   AGE
ingress-sample   azure-alb-external   *       hoge.fuga.azure.com   80      82s

このFQDNにアクセスすると、デプロイしたnginxのデフォルトページに繋がります。

Ingressとして使えることが確認できましたね。
手元に適当な証明書・ドメインがなかったため確認できていないですが、公式ドキュメントを見る限りTLSの終端も問題なくできそうです。

learn.microsoft.com

おわりに

今後が期待できそうな新サービス、Application Gateway for Containersのご紹介でした。
従来のAGICはApplication GatewayをAKSからコントロールする機構でしたが、AGfCはKubernetes用に用意された独自のリソースが作成される構成のようです。AKSから利用することだけ考えればAGfCのほうがシンプルで使いやすそうなので、今後のGAを楽しみに待ちたいと思います。

また、AGfCはIngressだけでなく、Gateway APIにも対応しているようなのですが、そちらはまた別の機会にご紹介できればと思います。

【PR】
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 吉川 俊甫
AKS/ACAが好きです。2023/06に Microsoft MVP (Microsoft Azure) を受賞しました。
Shunsuke Yoshikawa - Credly