Terraform で EKS を作成してみたのでメモとして残しておきます。 サンプルは GitHub に置いてます。README 通りに進めればデプロイできます。不備があれば Issue や PR もらえると喜びます。
なぜeksctlじゃないのか
ざっと理由を挙げると以下です。
- EKS Cluster に関連しない AWS リソースの管理が複雑となる
- 細かいパラメータの指定ができない
- Security Group のルールとか Launch Templete のパラメータとか
誤っているとかあればブコメや Twitter で教えてください。 念の為に書いておくと、僕は eksctl を dis るつもりは全く無く、なんなら今でも検証用途でサクッと EKS Cluster 作りたい時は eksctl でやっています。 プロダクションで eksctl 使ってるよって人がいればどういう運用をしているのか聞いてみたいです。
Managed Node Groupを利用しない
Managed Node Group は便利ですが、様々な制約があります。( 2020/06/07 現在
全ては網羅していませんが、代表的なものを挙げると以下です。
特に UserData がカスタムできない点が痛いです。Docker や kubelet の Config を修正することができないほか、
kubelet を起動する際に --register-with-taints
オプションで Taints を割り当てることもできません。
Unmanaged Node Group の場合は UserData で bootstrap.sh
の引数として --register-with-taints
を渡すことが可能です。
その他の Issue については aws/containers-roadmap に挙がっていますので、これ欲しい!という機能があれば Issue を立てるか既存の Issue に +1 しましょう!
工夫したところとか
template_file
Data Sourceの利用
Terraform の template_file
Data Source を利用して Woker node の UserData を指定しました。
Worker node を作成した EKS Cluster に参加させる際に /etc/eks/bootstrap.sh
の引数で EKS Cluster 名を指定する必要があり、そこで template_file
を利用することで、ShellScript に EKS Cluster 名をハードコードせずとも動的に指定することが可能です。便利。
EKS最適化AMIのAMI IDをSSM Parameter Storeから取得
EKS 最適化 AMI の AMI ID は SSM Parameter Store に存在します。
以下の様に Data Source で SSM Parameter Store の情報を取得し、value を利用することが可能です。便利。
data "aws_ssm_parameter" "eks_optimized_ami_id" { name = "/aws/service/eks/optimized-ami/1.16/amazon-linux-2/recommended/image_id" } resource "aws_launch_template" "eks_worker_node_template" { . . . image_id = data.aws_ssm_parameter.eks_optimized_ami_id.value . . . }
ハマったとことか
殆どドキュメントに記載されている内容です。
Worker nodeが認識されない
$ kubectl get nodes
No resources found in default namespace.
様々な問題が考えられますが、僕の場合は Security Group に問題がありました。
Terraform で Cluster 用の Security Group を作成していましたが、aws_eks_cluster
Resource で security_group_ids
を指定していなかったことが原因でした。
下記の様に security_group_ids
を指定することで、EKS 上では Additional security groups として認識されます。
vpc_config { security_group_ids = [ aws_security_group.eks-cluster-sg-01.id ] subnet_ids = [ aws_subnet.public-a-01.id, aws_subnet.public-b-01.id, aws_subnet.protected-a-01.id, aws_subnet.protected-b-01.id ] }
Additional security groups は EKS Cluster 作成後は更新できないため、注意しましょう。( 僕は Cluster 再作成しました...
aws-auth
configMap のデプロイ漏れ
aws-auth
configMap のデプロイし忘れで Worker node が認識されませんでした。
API server endpoint accessの設定不備
kubectl
などでローカルマシンから EKS の API server endpoint に対してリクエストを行う場合、接続元 IP アドレスを制限することが可能です。
ドキュメントにも記載されていますが、IP 制限を行う場合は API server endpoint access の設定で Private からも許可する設定を行うか、Worker node がインターネットへ出る時の Public IP も Public access source whitelist に追加する必要があります。つまり、下記の設定だと Worker node と EKS Cluster の Control Plane ( kube-apiserver ) 間の通信ができません。
なので僕は下記の様に設定しました。これで Worker node と Control Plane 間の通信が可能となりました。
次は
ALB Ingress Controllerについて書こうかと思います。