EKSのセキュリティーグループ周りを理解したい
EKSのセキュリティーグループ(以下SG)はちょっとだけ面倒そうで後回しにしていたのだが、ちゃんと理解してみたい。過去に色々と変更があった部分で、検索すると色々出てくるのだが、シンプルにまとめられたら嬉しい。
理解したいのは以下の3点だと思う。
- SGの管理をEKSに任せた場合どうなるのか
- SGのカスタマイズ、もしくは手動での管理はどこまで可能なのか
- カスタマイズ、手動での管理をする場合のベストプラクティスとは
1. SGの管理をEKSに任せた場合どうなるのか
公式ドキュメント的にはこちらだと思われる。
簡単にまとめると、
- EKSクラスタが作られると
eks-cluster-sg-xxx
というSGを自動的につくるよ - 作った
eks-cluster-sg-xxx
はEKSクラスタ(コントロールプレーン)と、マネージドなノードインスタンスに付与するよ - (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
の設定は不要。
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
から変更できるとのこと。
というわけで、選択肢としては2つか。
- EKSクラスタに紐づいて作成される
eks-cluster-sg-xxx
へのルール追加で対応する -
eks-cluster-sg-xxx
は放置。EKSクラスタへのSG追加と、ノードインスタンスに設定されるSGを変更することで手動管理する
eks-cluster-sg-xxx
を放置するデメリットは特にないため、完全にコントロールできる(2)が良さそう。
3. カスタマイズ、手動での管理をする場合のベストプラクティスとは
SGで管理すべき通信は以下になるはず。
- コントロールプレーン(EKSクラスタ)とデータノード(ノードインスタンス)間の通信
- 異なるノードインスタンス(データノード)間の通信
- データノードとEKS外部のリソース(LB, RDSなど)間の通信
1と2用のSGをcluster-sg
、3用のSGをnode-sgとして
-
cluster-sg
はcluster-sgが設定された同士の通信を許可して、EKSクラスタとノードインスタンスの両方に設定 -
node-sg
はLBからの通信、RDSへの通信など必要に応じて許可して、ノードインスタンスに設定
という感じで良さそう。
自分の場合はcluster-sg
は全ての通信を許可しちゃうと思うが、絞るなら公式ドキュメント記載の値を参照すればいいはず。