Chatwork Creator's Note

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

読者になる

AWS NLBにSecurity GroupがつけれるようになったのでAWS Load Balancer Controllerの動きを確認してみた

こんにちは。秋の新デバイス発売祭りにのっかりすぎて1ヶ月もやし生活を考えている cw-furuya です。

本記事はChatwork Product Day 2023応援記事です。

lp.chatwork.com

他の方と違ってかなりニッチな技術ネタですが、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のセキュリティグループ対応について情報が古いままなので注意が必要です。(コントリビュートチャンス?)

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/service/nlb/#security-group

何が変わったのか、また実際作ってみるとどうなのか、やってみました。

何が変わったのか

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を作成する場合は上記の仕様に気をつけていただければと思います。