はじめに
普通にできるから帰るhttps://t.co/gUtj3qfxh3
— nishipy (@iamnishipy) 2019年6月11日
やりたいこと
今回やりたいことは、以下の通りです。
- AWSアカウントは2つあるとする
- AWSアカウント①にEKSクラスタがある
- AWSアカウント②にECRリポジトリがある
- AWSアカウント①のEKS上のKubernetesクラスタに対してコンテナをデプロイする際に、AWSアカウント②のECRリポジトリからコンテナイメージをpullしたい
前提知識
ECR
Amazon Elastic Container Registry (Amazon ECR) は、Dockerレジストリのマネージドサービスです。レジストリは、AWSアカウントごとに用意されるので、今回のように別のAWSアカウントのリソースからアクセスしようとすると、少し設定が必要です。
EKS
Amazon Elastic Container Service for Kubernetes(Amazon EKS)は、Kubernetesのマネージドサービスです。現状は、コントロールプレーン(マスターノード)のみが、AWSのマネージドで提供されているようです。ワーカーノードはマネージドではなく、実態はEC2が動いています。
実現方法
2パターンまとめます。他にもあれば教えてください。
方法1. k8sのSecretを利用
Secretの生成
1つ目は、k8sのSecretを生成し、レジストリへの認証情報を埋め込む方法です。ECRのみならず、自前のDockerレジストリを利用する場合にも有効です。Dockerレジストリ認証用のSecretの生成については、以下のドキュメントが参考になります。
今回はECRへの認証トークンを、Secretに埋め込むことになるのですが、1つ懸念点があります。それは、ECRの認証に必要なトークンは、取得から12時間しか有効でない点です。したがって、ECR認証トークンとSecretを定期的に更新する必要があります。
CronJobで、ECR認証トークンとSecretを定期的に更新
ECR認証トークンとSecretを定期的に更新する仕組みについて、ググってみると、CronJob
で実現できるみたいです。以下は、Githubからの引用です。
CronJobによりデプロイするSecret更新用のコンテナは、aws cli
とkubectl
が利用できるように適切なコンテナイメージから作成すれば十分です。また、Secretの作成や削除が可能なService Account
を同時に作成し、コンテナにマウントしておく必要がありそうです。デフォルトのService Account
では、Secretの作成や削除はできません。
方法2. AWSのIAMを利用
正直言うと、ECRをレジストリとして使う場合は、今から紹介する方法が良いと思います。こっちの方が簡単だし、CronJob
も不要です。
ワーカーノードの設定
Kubernetesの公式ドキュメントによると、
Kubernetes has native support for the AWS EC2 Container Registry, when nodes are AWS EC2 instances.Simply use the full image name (e.g.
ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag
) in the Pod definition.
All users of the cluster who can create pods will be able to run pods that use any of the images in the ECR registry.
The kubelet will fetch and periodically refresh ECR credentials.It needs the following permissions to do this:
- ecr:GetAuthorizationToken
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:GetRepositoryPolicy
- ecr:DescribeRepositories
- ecr:ListImages
- ecr:BatchGetImage
つまり、KubernetesクラスタのワーカーノードがEC2である場合、ECRとの接続をネイティブはサポートされており、ワーカーノード(EC2)に適切なIAMロールを設定しておけばよいです。あとはマニフェストファイルに、pullしたいイメージのURIをそのまま書けば、コンテナが生成できます。
また、方法1で発生する「ECRの認証に必要なトークンは、取得から12時間しか有効でない」問題は、方法2では気にしなくてよいです。ECR認証情報の取得や更新は、ワーカーノードのkubelet
くんが代行してくれるみたいです。
ECRリポジトリの設定
仮にECRとEKSを同じAWSアカウントで使っていれば、おそらく上で行ったワーカーノードの設定だけで完結します。しかし、今回はAWSアカウントが2つあり、「AWSアカウント①のEKS上のKubernetesクラスタに対して、コンテナをデプロイする際に、AWSアカウント②のECRリポジトリからコンテナイメージをpullしたい」ので、ECR側にも設定が必要です。
具体的には、ECRリポジトリに対して、セカンダリアクセスを許可するリポジトリーポリシーを設定します。以下のAWS公式ドキュメントに、設定例が書いてあります。
さいごに
ECRは、設定次第では公開Dockerレジストリとして使えなくもないと言うことがわかりました。方法1を知ったおかげでCronJob
を使う練習にはなりましたが、せっかくAWSを使うなら方法2のようにIAMを利用するのがスマートな気もします。
AWSもKubernetesも奥が深いと言うか、進化がはやすぎて追いつける気がしませんが、今後も積極的に使っていき、あわよくば記事にまとめます。
以上.
コメント