EKSに入門した

2024/04/30に公開

動機

Kubernetes未経験ながらも、EKSの構成を考える機会があったので手を動かしながら得た知識を吐き出したくなった。

構成としては非常に単純で、Webアプリケーションを想定して、複数のnamespaceにあるnginxを単一のALBからアクセスできるようにするだけ。
そのなかでのメモだったり、いくつか比較したものがあったので主にそこらへんについて残す。

成果物

https://github.com/anizozina/eks-entry

EKSはどこで動くか

EKSがそもそも管理しているのはControl Plane。
Data Planeはユーザーの管理しているVPC内で動くが、EKS自体はAWSのネットワークに属する。

Cluster Endpoint

terraformのeks module上だと cluster_endpoint_public_access で表現されている設定部分。
ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cluster-endpoint.html

エンドポイントのパブリックアクセスが有効化されている場合は、公開されているエンドポイントにIAMによる認証・認可を行ってEKSのControl Planeにアクセスするような構成となる。
プライベートアクセスのみが有効化されている場合は、直接手元の環境からはアクセスできないので踏み台サーバーやCode Build等を経由して接続しないとダメそう。

Node Group vs Fargate

EKSでは実行環境のNodeとしてEC2インスタンスとFargateが選択できる。
Fargateの場合、サーバーレスとなりOSに近いレイヤの管理は不要となる。
EC2の場合はセキュリティパッチの適用など考えることが増える。
明確な違いとしてはFargateで動作させる場合は1つのNodeに対して1つのPodしか割り当てられない。
それもあって、Fargateは割高となるらしい。
ref. https://tech.uzabase.com/entry/2022/12/01/175423

単純なアプリで、運用に人手をかけられないが、ある程度コストが嵩んでも問題ないという状況であればFargateが望ましそう。
複雑なことをしたり、アプリケーションの規模が巨大でPodあたりのコストを抑えたい場合はEC2が望ましいのかなという感覚。

Fargateの制約事項を見ていると単純に載せ替えるのは骨が折れそうなので最初にちゃんと考えておきたいかも。
ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/fargate.html

Config Map vs Access Entry

terraformのeks module上だと authentication_mode で表現されている設定部分。

ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/grant-k8s-access.html

Config Map(aws-auth)が以前からある方法で、Access Entry(API)が比較的新しい方法。
いずれもClusterにアクセスできるIAM Principleの制御である。
現時点(2024-04-30)では、Access Entryが推奨されている。

ConfigMapはKubernetesのオブジェクトであり、IAMユーザーとKubernetes上のユーザーを紐づけて権限を管理する必要がある。
ref. https://dev.classmethod.jp/articles/eks-cluster-access-control/

この構成のデメリットは、IaCを使用してアクセス権の設定を変更しづらい点にあるらしい。また、Clusterを生成したユーザーが暗黙的にマスター(system:master)となり、トラブルは発生することがあるらしい。
ref. https://dev.classmethod.jp/articles/eks-access-management-with-iam-access-entry/

Access EntryはAWSの仕組みのうえで完結させられるので、IaCで設定できる上に自由度が高い。
任意のIAM Principalに対してClusterへのアクセスの範囲と権限を付与できる。
例えば特定のnamespaceに対してadmin権限を与えたり、全体的なread権限を与えるなど。
ref. https://aws.amazon.com/jp/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/

terraform経由で作成したClusterだと、作成したPrincipleであってもaccess entryに値がないとアクセスできなかった。

AWS Load Balancer Controler

ALBCは、Serviceとの境界にApplication Load Balancerを設置してくれるControllerである。
大量のトラフィックが来ても適切に捌けるマネージドなALBを利用することで、考慮することを減らしながら運用できるようになる。

ALBCはNodeにControllerをDeployして、Ingress/Serviceのリソースが出来たらALBを生成する動きを取る。
ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html

そのまま動かすと、ALBCはnamespaceに対して1つのALBを作ってしまうので、今回はTarget Groupを用いて異なるNamespaceでも単一のALBを動かしてPathによるRoutingによって振り分けを実現している。
(厳密に言うと、Pathの先で考慮すべきことができていないので動かないんだが、、、nginx ingressのようにrewrite pathをしたい。。。)

ALBCはkubernetesのService Account(とそれに紐づけられたIAM Policy)によって動く。
めちゃめちゃ詰まったが、公式ドキュメントで eksctl create iamserviceaccount で隠蔽されすぎてterraform / helmで表現するのが難しかった。
実行しているものの詳細は以下の通り

  1. kubernetesのservice accountを作成
  2. 信頼関係に必要なOIDCの情報等を収集する
    • つまり、ClusterでOIDCの設定が有効化されている必要がある
  3. Service AccountがOIDC経由でClusterにアクセスできるようにしたIAM Roleを作成
  4. Service Accountのannotationに上記IAM Roleをアタッチ

ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/associate-service-account-role.html

今回のケースではterraform上ではIAM Roleの作成までを行い、helmによってservice accountの生成・Roleのアタッチをするようにしている。

Pod Identity Agent vs IAM Role for Service Account

ref. https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-identities.html

上記でIRSAを使用してALBCをアクセスさせていたが、多分それすらもいらなくなるのがPod Identity Agent。
OIDCを利用せず、Service AccountにRoleをマッピングさせることで、権限を最小に抑えつつPodのアクセスコントロールを実現できると言うもの。

今回は入れてみただけで使ってはいない。。。

おしまい

Kuberneteの知識もろくに持ってないままEKSを触り始めるとどっちの責務・機能の範囲なのか理解できなくなる。
今後知識ゼロからスタートする人は少なくともKubernetesにあるオブジェクトを一通り見てなんとなく理解してからEKSに入ることをお勧めする…。

Discussion