Amazon Elastic Kubernetes Service(Amazon EKS)のクラスターは、IAMを使って認証するわけですが、IAMはAWS SSOなどを利用することでID情報を外部から取得できます。したがって、Google Workspaceのアカウントなど外部IDでEKSクラスターを認証できます。
実際に運用するには、AWSアカウント構成など考慮点がたくさんあるかと思いますが、この記事では、AWSのルートアカウントでAWS SSOを有効化し、ID情報をGoogle Workspaceから取得して、そのAWSアカウントでEKSクラスターを作成して認証に使ってみます。
AWS SSOの設定
まず、AWS SSOを設定して、Google Workspaceで管理しているアカウントでAWSのサービスにアクセスできるようにします。
いくつかUIに違いがあるだけで、ほぼ以下のブログに記載があるとおりですが、AWS SSOまわりの設定は後ほど本記事でも補完しようと思います。
EKSクラスターの作成
EKSクラスター管理ユーザーの作成
まず、EKSクラスターを構築、管理するユーザーを用意します。前述のブログにある「Manage Users and Permissions」の手順で、手動でアカウントを作成できます。実際の運用ではssosyncでアカウントを同期するのがいいと思います。
手動でアカウントを作成する際に一つだけハマったのはAWS SSOのユーザーを追加する部分で、 「username
をGoogleアカウントのプライマリーメールアドレスにする」です。これを忘れると、ログイン時にInvalid MFA credentials Your MFA credentials were incorrect. Please check your device and try again.
というエラーが発生します。
eksctlの実行には、AWS管理ポリシー AdministratorAccess
またはeksctlのサイトに記載がある権限が必要なので、このユーザーに割り当てておきます。
SSO ログイン
AWS CLI v2では、以下のようにSSOでログインできます。
## AWS SSOの設定
$ aws configure sso
$ aws sso login
詳細は以下をご確認ください。
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
EKSクラスターの作成
EKSクラスター管理ユーザーでSSOログインしたら、EKSクラスターを作成します。この記事ではeksctlを利用します。
しかし、eksctlは現時点で、aws configure ssoで作成したAWS SSOログイン情報を理解しないので、そのままでは以下のようなエラーで利用できません。
$ eksctl create cluster -f cluster.yaml
[!] retryable error (RequestError: send request failed
caused by: Put "http://169.254.169.254/latest/api/token": dial tcp 169.254.169.254:80: connect: host is down) from ec2metadata/GetToken - will retry after delay of 3.561742848s
この記事では、eksctlをAWS SSO環境下で利用するためにaws2-wrapを使ってみました。このツールは、terraform
やeksctl
などの、AWS SSOクレデンシャルに対応していないツールでもAWS SSOクレデンシャルを使えるようにしてくれるラッパーツールです。
# aws2-wrapのインストール
$ python3 -m pip install aws2-wrap
$ aws2-wrap eksctl create cluster -f ./cluster.yaml
[ℹ] eksctl version 0.33.0-rc.0
[ℹ] using region ap-northeast-1
[ℹ] setting availability zones to [ap-northeast-1c ap-northeast-1d ap-northeast-1a]
[ℹ] subnets for ap-northeast-1c - public:192.168.0.0/19 private:192.168.96.0/19
[ℹ] subnets for ap-northeast-1d - public:192.168.32.0/19 private:192.168.128.0/19
[ℹ] subnets for ap-northeast-1a - public:192.168.64.0/19 private:192.168.160.0/19
[ℹ] using Kubernetes version 1.18
...
これで、AWS SSOを使ってGoogleアカウントでログインしたユーザーでEKSクラスターが作成されました。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-34-136.ap-northeast-1.compute.internal Ready <none> 6m24s v1.18.9-xxx
ip-192-168-83-237.ap-northeast-1.compute.internal Ready <none> 6m39s v1.18.9-xxx
EKSクラスターに開発者アカウントを追加する
次に、開発者アカウントをこのEKSクラスターに追加してみます。EKSクラスターの管理ユーザーを作成したときと同様、前述のブログにある「Manage Users and Permissions」の手順で、手動でアカウントを作成します。このユーザーにはEKSクラスターのDescribe、EKSクラスター認証のためのトークン取得の権限などが必要です。ここでは、ReadOnlyAccess
を割り当てますが、実際には、適切に権限を設定する方がいいでしょう。
開発者アカウントを、EKSクラスターに追加する
上記で作成したユーザーにはIAMロールが割り当てられています。具体的なIAMロールは、IAMのコンソールから、アクセス権限セットの名前でロールを検索すると表示されます。このIAMロールを、EKSクラスターのaws-auth
に設定します。
このときセットするロールのフォーマットは、 arn:aws:iam::<ACCOUND_ID>:role/<ROLE_NAME>
となります。
$ kubectl -n kube-system edit cm aws-auth
apiVersion: v1
data:
mapRoles: |
....
- rolearn: arn:aws:iam::<ACCOUND_ID>:role/<ROLE_NAME>
username: developer1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
EKS上のユーザーに権限を割り当てる
この開発者アカウントに、dev1
というNamespaceを管理する権限を割り当ててみます。
$ kubectl create ns dev1
$ kubectl -n dev1 create rolebinding dev1-developer1 --clusterrole admin --user developer1
実際に開発者アカウントでログインし、Kubernetesリソースを作成できることを確認します。
## 開発者アカウントでのログインを設定
$ aws configure sso
# kubectl更新
$ aws --profile <AWS SSOログイン用プロファイル> eks update-kubeconfig --name <EKSクラスター名>
# Kubernetesリソースを作成してみる
$ kubectl run nginx --image=nginx -n dev1
$ kubectl get pods -n dev1
# 他のリソースにアクセスできないことを確認
$ kubectl get pods -n default
Error from server (Forbidden): pods is forbidden: User "developer1" cannot list resource "pods" in API group "" in the namespace "default"
まとめ
この記事では、Google Workspaceなど、AWS外のIDを利用してEKSクラスターに認証するために、簡単な手順を記載してみました。IAMと連携できる様々なIDプロバイダーも同じように利用できますので、試してみていただければと思います。