LoginSignup
1

More than 1 year has passed since last update.

Azure Kubernetes Service(AKS)でACIによる仮想ノードを構築する

Posted at

はじめに

この記事ではAzure Kubernetes Service(以下、AKS)で、Azure Container Instance(以下、ACI)を利用して仮想ノードを構築する方法を解説します。

想定読者

  • Kubernetesを利用したことがある方
  • Azureが好きな方

AKSでのワーカーノード

Kubernetesにおけるワーカーノードとは、クラスタにデプロイしたアプリケーション(Podなど)を実行する場所です。

AKSでのワーカーノードを構成する方法として、Virtual Machine Scale Set(以下、VMSS)を利用する方法、ACIを利用する方法が挙げられます。
VMSSによってワーカーノードを構成する場合、展開される各Virtual Machine(以下、VM)にkubeletやコンテナランタイム(containerd)が搭載されます。
このワーカーノードはVMと同様にあらかじめVMのサイズを決定し、それに沿ったキャパシティのもとアプリケーションを実行できます。
ACIを利用してワーカーノードを構成する場合、kubeletの代わりにOSSのVirtual Kubeletを利用してACIを仮想的なノードとして構成します。物理的なサーバを持たないことから、これを仮想ノードと呼びます。
VMSSによるワーカーノードと比較すると、以下の利点があります。

  • ノードの空きリソースに関係なく、リクエストのバースト時に素早くアプリケーションをスケールアウトできる

VMSSによるワーカーノードの場合、VMの空きリソースがある場合は素早くスケールアウトできますが、空きリソースがない場合にはノード自体をスケールアウト(VMを新しく起動)する必要があります。
ACIによるワーカーノードの場合は、ノードの空きリソースに関係なく、VMノードを起動するよりも素早くスケールアウトできます。

  • OS層のメンテナンスが必要ない

OS層がマネージドなACIを利用することで管理負荷を下げることができます。
ただし、仮想ノードのアドオン自体のバージョンアップは必要です。

ACIを使った仮想ノード

前述の通り、ACIはVirtual Kubeletをもとに実装されています。ここではそのアーキテクチャと、仮想ノードを利用するうえでの注意点について説明します。

アーキテクチャ

Virtual Kubeletを説明する前に、KubernetesにおけるKubeletについて簡単に説明します。
Kubeletの役割はノード上で実行されるPodを管理・操作することです。Kubernetesクラスタを構成する各ノード上で実行されるエージェントとして動作します。Kubeletが動作するノードは物理サーバ・仮想サーバを問いません。Kubernetesのapiserverからの入力を受け取り、受け取ったマニフェストのPodSpecをもとにノード上のPodを監視し、PodSpec通りの動作を続けるよう管理します。

Kubeletを実装したものの1つがVirtual Kubeletで、Kubernetes外のAPIと接続することを目的につくられています。

このVirtual Kubeletと接続するAPIとして、ACIなどのコンテナプラットフォームを選択することで、Kubernetesのノードをサーバレスに構成することができます。

画像はこちらから引用

virtual-kubelet.png

仮想ノードを利用するうえでの注意点

仮想ノードを利用するうえでの注意点(制約)もあるので、ここで代表的なものを紹介します。

AKSではCoreDNSmetrics-serverのPodを常に起動させておくシステムノードプールが必要になります。
システムノードプールはノード数を0にできないため、AKSを構成するワーカーノードをすべて仮想ノードにすることはできません。

仮想ノードを利用すると、実際にはACIをVNETに配置することになるため、ACIのVNET上での制約事項がそのまま適用されます。

  • Azure Container Registry(以下、ACR)からのサービスプリンシパルを利用したイメージのプルができない

仮想ノード上ではサービスプリンシパル(マネージドID含む)を利用してACRに対して認証することができません。仮想ノードでACRにホストされたイメージを利用したい場合、Kubernetes Secretを利用する必要があります。

  • Init Containerが利用できない

Init Containerを利用するワークロードを仮想ノード上で実現できません。VMノードで実行するか、Init Containerを必要としないアプリケーションアーキテクチャを採用する必要があります。

  • Kubenetを利用できない

Azure CNIネットワークを利用したAKSクラスタを構築する必要があります。

  • DaemonSetのPodは仮想ノードにデプロイされない

DaemonSetのPodがデプロイされるのはVMノードのみです。

その他制約事項はこちらを参照ください。

ACIを利用して仮想ノードを構築する

ここからは公式ドキュメントにならって、AKSに仮想ノードを構築してアプリケーションをホストする手順を解説していきます。

Azure Cloud Shell

この記事では、Azure Cloud Shell(Bash)からAzure CLIを利用します。
Azure CLIからACIを利用するため、以下のコマンドを実行します。

az provider register --namespace Microsoft.ContainerInstance

次のコマンドによりACIのリソースプロバイダが登録されていることを確認します。

az provider list --query "[?contains(namespace,'Microsoft.ContainerInstance')]" -o table

RegistrationStateRegisteredになっていることが確認できればOKです。

AKSの構築

AKSをリンクを参考に構築します。

ネットワークの種類はAzure CNIを選択してください。

AKSへの接続情報取得

以下コマンドを実行し、AKSへの接続情報を取得します。

az aks get-credentials --resource-group <リソースグループ名> --name <AKSクラスタ名>

kubectl config get-contextsを実行したときに作成したAKSクラスターが選択されていればOKです。

マネージドIDの有効化とロールの割り当て

AKSクラスターでマネージドIDを有効化します。

az aks update -g <リソースグループ名> -n <AKSクラスタ名> --enable-managed-identity

az aks show -g <リソースグループ名> -n <AKSクラスタ名> --query "servicePrincipalProfile"を実行したとき、"clientId": "msi"が確認できればOKです。

次に有効化したマネージドIDに対して、ロールを割り当てます。
仮想ノードでは、AKSクラスターが利用しているVNETに対してACIをデプロイする必要があるため、そのデプロイに必要なロールを割り当てます。
なお、AKSのVNET名はAzureポータルから確認してください。

# マネージドIDのオブジェクトID取得
principalId=$(az aks show  -g <リソースグループ名> -n <AKSクラスタ名> --query "identity.principalId" -o tsv)
# ノードのリソースグループ取得
nodeRg=$(az aks show  -g <リソースグループ名> -n <AKSクラスタ名> --query "nodeResourceGroup" -o tsv)
# VNETのオブジェクトIDの取得
vnetId=$(az network vnet show --resource-group $nodeRg --name <AKSのVNET名> --query id -o tsv)
# マネージドIDへVNETへのアクセス許可を割り当て
az role assignment create --assignee $principalId --scope $vnetId --role Contributor

仮想ノード用のサブネットの作成

仮想ノードで利用するACIをデプロイするためのサブネットを作成します。
サブネットのCIDRは、作成されたVNETに合わせて調整してください。

az network vnet subnet create \
    --resource-group $nodeRg \
    --vnet-name <AKSのVNET名> \
    --name <仮想ノード用サブネット名> \
    --address-prefixes 10.241.0.0/16

仮想ノードアドオンを有効化

いよいよ仮想ノード用のアドオンを有効化します。
以下コマンドを実行してください。

az aks enable-addons \
    --resource-group <リソースグループ名> \
    --name <AKSクラスタ名> \
    --addons virtual-node \
    --subnet-name <仮想ノード用のサブネット名>

有効化後、kubectl get pods --namespace kube-systemを実行したときにaci-connector-linuxで始まるPodがデプロイされていればOKです。

仮想ノードにアプリケーションをデプロイ

仮想ノードにアプリケーションをデプロイするため、以下のマニフェスト(virtual-node.yaml)を作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aci-helloworld
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aci-helloworld
  template:
    metadata:
      labels:
        app: aci-helloworld
    spec:
      containers:
      - name: aci-helloworld
        image: mcr.microsoft.com/azuredocs/aci-helloworld
        ports:
        - containerPort: 80
      nodeSelector:
        kubernetes.io/role: agent
        beta.kubernetes.io/os: linux
        type: virtual-kubelet
      tolerations:
      - key: virtual-kubelet.io/provider
        operator: Exists
      - key: azure.com/aci
        effect: NoSchedule

ポイントはnodeSelectortolerationsです。

nodeSelectorはPodが利用するノードを特定のノードに限定するためのもので、ここではvirtual-kubeletが指定されていることがわかります。VMノードにはPodを配置せず、仮想ノードにのみ配置するよう定義されています。

次にtolerationsを説明する前に、Taintについて説明します。
Taintとはノード上で実行するPodを制限するためのものです。仮想ノードで重要なPod(kube-proxyなど)が配置されるのを避けるため、Taintが設定されています。
tolerationsはこのTaintによる制約の影響を受けなくすることができるものです。上記マニフェストでは仮想ノードに設定されたTaintの影響を避けることができます。

kubectl apply -f virtual-node.yamlでデプロイします。

動作確認

kubectl get pods -o wideを実行すると、aci-helloworldのPodがvirtual-node-aci-linuxのノードで実行されていることが確認できます。これは仮想ノードであり、コンテナランタイムはACIになります。

実際にAzureポータルからACIのメニューを開くと、マニフェストで定義したコンテナが実行されていることが確認できます。

aci.png

次に実際にアプリケーションが動作しているか確認します。
AKSクラスターに次のコマンドを実行して、仮想ノード上のアプリケーションに対してcurlでアクセスしてみます。
まずはubuntuベースのコンテナをクラスタ内に展開します。

kubectl run -it --rm testvk --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11

コンテナ内でcurlをインストールします。

apt-get update && apt-get install -y curl

実際にcurlにより、仮想ノード上のアプリケーションにアクセスします。
IPアドレスは、kubectl get podsにより得られるアドレスを指定してください。

curl -L http://<仮想ノード上のPodのIPアドレス>

<html>
<head>
  <title>Welcome to Azure Container Instances!</title>
</head>
...

htmlの出力が得られているため、正常にアプリケーションが実行されていることが確認できました。

おわりに

この記事ではACIを利用して、AKSで仮想ノードを構成する方法を解説しました。
まだまだ制約事項が多く利用場所を選ぶ技術なので、実際のワークロードにそって導入を検討してください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1