こんにちは。秋の新デバイス発売祭りにのっかりすぎて1ヶ月もやし生活を考えている cw-furuya です。
本記事はChatwork Product Day 2023応援記事です。
他の方と違ってかなりニッチな技術ネタですが、EKSユーザの方の参考になれば幸いです。
AWSのNetwork Load BalancerがついにSecurity Groupをサポートしましたね。 https://aws.amazon.com/about-aws/whats-new/2023/08/network-load-balancer-supports-security-groups/
これに伴い、AWS Load Balancer Controllerで作成されるNLBにも デフォルトでSecurity Groupが付与されるようになっています。 ※2023/10/10時点でAWS Load Balancer Controllerのドキュメントでは NLBのセキュリティグループ対応について情報が古いままなので注意が必要です。(コントリビュートチャンス?)
何が変わったのか、また実際作ってみるとどうなのか、やってみました。
何が変わったのか
v2.6.0のリリースノートに詳しい挙動が書いてあります。ポイントとしては以下の通りです。
- ALB(ingress)と同様に、アタッチするSecurity Groupを明示しない場合は自動的に2つのSecurity Groupが作成されアタッチされる
- ひとつは外部からの通信を受け付けるもの(frontend SG)
- ひとつはBackendのNode Groupたちと通信するもの(backend SG)。Node GroupのSecurity Group側のingressに自動で追加される
- frontend SGは
service.beta.kubernetes.io/aws-load-balancer-security-groupsアノテーションで明示することができる - 既存のSecurity GroupがアタッチされていないNLBも引き続きAWS Load Balancerで管理可能
新しいNLBをAWS Load Balancer Controllerで作ってみた
annotationによってどのようなセキュリティグループが作成されるのか、確認しました。 まずはAWS Load Balancer ControllerをインストールしたEKSを用意します。
eksctl create cluster --name new-nlb
AWS Load Balancer Controllerのインストール方法はこちら。
https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/deploy/installation/
接続先のアプリケーション(nginx)を用意します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.2
ports:
- containerPort: 80
NLBを作成するため、Serviceリソースを作成します。 まずはデフォルトのままでデプロイします。
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: '10'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true
service.beta.kubernetes.io/aws-load-balancer-type: external
labels:
app.kubernetes.io/instance: postfix-internal
app.kubernetes.io/name: nginx
app.kubernetes.io/version: 1.25.2
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerSourceRanges:
- [your ip]
NLBが作成され、自動的に作成されたSecurity Groupがアタッチされています。



また、Node Group側のSecurity Groupでは、NLBのbackend SGからの通信を許可するルール(TCP:80)が自動で追加されています。

次にservice.beta.kubernetes.io/aws-load-balancer-security-groupsアノテーションを使って
既存のSecurity Groupを指定してみます。(先程作ったNLBは一旦削除しています)
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: '10'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-security-groups: [sg id]
labels:
app.kubernetes.io/instance: postfix-internal
app.kubernetes.io/name: nginx
app.kubernetes.io/version: 1.25.2
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
NLBに指定したSecurity Group(frontend SG)がアタッチされました。

ただしこの場合はbackend SGが作られないためNode Group側のSecurity Groupを自分で更新し、
frontend SGからの通信を許可する必要があります。
先程のように自動でbackend SGの作成とNLBへのアタッチ、およびNode Group側のSecurity Groupの修正をするためには
service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rulesアノテーションを使います。
デフォルトがfalseであるため、frontend SGを明示した場合はbackend SGを管理してくれません。
では再度NLBを消して、service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rulesをtrueにしてデプロイしてみます。
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: '10'
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: '2'
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-security-groups: [sg id]
service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: 'true'
labels:
app.kubernetes.io/instance: postfix-internal
app.kubernetes.io/name: nginx
app.kubernetes.io/version: 1.25.2
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
指定したfrontend SGがアタッチされ、backend SGが自動生成され、Node Group側のSGも変更されました。


まとめ
NLBでSecurity Groupがサポートされたことで、AWS Load Balancer Controllerで作成されるNLBも仕様が変わりました。 既存には影響ないですが、今後新しくNLBを作成する場合は上記の仕様に気をつけていただければと思います。