Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

EKSのクラスタに追加のセキュリティーグループを導入してクラスタバージョン更新に備える

研究開発部 Architectグループ ML PlatformチームのKAZYこと新井です。

名古屋にある中部支店に所属しています。

バージョン更新の負荷を減らすためにEKSにセキュリティーグループを追加した話を紹介します。

なお、本記事は【R&D DevOps通信】という連載記事のひとつです。

目次

背景

研究開発部へのEKS導入

2022年に研究開発部ではアプリケーション基盤としてEKS(Circuitと呼んでいます)を導入しました。

buildersbox.corp-sansan.com

Kubernetesは日々開発が進んでおり、新しいバージョンが続々とリリースされています。

Amazon EKSでは、新しいKubernetesのバージョンが最初に利用可能になってから14か月間サポートされます*1

Amazon EKS Kubernetes のバージョン - Amazon EKS

Amazon EKSユーザは定期的にKubernetesのバージョン更新をすることになります。

私達のチームでは、この度はじめてのクラスタのバージョン更新を迎えます。

Blue/Greenデプロイによるクラスタのバージョン更新

CircuitではBlue/Greenデプロイでクラスタのバージョン更新を行います。

この方法では、新しいバージョンのクラスタに、既存のクラスタと同様のシステムを作成し、トラフィック移行をします*2

既存のクラスタを更新するよりも、新しいクラスタを作成する方が手間やコストはありますが、ロールバックや検証が容易で、更新をより安全に行えるメリットがあります。

Blue/GreenデプロイをするためにCircuitではアプリケーションの負荷分散にIngressリソースは使わず、TargetGroupBindingリソースを使いターゲットグループの向き先を変えるだけでクラスタ間のトラフィック移行ができるようにしています。

以下の記事が詳しいです。

TargetGroupBinding を使って AWS EKS で Kubernetes を無停止かつ DNS 切り替え無しでバージョンアップしました – PSYENCE:MEDIA

Blue/Greenデプロイ

以下の記事を読むとさらに理解が深まると思います。

より安全なEKS cluster update方法を模索する

宣言的 Blue/Green デプロイで EKS バージョンライフサイクルに立ち向かう話|グロービス・デジタル・プラットフォーム

クラスタごとに作られるクラスタセキュリティーグループ

EKSにはクラスタセキュリティーグループ(以降クラスタSG)というものがあります。クラスタSGはクラスタ作成とともに自動作成されます。

そしてeks-cluster-sg-<クラスタ名>-<uniqueID> という名前を持ちます。

クラスタSGはコントロールプレーンに割り当てられているセキュリティーグループです。FargateノードやEC2ノードもデフォルトではこちらに割り当てられています。

Amazon EKS セキュリティグループの要件および考慮事項 - Amazon EKS

クラスタの数だけクラスタセキュリティーグループがある

SecrurityGroupPolicyでPodごとのアクセス制限

CircuitではSecrurityGroupPolicyリソースを使って、Pod単位でのアクセス制限をしています。

SecurityGroupPolicyを使うとPod毎にアクセス制限ができる

SecrurityGroupPolicyを使うためには紐付けるセキュリティーグループで満たすべき条件があります。

CircuitではEC2とFargateのノードがクラスタ内で動作しているため以下のようになります。


EC2ノード/Fargateノード共通

  • PodからCoreDNSのPodへのTCP/UDP 53番ポートでの通信
    • 名前解決を含む通信を避けることができれば塞がっていてもPodは起動するが、実用上不便です
  • ノードに適用されたセキュリティーグループからのインバウンド通信
    • probeを利用している場合は塞がっているとPodが正常に起動しない
  • コントロールプレーンからkubelet に対する TCP:10250 通信
    • 塞がっていてもPodは起動するが、kubectl exec/logsなどが使えなくなるため、実用上不便です
    • EC2ノードにクラスタSGがノードにアタッチされている場合は意識しなくても通信ができる

EC2ノードのみ

  • Podごとにネットワークインターフェースがある
    • Amazon VPC CNI plugin for Kubernetesで実現ができる

Fargateノードのみ

  • Podからコントロールプレーン(kube-apiserver)へのTCP:443 通信
    • 塞がっているとFargateノードをプロビジョニングできずPodが起動しない

EC2ノードでSecurityGroupPolicyを使うために必要な通信

FargateノードでSecurityGroupPolicyを使うために必要な通信


通信的な観点ではFargateノードのPodからコントロールプレーン(apiserver)への通信が必須で、その他は運用方法に合わせて決めます。

チュートリアル: Pods のセキュリティグループ - Amazon EKS

解決したい課題

クラスタのバージョン更新のたびにSecurityGroupPolicyを書き換えたくない

ドキュメントには、SecurityGroupPolicyを使用するための簡単な方法が書かれており、クラスタSGをセキュリティーグループの1つとして指定することが提案されています。Circuitでも同様の方法を採用していました。

そのため、Circuit内で使用するSecurityGroupPolicyリソースのマニフェストは、クラスタSGとPod固有のセキュリティーグループを組み合わせています。

apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
︙略
  securityGroups:
    groupIds:
      - クラスタSG
      - Pod独自のSG

この構成では、新しいクラスタを作成するたびにマニフェストを更新する必要があります。 クラスタSGはクラスタごとに作成されるためです。

apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
︙略
  securityGroups:
    groupIds:
      - クラスタSG  ←クラスタが変わる毎に変更が必要
      - Pod独自のSG

この書き換え作業が今回の課題です。無くしたいです。

解決策

追加のセキュリティーグループをSecurityGroupPolicyに紐付ける

EKSにセキュリティーグループを追加して解決しました。

追加のセキュリティーグループ

EKSでは、クラスタSG以外にも、追加のセキュリティーグループがあります。独自に作成したセキュリティーグループを追加することができます。

コンソール上ではネットワーキングタブの中央辺りのクラスタセキュリティーグループの下にあります。

追加のセキュリティーグループはクラスタSGと同様にコントロールプレーンに割り当てられています。

TerraformでEKSにセキュリティーグループを追加する

CircuitはTerraformのaws_eks_clusterリソースでEKSクラスタを作成しているため、vpc_configのsecurity_group_idsにセキュリティーグループを追加しました。

resource "aws_eks_cluster" "eks_circuit" {
︙略
  vpc_config {
︙略
    security_group_ids      = ["sg-XXXXXX"]  # 追加のセキュリティーグループ
  }
︙略
}

Terraform Registry

追加のセキュリティーグループの設定

以下のルールを全てのSecrutiyGroupPolicyにアタッチして運用することを前提に設定しました。この設定により、EC2/Fargateのノードを気にすることなくPod単位のアクセス制限が運用できます。

  • 443ポートへのコントロールプレーン通信
    • Fargateノードのプロビジョニングを可能にするためです
  • TCP/UDP53ポートへのCoreDNS通信

SecurityGroupPolicyを書き換える

SecurityGroupPolicyのリソースに設定しているクラスタSGを、新しく作成したSGに書き換えて完成です。

apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
︙略
  securityGroups:
    groupIds:
      - 追加のセキュリティーグループ ← クラスタが変わっても書き換える必要なし
      - Pod独自のSG

これにより、次回以降のクラスタ更新では、セキュリティーグループの書き換えが不要になりました。

おわりに

クラスタSG、CoreDNS、VPC CNI、kubelet の動作について学ぶことができ、私にとって良い課題でした。

引き続き勉強します。

余談

Pod毎にセキュリティーグループをつけて、Liveness probe/Readiness probeを使用するためには、AmazonVPC CNIの設定でTCP Early Demux も無効にする必要があることに気がつかず結構ハマりました。

チュートリアル: Pods のセキュリティグループ - Amazon EKS

求人

私の所属するML Platformチームを含む、研究開発部Architectグループでは一緒に働く仲間を募集しています。

R&D MLOps/DevOpsエンジニア / Sansan株式会社

*1:サポート終了日を過ぎると、コントロールプレーンが自動的に更新されてしまいます。

*2:マイグレーションとも呼ばれているようです

© Sansan, Inc.