kubell Creator's Note

ビジネスチャット「Chatwork」のエンジニアのブログです。

ビジネスチャット「Chatwork」のエンジニアのブログです。

読者になる

EKSでNode Local DNS CacheとSecurity groups for podsを一緒に使う

Chatwork SRE部の坂本です。この記事はChatwork Advent Calendar 2022 15日目の記事です。

この記事ではEKSにおいて、Node Local DNS CacheとSecurity groups for podsを一緒に使う方法について記載したいと思います。

Node Local DNS Cacheとは

下記の記事で導入までの過程やハマリポイントを記載しておりますので、ご参照下さい。

creators-note.chatwork.com

Security groups for podsとは

Kubernetesでは、Network Policyもありますが、AWSのサービス側のsgでも制御したい場合があると思います。 そのときに利用できるのが、Security groups for podsです。 docs.aws.amazon.com

すごく簡単にまとめると、EKSに対して下記のコマンドを実行すれば、使える状態になります。

$ kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true

しかしこれだけでは、readiness/livenessが通らなくなってしまうので(使わないのであれば不要ですがなかなかそういう状況はないと思います)、もう1つコマンドを実行します。

$ kubectl patch daemonset aws-node -n kube-system \
  -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

この2つで"基本的には"Security groups for pods自体は利用可能な状態になり、あとはkind: SecurityGroupPolicyをapplyすれば、アプリケーションからSecurity groupが利用可能になります。

2つを一緒に使いたい

さて、この2つを一緒に使いたい場合、ちょっとしたハマリポイントがあります。というか、弊社で最初にSecurity groups for podsを検討した際、まだ一緒に使うことができず、断念した、という経緯がありますが、aws-vpc-cniの1.11でついに使えるようになりました。

https://github.com/aws/amazon-vpc-cni-k8s/pull/1907

そのことを記事に書こうとしたら、すでにありました!ですので、下記の記事を読んでください!

zenn.dev

で、終わりたいところではありますが、弊社ではVPC Peering越しにSecurity groups for podsを利用しており、実はもう一捻り必要です。 Node Local DNS Cacheを使えるようにするだけであれば、上記のブログに記載されている通り、下記のコマンドを実行すれば利用可能になります。

$ kubectl set env daemonset -n kube-system aws-node POD_SECURITY_GROUP_ENFORCING_MODE=standard

しかし、このPOD_SECURITY_GROUP_ENFORCING_MODE=standardにすると、VPC外のリソース(例えばpeering越しのリソース)にアクセスする際、EKSのaws-vpc-cniのデフォルトの設定のままではNodeのPrimary ENI を使用して通信を行うため、NodeのPrimary ENIに設定されているセキュリティグループが使用されてしまって、VPC外のリソースのinboundにpodのセキュリティグループでは届かないために、通信ができなくなります。これはNodeでのSNATが有効になっていることによる挙動です。

そこでもう1つ環境変数を設定します。これは、NodeでのSNATをoffにするパラメータでこれをtrueにすることで、NodeでのSNATが無効になります。

$ kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true

これを有効にするとノードでのSNATが使えなくなるので、public subnetは使えなくなります。あまりpublic subnetでノードを動かしていることはありませんが、お気をつけください。

Security groups for podsの懸念点など

さて、Security groups for podsですが、パフォーマンスが劣化する可能性について、READMEでは言及されています。

正確には、readiness/livenessを使う際のDISABLE_TCP_EARLY_DEMUXtrueにすることによる影響なので、これをデフォルトのfalseのままであれば影響はありません。

下記のREADMEには

This will increase the local TCP connection latency slightly.

https://github.com/aws/amazon-vpc-cni-k8s#disable_tcp_early_demux-v173

と記載されおります。しかし、弊社で負荷試験をしたところ、ほとんどパフォーマンスの劣化はなく、正直なところ何とも言えないのですが、"そういう可能性がある"という点にご留意ください。

また、そのほかの注意点が、AWSのドキュメントに記載されておりますので、Security groups for podsを利用する際には、AWSのドキュメントをご確認ください。

悩ましいところ

弊社では、aws-vpc-cniをEKSのaddonで管理していますが、上記の環境変数の設定は(環境変数の設定だけではなく設定すること自体が)addon経由では実行できず、クラスタ作成して、addonを有効にした後でコマンドを実行して反映している状態です。chartもあるので、それで管理する方法もありますが、addonとの差分が出た場合を懸念して、今は最小で更新するためにコマンドを実行していますが、モヤモヤ感はあります。

eks-charts/README.md at master · aws/eks-charts · GitHub

このあたりaddonと合わせてうまく管理できるようになりたいところですが、いまのところいい落とし所が定まっていない状態です。

と、書いていたら、なんとaddonの追加の設定ができるようになったっぽいです🥰🥰🥰

aws.amazon.com

まだ試せていないですが、これでクラスタ作成後のpatchがなくなりそうです!

それでは、Enjoy EKS 🥰