CDKで作成したEKSクラスタのノードにセキュリティグループを設定する

awskubernetes

aws_eks.Clsuter を作る際に渡せる securityGroup はノードでなくコントロールプレーンの ENI に紐づく SG となっている。

Cluster に defaultCapacity というフィールドがあるので、 ここから SG を追加しようとしたが何も起こらない。 EKS クラスタを作成する際、DefaultCapacityType がデフォルトの NODEGROUP のとき、defaultCapacity の数のノードから構成され、EKS によって drain などが行われるマネージドノードグループが作られるが、defaultCapacity は DefaultCapacityType が EC2 のときにしか値が入らないのだ。

NODEGROUP の場合は代わりに defaultNodegroup を参照できるが、 こちらは AutoScalingGroup の defaultCapacity と異なり、 addSecurityGroup() のようなインタフェースを持たない Nodegroup となっている。

ややこしい名前だが、clusterSecurityGroup はコントロールプレーンだけでなくマネージドノードグループのノードの ENI にも紐づくのでこれを編集することでノードの SG を設定できる。

cluster.clusterSecurityGroup.addIngressRule(ec2.Peer.ipv4("xxx.xxx.xxx.xxx/32"), ec2.Port.allTcp())

また、マネージドノードグループではなく自前の AutoScalingGroup で SG を追加する方法もある。 既存の SG を追加する場合は注意が必要で、自動で追加される設定と重複するものが既にある場合、リソースの削除時にまとめて消されてしまう。 そのため使い回さずに新規に作った方が良いと考えている。

const cluster = new eks.Cluster(this, 'Cluster', {
  ...
  defaultCapacity: 0,
})

const securityGroup = new ec2.SecurityGroup(this, 'EKSClusterDefaultCapacitySecurityGroup', {
  vpc,
  allowAllOutbound: true,
})

const defaultCapacityAsg = cluster.addAutoScalingGroupCapacity('EKSClusterDefaultCapacity', {
  instanceType: new ec2.InstanceType('t3.small'),
  minCapacity:  2,
})

defaultCapacityAsg.addSecurityGroup(securityGroup)

自前の ASG の場合、drain に加えて、必要に応じて boostrap.sh のパラメータを渡す必要があったりするので、基本的にはマネージドノードグループを使うのが良いと思うが、ASG にタグが伝搬されないため launchTemplate を指定しないとインスタンス名が空になるのは何とかなってほしい。

EKSクラスタによるIPアドレスの枯渇とIPv6への移行 - sambaiz-net