この記事は 第二のドワンゴ Advent Calendar 2019 の20日目の記事です。
投稿が遅くなりました。
「Kubernetesのカスタムコントローラーを作ってみた」的な記事を書きたかったのですが、作ってる際にハマったclient-goでのラベルセレクターの扱いについて書いていこうかと思います。
ラベルセレクターとは
ラベルはユニーク性を提供しません。通常、多くのオブジェクトが同じラベルを保持することを想定します。 ラベルセレクター を介して、クライアントとユーザーはオブジェクトのセットを指定できます。ラベルセレクターはKubernetesにおいてコアなグルーピング機能となります。
Podをスケジュールする際にNodeを決定する nodeSlector
もラベルセレクターの一種で、ラベルを持つノードからこの nodeSelector
を利用してPodをスケジュールするノードをグルーピングします。
kubectl get
コマンドにおいては --selector
オプションにて入力可能です。
たとえば全てのネームスペースから、app = myapp
というラベルのついて Pod をグルーピングする場合は、以下のようなコマンドを実行します。
kubectl get pods --all-namespaces --selector='app=myapp'
client-go からラベルセレクターを利用する
Podについてラベルセレクターを利用してフィルタリングを行います。
ラベルセレクターなどを利用せずに全てのネームスペースからPodを取得する場合、以下のようなコードになるかと思います。
Podのリストを取得する際の ListOptions
には、それらしい LabelSelector
という文字列を与えることができます。
一方で、ラベルセレクターを表すのLabelSelector
構造体には、ListOptions
の LabelSelector
が期待する文字列を生成する関数は定義されていません。*1
では、どうするかというと、同パッケージに定義されている FormatLabelSelector(labelSelector *LabelSelector) string
を利用します。
labelSelector := &metav1.LabelSelector{ MatchLabels: map[string]string{ "app": "myapp", }, } clientset.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{ LabelSelector: metav1.FormatLabelSelector(labelSelector), })
こうすることで、app = myapp
というラベルを持つPodを取得することができます。
また、LabelSelector
構造体を利用せずに、ListOptions.LabelSelector
に "app=myapp"
という文字列を与えることでも同じ結果を得られます。
clientset.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{
LabelSelector: "app=myapp",
})
まとめ
client-go からKubernetesラベルセレクターを利用する方法について説明しました。
以下のリポジトリに本記事で使用したコードがあります。
ラベルセレクターは強力な仕組みで kubectl や client-go からでも簡単に利用できます。 カスタムコントローラーを開発する際にも役立てていきたいですね!
*1:ここでめちゃくちゃハマった