AWS Load Balancer ControllerがIngressに対応するリソースをプロビジョニングする部分を読む
この記事はKubernetes Advent Calender 2022の23日目の記事です。
AWS Load Balancer Controllerとは
AWS Load Balancer Controller(以下ALBC)はIngress/Service type LoadBalancerをElastic Load Balancer(ELB)を使ってプロビジョニングしてくれるコントローラーです。
IngressリソースにはALB、Service type LBにはNLBをプロビジョニングしてくれます。
EKSを採用しているプロダクトでは広く使われていると思います。今回はALBCがIngressに合わせてAWSのリソースをプロビジョニングしている部分のコードをざっと追ってみます。
How it works - AWS Load Balancer Controller
Ingressリソースに対するALBCの操作
Ingressリソースが作成されるとALBCが作成イベントをwatchしてAWSのリソース作成を開始します。
Ingressには様々なアノテーションを設定することができ、IngressにWAFやACMの証明書を簡単に紐づけることができます。
ALBCははじめに、IngressにつけられたALBC用のアノテーションに対応するようにALBリソースを作成します。
ABLリソースを作成した後は、ALBからIngressのTargetへ通信ができるように、TargetGroupやALBのListernersを作成します。httpsを使用する場合にはアノテーションで指定された証明書もアタッチしてくれます。
パスごとのルーティング設定がある場合には、Listener Rulesの設定も行われます。また、Ingressの削除時にも作成時とは真逆に上記のリソースの削除もコントローラーが行ってくれます。
コードリーディング
今回コーディリーディングに使用したコミット: https://github.com/kubernetes-sigs/aws-load-balancer-controller/tree/edeb4f1c1312f2e2915ded595fcef8545501878a
起点になるReconcileはこの部分になります。ここから読んでいきます。
controllerの実装がいまいちわからない方は「つくって学ぶKubebuilder」という資料が非常に参考になるのでこちらを先に読むと理解が早いかもしれませんが、最初以外は特に登場しないので気にしなくても大丈夫です。
この記事ではIngressリソースに関連するコードにのみ焦点を当てていますが、Serviceリソースに対応するreconcile処理を見たい時にはServiceに対応したControllerのReconcile関数を確認するとServiceリソースに対するコントローラーの処理内容が書いてあります。(↓)
IngressGroupについて
groupReconciler
のgroupというのはIngressGroupのことです。IngressGroupは複数のIngressをまとめる単位で、Ingressにalb.ingress.kubernetes.io/group.name
のアノテーションを指定することで指定します。
同じIngressGroupに所属するIngressは同じALBに所属し、各IngressへのルーティングはListener Rulesがそれぞれ設定されます。
IngressGroup名はalb.ingress.kubernetes.io/group.name
というアノテーションで指定することができます。controllerでは以下の関数でIngressGroup名を取得しています。
AWSリソースのスタック計算とデプロイ
Ingressリソースに対応するAWSのリソースのスタックはこの関数の中で作成されています。スタックは前述したようにreconcile対象のIngressが所属するIngressGroupごとに行われるようになっています。
同一IngressGroupは同じLBにまとめられるので、該当のIngressGroupに所属する各Ingressに対して計算が行われています。設定している項目は多いですが、LBだけでなくListener、ListnerRuleもIngressに対応するように設定されています。
上記で計算されたスタックを元にAWSの各サービスのリソースの作成、アプデートを行っている部分は以下になります。各リソースに対してSynthesizer
というinterfaceを満たすstructが用意されており、必要なSynthesizer
をsliceにまとめてforで順番に回しています。この順番もリソース間の依存関係に沿って決まっていそうです。
AWSのリソースの操作が完了したあとで、新規に作成されたLBがあった場合はLBのDNSを取得してIngressのHostNameの更新を行なっています。taskの初期ではnilになっているので作成された新規作成されたLBがない場合は特に何もしないようです。
おわり
駆け足になりましたが、これでALBCがIngressに対応したAWSのリソースを作成している部分のコードを一通り見てみました。
意外とシンプルにまとまっているので尺がだいぶ短くなってしまいましたが、他のCustom ControllerもReconcileからの流れは同じ感じになっているものが多いので、もしOSSでクラスタにコントローラー入れてるけど何してるかよくわからないみたいな時はコードをパッとみて実装を確認できるのが良いですね。
Discussion