一回EKSのFargateを試してみようと思っていたので、新年早々やってみた。せっかくなのでEKS+FargateプロファイルをTerraformから作成する。他の事例だとeksctlから構築するパターンが多いようだが、最近Terraformいじってるし、eksctl嫌いなもんで。(削除時にハマったこともあり)

 

その前に Fargateのことをよく分かっていなかったので基本項目をあげておく。以下は2022年1月現在の仕様・制約事項。

  1. 「面倒なEC2の管理が不要!」と大っぴらに言われているが、Fargateでも最低限のノードグループは必要。
  2. Fargate Pod用のノードが起動するサブネットはプライベートサブネットであること。
  3. 2.のPodがコントロールプレーンと通信するためVPC外へ出る必要がある。NATゲートウェイ/プロキシ/VPCエンドポイントいずれかの方式で外部への通信経路を確保する。
  4. Fargateプロファイルを設定する。(大雑把に言うとここでFargateが動作する環境を定義する)
  5. FargateにおけるPodとノードの関係は常に1:1となる。(1ノードに複数のPodは起動できない)
  6. Fargate Pod専用のIAMロールが必要。(4.で指定)
  7. Fargateと通常のEKSワーカーノードの共存が可能。

 

実は 1.については知らなかったので、EKSクラスタ起動してFargateプロファイル設定すればPodが起動できるもんだと思っていた。EC2がいらないってウソやんけ…。当初その辺りで躓いたのだが、余計な失敗ネタは置いといて成功パターンを書いておく。

 

で、Terraformのコード載せる前に基本前提について。上記の制約があることから、最小限以下の構成を用意しておく。それらもTerraformで作るのであればそれでもいいが、自分はさすがに面倒見切れないので既存のアイテムを流用した。VPCはすでにある想定で:

  1. AZにまたがったパブリックサブネット
  2. AZにまたがったプライベートサブネット
  3. NATゲートウェイ(2.のサブネットが外部と通信するため)
  4. ①EKSクラスタ ②ノードグループ ③Fargate Pod用の各IAMロール
  5. ノードグループリモートアクセス用のセキュリティグループ
  6. EKSクラスタ用のセキュリティグループ
  7. ノードグループ用のssh key

 

Fargateだろうが何だろうが、これらの前提アイテムは別途構築しなければならないのである。「eksctlならよしなに作ってくれるから楽!」とか言ってても、PoCならともかく実運用時にeksctlでお任せ構築なんてあり得ないのである。夢は見させてくれないのである。

 

IAMロールについて

①クラスタ②ノード用ロールは既存のを使用した。ちなみにそれぞれ必要なポリシーは、①はAmazonEKSClusterPolicy、②はAmazonEKSWorkerNodePolicy、AmazonEC2ContainerRegistryReadOnlyとなる。②については、PoC時は最小限の権限でよいが本来Podが必要とするサービスの権限をすべてポリシーに追加する。

参考
Amazon EKS クラスター の IAM ロール
Amazon EKS ノード の IAM ロール

Fargate Pod用ロールはCLIから新規作成した。信頼ポリシー用JSONを用意してコマンド実行。

 

eks-fargate-pods-policy.json(信頼ポリシー用JSON)

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {
      "Service": "eks-fargate-pods.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
  }
}

 

# ロール作成
$ aws iam create-role \
     --role-name AmazonEKSFargatePodExecutionRole \
     --assume-role-policy-document file://eks-fargate-pods-policy.json

# ロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name AmazonEKSFargatePodExecutionRole\
    --policy-arn "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy"

 

Teraraformコード

以降、Terraformコード。今回、前提条件となるネットワーク環境、IAMロール等はTerraform外で作成済みのアイテムを指定している。

eks.tf

#############################################
# EKS Cluster
#############################################

resource "aws_eks_cluster" "eks-cluster" {
  name     = "eks-test-cluster"
  role_arn = var.cluster-role

  vpc_config {
    subnet_ids         = [var.public-a, var.public-c]
    security_group_ids = [var.cluster-sg]
  }
}

output "endpoint" {
  value = aws_eks_cluster.eks-cluster.endpoint
}

output "kubeconfig-certificate-authority-data" {
  value = aws_eks_cluster.eks-cluster.certificate_authority[0].data
}

#############################################
# EKS Node Group
#############################################

resource "aws_eks_node_group" "eks-node" {
  cluster_name    = aws_eks_cluster.eks-cluster.name
  node_group_name = "eks-test-node"
  node_role_arn   = var.node-role
  subnet_ids      = [var.private-a, var.private-c]
  ami_type        = "AL2_x86_64"
  instance_types  = ["t3.small"]

  labels  = {
    type  = "fargate-test"
  }

  remote_access {
    ec2_ssh_key               = var.keyname
    source_security_group_ids = [var.remote-sg]
  }

  scaling_config {
    desired_size = 2
    max_size     = 2
    min_size     = 2
  }
}

#############################################
# EKS Fargate Profile
#############################################

resource "aws_eks_fargate_profile" "fargate-test" {
  cluster_name           = aws_eks_cluster.eks-cluster.name
  fargate_profile_name   = "test-profile"
  pod_execution_role_arn = var.pod-role
  subnet_ids             = [var.private-a, var.private-c]

  selector {
    namespace = "fargate-test"
  }
}

 

以下、変数参照先のvariables.tf。最近のTerraform PoCではtfvarsを使っていたが、今回は単純なケースなのでこれ一本で行く。

variables.tf

#############################
# public subnet-a
#############################
variable "public-a" {
  default = "subnet-xxxxxxxxxxxxxxxxx"
}

#############################
# public subnet-c
#############################
variable "public-c" {
  default = "subnet-yyyyyyyyyyyyyyyyy"
}

#############################
# private subnet-a
#############################
variable "private-a" {
  default = "subnet-wwwwwwwwwwwwwwwww"
}

#############################
# private subnet-c
#############################
variable "private-c" {
  default = "subnet-zzzzzzzzzzzzzzzzz"
}

#############################
# cluster security group
#############################
variable "cluster-sg" {
  default = "sg-xxxxxxxxxxxxxxxxx"
}

#############################
# eks node security group
#############################
variable "remote-sg" {
  default = "sg-xxxxxxxxxxxxxxxxx"
}

#############################
# cluster IAM role
#############################
variable "cluster-role" {
  default = "arn:aws:iam::012345678910:role/eks-cluster-role"
}

#############################
# node IAM role
#############################
variable "node-role" {
  default = "arn:aws:iam::012345678910:role/eks-node-group-role"
}

#############################
# pod IAM role
#############################
variable "pod-role" {
  default = "arn:aws:iam::012345678910:role/AmazonEKSFargatePodExecutionRole"
}

#############################
# eks node key
#############################
variable "keyname" {
  default = "eks-workeernode-key"
}

 

この状態で terraform apply したところ、十数分後にEKSクラスタ/ノードグループ/Fargateプロファイルの作成が完了した。

EKS EKS EKS

 

最後のFargate Profile -> [Pod selectors]は、Fargate上で実行させたいPodの条件が設定されている。上記の場合Namespaceに[fargate-test]を指定しているため、Kubernetes上のfargate-testネームスペースにおいてFarget Podが実行されるようになる。

 

ではようやく、Fargate Podを起動してみる。…といきたいが、長くなるので次回に持ち越し。

 

参考
Getting started with AWS Fargate using Amazon EKS
【AWS】 EKS on Fargate のクラスタを構築してみる
EKS on Fargateの特徴、通常のEKSとの違いは何か?(第1回)
Amazon Fargate for Amazon EKSを試してみた #reinvent
なんとなく「Fargate for EKS」が分かった気になる? ~ いろいろなギモンを調べてみた ~ #reinvent

 

三島 三島 三島 三島

 

続きは以下。
EKS FargateクラスタをTerraformで作成する(2)


関連がありそうな記事