銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

kubernetes on Azureで接続できる上限を超えた数のディスクをPVとして利用するPodをデプロイしたときの話

kubernetesをAzureで動かすとAzure DiskをPVとしてマウントできる機能があります。一方、Azure Diskは仮想マシンサイズごとに仮想マシンに接続できる上限が決まっています。というわけで、その上限を超えるようなディスクをPVとしてマウントしているPodをデプロイしようとすると、どうなるかという話です。 ちなみに、このような事象事態はAWSやGCPでもあるのですが、仮想マシンサイズごとに上限が違うというのはAzureだけの仕様のようで、ここがあとあと問題になってきます。

今回は、OpenShift 3.11をAzureで動かして検証しています。AKS含めて、kubernetes 1.11.xで Azure Cloud Provderを有効化していれば同じ結果になるはずです。まず、10枚のAzure DiskをマウントするPodを定義します。

f:id:tanaka733:20190221103653p:plain

で、このPodをデプロイしてみます。するとイベントに次のように表示されます。

f:id:tanaka733:20190221103720p:plain

Podがノードにスケジューリングされ、順番にDiskが接続されていくのですが、上限(今回のインスタンスサイズでは4)を超えたところで接続のエラーが発生しています。最終的にディスクの接続が完了しないためこのPodのデプロイは失敗となっています。

せっかくなのでもっと枚数を増やしてみましょう。17枚マウントすることにします。

f:id:tanaka733:20190221104149p:plain

でこれをデプロイするとこうなります。

f:id:tanaka733:20190221104217p:plain

今度はPodがノードにスケジュールされるところで、max volume countのためスケジュール可能なノードがみつからなかったということでエラーが発生してしまいました。どちらかというと後者の方が実際にPodが生成される前にエラーになるのでうれしいのですが、この違いはなぜでしょう。

ノードが接続可能なボリュームの上限を考慮したkubernetesのスケジューリングはこのPRで最近入った機能です。AWS、GCP、Azureに対応しています。

Balanced resource allocation priority to include volume count on nodes. by ravisantoshgudimetla · Pull Request #60525 · kubernetes/kubernetes · GitHub

このPRおそらく、1.10以降の最新パッチでは含まれていると思うのですが、コードをよく見てみるとAzureだけTODOがついています。

// DefaultMaxAzureDiskVolumes defines the maximum number of PD Volumes for Azure
// Larger Azure VMs can actually have much more disks attached.
// TODO We should determine the max based on VM size

kubernetes/predicates.go at v1.11.7 · kubernetes/kubernetes · GitHub

というわけで、Azureだけが仮想マシンのサイズごとに上限が違っているのだが、とりあえずデフォルト16でハードコーディングしとくよ、という状況のようです(でした)。従って、今回のノードのように実際の上限が4だと、5~16の間ではスケジュールはされるものの、ディスクを接続するためのAzure API実行時にエラーが発生します。

そこで、kubernetes 1.12.0以降では次のPRでインスタンスサイズごとの上限を考慮できるような修正が追加されています。

Enable dynamic azure disk volume limits by andyzhangx · Pull Request #67772 · kubernetes/kubernetes · GitHub

これで、kubernetes 1.12以降ではスケジュール時にエラーが出るようになるはずです。