Closed4

EKSのセキュリティーグループ周りを理解したい

dekimasoondekimasoon

EKSのセキュリティーグループ(以下SG)はちょっとだけ面倒そうで後回しにしていたのだが、ちゃんと理解してみたい。過去に色々と変更があった部分で、検索すると色々出てくるのだが、シンプルにまとめられたら嬉しい。

理解したいのは以下の3点だと思う。

  1. SGの管理をEKSに任せた場合どうなるのか
  2. SGのカスタマイズ、もしくは手動での管理はどこまで可能なのか
  3. カスタマイズ、手動での管理をする場合のベストプラクティスとは
dekimasoondekimasoon

1. SGの管理をEKSに任せた場合どうなるのか

公式ドキュメント的にはこちらだと思われる。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/sec-group-reqs.html

簡単にまとめると、

  1. EKSクラスタが作られるとeks-cluster-sg-xxxというSGを自動的につくるよ
  2. 作ったeks-cluster-sg-xxxはEKSクラスタ(コントロールプレーン)と、マネージドなノードインスタンスに付与するよ
  3. (2)によって、コントロールプレーンとノード間の通信が許可されるよ

という感じらしい。実際に作成されるSGを見てみる。

✗ aws ec2 describe-security-groups --group-ids sg-067eaf4e2cb9f1776 --output yaml

SecurityGroups:
- Description: EKS created security group applied to ENI that is attached to EKS Control
    Plane master nodes, as well as any managed workloads.
  GroupId: sg-067eaf4e2cb9f1776
  GroupName: eks-cluster-sg-s8-stack8-example-437337099
  IpPermissions:
  - IpProtocol: '-1'
    IpRanges: []
    Ipv6Ranges: []
    PrefixListIds: []
    UserIdGroupPairs:
    - GroupId: sg-067eaf4e2cb9f1776
      UserId: '017057219515'
  IpPermissionsEgress:
  - IpProtocol: '-1'
    IpRanges:
    - CidrIp: 0.0.0.0/0
    Ipv6Ranges:
    - CidrIpv6: ::/0
    PrefixListIds: []
    UserIdGroupPairs: []
  OwnerId: '017057219515'
  Tags:
  - Key: Name
    Value: eks-cluster-sg-s8-stack8-example-437337099
  - Key: aws:eks:cluster-name
    Value: s8-stack8-example
  - Key: kubernetes.io/cluster/s8-stack8-example
    Value: owned
  VpcId: vpc-0105b1637bb889d9f

IpPermissionsのとこがIngressでUserIdGroupPairsに自身のSGが指定されているので、このSGが設定されている者同士について全ての通信を許可、となっている。
IpPermissionsEgressがEgressで、こちらはシンプルに全ての通信を許可になっている。

なるほど。ドキュメントに書かれている通りだ。

ロードバランサー(以下LB)、AWS Load Balancer Controllerについて補足

上のSGを見て、あれ?でもLBからの通信受け付けてるよな?と疑問に思って見ていた。
AWS Load Balancer ControllerにLBの作成を任せている場合、AWS Load Balancer ControllerがLBとノード間のSGを管理してくれているらしい。

これはBackend Security Groupsと呼ばれていてドキュメントが詳しく書かれていた
自分で管理したい場合は--enable-backend-security-group=falseに設定すると良いらしい。

またTargetGroupBindingを使ってLBとServiceリソースとの紐づけを行っている場合は、spec.networking.ingress[0].from[0].securityGroup.groupIDを指定している場合はSGを管理してくれるらしい。自前で管理するならspec.networkingの設定は不要。

dekimasoondekimasoon

2. SGのカスタマイズ、もしくは手動での管理はどこまで可能なのか

まず、(1)で書いたEKSクラスタに紐づいて作成されるeks-cluster-sg-xxxというSGには手出しできないらしい。このSGは必ず作成されて、EKSクラスタの管理下にあるとのことである。しかし、SGにルールを追加することは可能らしい。

ただし、追加のSGをEKSクラスタ(コントロールプレーン)に設定することは可能とのこと。こちらはAWSの公式ドキュメントが見つけられないが、CloudFormationやTerraformにはResourcesVpcConfig.SecurityGroupIdsであったりvpc_config.security_group_idsから指定できそう。

次に、ノードインスタンスに設定されるSGは変更可能らしい。公式ドキュメントは以下。
ノードグループに指定するLaunchTemplateにSGを指定すれば、ノードインスタンスに設定されるSGをデフォルトのeks-cluster-sg-xxxから変更できるとのこと。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/launch-templates.html#launch-template-security-groups

というわけで、選択肢としては2つか。

  1. EKSクラスタに紐づいて作成されるeks-cluster-sg-xxxへのルール追加で対応する
  2. eks-cluster-sg-xxxは放置。EKSクラスタへのSG追加と、ノードインスタンスに設定されるSGを変更することで手動管理する

eks-cluster-sg-xxxを放置するデメリットは特にないため、完全にコントロールできる(2)が良さそう。

dekimasoondekimasoon

3. カスタマイズ、手動での管理をする場合のベストプラクティスとは

SGで管理すべき通信は以下になるはず。

  1. コントロールプレーン(EKSクラスタ)とデータノード(ノードインスタンス)間の通信
  2. 異なるノードインスタンス(データノード)間の通信
  3. データノードとEKS外部のリソース(LB, RDSなど)間の通信

1と2用のSGをcluster-sg、3用のSGをnode-sgとして

  • cluster-sgはcluster-sgが設定された同士の通信を許可して、EKSクラスタとノードインスタンスの両方に設定
  • node-sgはLBからの通信、RDSへの通信など必要に応じて許可して、ノードインスタンスに設定

という感じで良さそう。
自分の場合はcluster-sgは全ての通信を許可しちゃうと思うが、絞るなら公式ドキュメント記載の値を参照すればいいはず。

このスクラップは4ヶ月前にクローズされました