AWS Load Balancer Controller は Kubernetes のリソースに対応する ELB を作成し管理するコントローラー。 必要な Policy を ServiceAccount に与えて Helm Chart でインストールできるが、CDK でクラスタを作る場合は albController でバージョンを指定することでこれをやってくれる。
new eks.Cluster(this, 'Cluster', {
...
albController: {
version: eks.AlbControllerVersion.V2_6_2,
},
})
次のような Ingress を作成すると ALB が作られる。 subnet は alb.ingress.kubernetes.io/subnets で指定することもできるが、 subnet に次のタグが付いている場合 auto discovery される。
- kubernetes.io/role/elb : 1
- kubernetes.io/cluster/${cluster-name}: owned or shared
alb.ingress.kubernetes.io/target-type は instance か ip を取り、 それぞれトラフィックがインスタンスまたは直接 Pod に向く。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/subnets: testpublicsubnet1, testpublicsubnet2
alb.ingress.kubernetes.io/healthcheck-path: /health
alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds=5
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80
ip にすると ALB の deregistration より前に pod が停止することで接続に失敗し 5xx エラーになってしまうことがあるため、 Deregistration delay を短くした上で、それ以上の時間待つ必要がある。
lifecycle:
preStop:
exec:
command: ["sleep", "15s"]
また、ローリングアップデート時に ALB のヘルスチェックが通る前に pod が ready になってしまうと、古い pod が終了してリソースが不足してしまう。 これを防ぐには namespace に次のラベルを付けて Pod readiness gate が挿入されるようにする。
apiVersion: v1
kind: Namespace
metadata:
name: app
labels:
elbv2.k8s.aws/pod-readiness-gate-inject: enabled
特定の Pod に負荷が集中するとヘルスチェックに失敗してリクエストがルーティングされなくなることで、残りの Pod に負荷が集中して全滅してしまう悪循環が起きてしまうことがあるが、デフォルトのラウンドロビンではなく処理中のリクエストが最も少ない Target にルーティングする Least Outstanding Requests (LOR) にすることで集中を解消できる可能性がある。 ただしリクエスト数に比例して負荷が高まるサイドカーがある場合はそちらの負荷が偏ってしまうことがある。
alb.ingress.kubernetes.io/target-group-attributes: load_balancing.algorithm.type=least_outstanding_requests
AccessDenied などで ALB が作られない場合は Policy が最新で ServiceAccount の annotations に誤りがないかを確認するとよい。
alb.ingress.kubernetes.io/security-groups で独自のセキュリティグループを設定できるが、そうする場合併せて alb.ingress.kubernetes.io/manage-backend-security-group-rules を true にしないとインスタンスの SG の inbound で許可されている Backend SG が ALB に追加されずアクセスできない。
参考
AWS Load Balancer Controller v2.3.0 から導入された Optimized SG rules について #AWS - Qiita