はじめに
実務においてEKSクラスターへのアクセス制御について理解が浅いと感じたため、深堀りしていこうと思います。
EKSクラスターへのアクセス制御についてはConfigMap
とEKS API
という二つの方法が存在します。
2023年12月18日のアップデートがあるまではConfigMap
による制御のみでした。
しかし、アップデートしたことにより、より簡素化されたEKS API
という方式でKubernetesクラスターへアクセスできることとなりました。
このConfigMap
とEKS API
の違いについてまとめた上でEKS APIのアクセスについて解説します。
結論
いきなり結論です。
ConfigMap
AWS IAMユーザまたはロールとKubernetes上のユーザやグループとマッピングを行い、EKSクラスターからEKSリソースへのアクセスをする必要がある。
EKS API
AWSのIAMユーザやロールに対してKubernetesの権限を設定することができる。
ConfigMapとEKS APIの違いについて
ConfigMapとは
Kubernetes APIにアクセスするための認証/認可ではaws-auth
を使用し、AWSのIAMユーザやロールとKubernetesのユーザやロールをマッピングして権限設定する必要があります。
図で表すと以下のようになります。
- AWS IAMユーザまたはロールがkubeconfigファイルを使用してEKSで稼働している
kube-apiserver
へリクエスト - kube-apiserverはリクエストを処理する前にリクエストしてきたユーザやロールを認可する前に、
kube-system
のネームスペースに存在するaws-auth
ConfigMapを参照 - ConfigMapに基づいて、IAMユーザまたはロールをKubernetesのユーザやグループにマッピング
- マッピングされたKubernetesユーザやグループが適用され、
kube-apiserver
がリクエストに対して適切な権限を確認し、AWS リソースへの操作を実行
EKS APIとは
AWSで以下4つの権限を用意しており、これらの権限をIAMユーザまたはロールにアタッチすることで、EKSクラスターへのアクセスを制御します。
- AmazonEKSClusterAdminPolicy (EKSサービスそのもののリソースに対する管理権限: EKSクラスターの作成、更新、削除、クラスターに関連するIAMロールやポリシーの管理、EKSサービスに関連する他のAWSリソースの管理が可能となる)
- AmazonEKSAdminPolicy (EKSクラスター内部での管理者権限に相当し、全てのネームスペースでのリソース作成、更新、削除、クラスター設定の変更、リソースの追加及び削除などが可能となる)
- AmazonEKSEditPolicy
- AmazonEKSViewPolicy
動作確認
クラスター構築準備
Amazon Linux2023のAMIを使用したEC2インスタンスを起動し、EKSクラスターを作成します。
※EC2インスタンスの作成方法については省略します。
以下のAWS公式ドキュメントを参照しながらeksctl1をダウンロードします。
1.eksctlの最新リリースをダウンロードする
$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
2.ダウンロードしたバイナリを/usr/local/binに移動する
$ sudo mv /tmp/eksctl /usr/local/bin
3.ダウンロード確認
$ eksctl version
4.kubectlインストール (https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)
$ curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.30.0/2024-05-12/bin/linux/amd64/kubectl
5.チェックサム確認
$ curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.30.0/2024-05-12/bin/linux/amd64/kubectl.sha256
6.バイナリへの実行アクセスを許可する
$ chmod +x ./kubectl
7.バイナリをPATHのフォルダにコピーする
$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
8.シェルを開いたときに設定されるようにシェルの初期化ファイルに$HOME/binパスを追加
$ echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
9.以下yamlファイルでクラスターを作成する (既存VPCおよびサブネットを指定しないとVPC, Subnetなど全てゼロから構築されてしまうため、自身で使用しているVPCやサブネットを使用する場合には明示的に指定します)
$ eksctl create cluster -f cluster.yml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: sandbox-cluster
region: ap-northeast-1
vpc:
id: vpc-xxxxxxxxxxxxxxx # 自身のVPC IDに置き換えてください
subnets:
private:
ap-northeast-1a:
id: subnet-xxxxxxxxxxxxxxx # 自身のサブネットIDに置き換えてください
ap-northeast-1c:
id: subnet-xxxxxxxxxxxxxxx # 自身のサブネットIDに置き換えてください
fargateProfiles:
- name: fp-default
selectors:
- namespace: default
- namespace: kube-system
10.kubeconfigファイルを作成し、EKSクラスターとのやり取りをできるようにする
$ aws eks update-kubeconfig --region ap-northeast-1 --name sandbox-cluster
kubeconfigは~/.kube/config
に作成されます。
クラスター構築後
クラスター構築後のアクセスポリシーを確認してみます。
eksctl-sandbox-cluster-clus-FargatePodExecutionRole
はEKSが自動的に作成したIAMロールです。
このロールはEKS Fargate Podがクラスター内で実行される際に使用されるIAMロールで、PodがECRからコンテナイメージを取得したり、その他のAWSサービスにアクセスしたりするための権限です。
Administrator
のプリンシパルにはAmazonEKSClusterAdminPolicy
がアタッチされ、EKSクラスター内の管理者権限が付与されます。
ただし、このままではEKSクラスターとはまだやりとりできません。
冒頭で説明したように、EKSクラスターのAPIにリクエストを送る際にはkubeconfigファイルを作成し、kubeconfigファイルを使用してリクエストする必要があります。
試しに、kubeconfigファイルを作成しない状態でkubectlコマンドでEKSクラスター(kube-apiserver)へリクエストを投げてみましょう。
$ kubectl get nodes
E0701 05:46:57.542348 4454 memcache.go:265] couldn't get current server API group list: Get "https://D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
E0701 05:46:57.544274 4454 memcache.go:265] couldn't get current server API group list: Get "https://D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
E0701 05:46:57.545485 4454 memcache.go:265] couldn't get current server API group list: Get "https://D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
E0701 05:46:57.546774 4454 memcache.go:265] couldn't get current server API group list: Get "https://D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
E0701 05:46:57.548003 4454 memcache.go:265] couldn't get current server API group list: Get "https://D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
Unable to connect to the server: dial tcp: lookup D7D0E33219BB97104A4A840CB72A87DD.gr7.ap-northeast-1.eks.amazonaws.com on 10.0.0.2:53: no such host
上記のように"サーバーに接続できません"といったエラーが返されます。
kubeconfigファイルを作成して再度アクセスしてみます。
# kubeconfigファイルの作成
# 以下AWS CLIコマンドでKubernetes Configファイルを作成
$ aws eks update-kubeconfig --name <cluster_name> --region <region>
Updated context arn:aws:eks:ap-northeast-1:{AccountID}:cluster/sandbox-cluster in /home/ec2-user/.kube/config
# 再度アクセスしてみます
$ kubectl get nodes
# リクエストに対するレスポンスが返ってきました -> 現状Nodeを作成しているわけではないので"No resorces found"となります
No resources found
kubeconfigファイルを作成すると~/.kube配下にconfigファイルが作成され、認証情報が登録されます。
$ cat ~/.kube/config
一部マスクしますが、certificate-authority-data以下に記載されている(マスクしている箇所)箇所がKubernetesクラスターのAPIサーバ(kube-apiserver)にアクセスする際のサーバ証明書を検証するためのCA証明書情報です。
EKSクラスターを作成したIAMユーザ以外をアクセスエントリに追加する場合
クラスターの[アクセス]タブから[アクセスエントリの作成]ボタンをクリックします。
IAMプリンシパルに登録したいIAMプリンシパルARNを選択します。
ユーザが利用するIAMプリンシパルにはタイプを[スタンダード]に設定します。
アクセスポリシーを追加 - オプションでポリシー名[AmazonEKSClusterAdminPolicy] (EKSクラスターを作成したIAMユーザと同じポリシー)を追加
これでポリシーの追加が追加されます。
AWS CLIでアクセスエントリーに追加されたことを確認します。
$ aws eks list-access-entries --cluster-name sandbox-cluster
{
"accessEntries": [
"arn:aws:iam::xxxxxxxxxxxx:role/eksctl-sandbox-cluster-clus-FargatePodExecutionRole-dMNVotqRuHbj",
"arn:aws:iam::xxxxxxxxxxxx:user/Administrator",
"arn:aws:iam::xxxxxxxxxxxx:user/develop-user"
]
}
クラスターの削除
諸々確認が終わり、もうクラスターは必要ないという場合には以下のコマンドでクラスターの削除をすることができます。
$ eksctl delete cluster --name <clustername>
最後に
今回はEKSクラスターへのアクセスEKS API/ConfigMapについての違いを理解し、EKS APIによるアクセスを行ってみました。
本記事内ではEKSクラスターを作成したユーザにおけるEKSクラスターのアクセスについての検証ができませんでしたが、別途機会を設けて試してみたいと思っています。
-
EKS専用のコマンドラインツールであり、EKSクラスターを構築することができます。 ↩