kube2iamをTerraformとHelmfileでデプロイする
Kubernetes workerをEC2インスタンスで実行する場合,何も設定しないとPodはEC2インスタンスのIAMロールを利用します.このままでは,攻撃者が悪意のあるイメージを利用して情報漏洩や破壊を行うリスクがあります.kube2iamを利用すると,Podに適切なIAMロールを割り当てることが可能です.
本稿では,Amazon EKSで以下を利用する方法を説明します.
ここでは例として,S3バケットの読み取りが必要なアプリケーションをPodで実行するケースを考えます.
workerインスタンスへのIAMポリシーの割り当て
kube2iamはAssume Roleという仕組みを利用してPodにIAMロールを割り当てます.Assume Roleに必要なリソースは別のモジュール(kube2iam
)で定義します.
# kube2iam/main.tf variable "worker_iam_role_name" { description = "Name of the IAM role of the Kubernetes worker" } data "aws_iam_role" "worker" { name = var.worker_iam_role_name } resource "aws_iam_role_policy" "this" { role = data.aws_iam_role.worker.id name_prefix = "kube2iam" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Resource": "*" } ] } EOF } data "aws_iam_policy_document" "assume_role_policy" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } principals { type = "AWS" identifiers = [data.aws_iam_role.worker.arn] } } } output "assume_role_policy" { description = "JSON string of IAM policy for Assume Role" value = data.aws_iam_policy_document.assume_role_policy.json }
上記のkube2iam
モジュールを利用して,Assume Roleを許可するIAMポリシーをworkerインスタンスに割り当てます.terraform-aws-eks module を利用している場合は以下のように定義します.
module "kube2iam" { source = "./kube2iam" worker_iam_role_name = module.eks.worker_iam_role_name }
S3アクセスのIAMロールの作成
S3の読み取りアクセスを許可するIAMロールを作成します.ここでは簡単のため,AWSであらかじめ定義されているポリシーを利用します.
resource "aws_iam_role" "s3_readonly" { name = "s3_readonly" assume_role_policy = module.kube2iam.assume_role_policy } resource "aws_iam_role_policy_attachment" "s3_readonly" { role = aws_iam_role.s3_readonly.id policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess" }
実際には,IAMロールに利用目的を表す名前を付けた方がよいでしょう.例えば,GitLab Runnerであれば gitlab_runner_build_app
だったり,アプリケーションであれば app_frontend
といった感じです.
Helm chartのデプロイ
stable/kube2iamをデプロイします.
releases: # https://github.com/helm/charts/tree/master/stable/kube2iam - name: kube2iam namespace: kube-system chart: stable/kube2iam values: - host: iptables: true # https://github.com/jtblin/kube2iam#iptables interface: eni+ extraArgs: # https://github.com/jtblin/kube2iam#base-arn-auto-discovery auto-discover-base-arn: "" rbac: create: true
kube2iamはiptablesを利用してPodの通信を横取りします.amazon-vpc-cniを利用している場合は,上記のようにインタフェース名に eni+
を指定します.Calicoを利用している場合は cali+
になります.詳しくはkube2iamのiptablesセクションを参照してください.
Pod annotationによるIAMロール割り当ての確認
kube2iamを利用すると,Podに iam.amazonaws.com/role
アノテーションを付与するとIAMロールが割り当てられるようになります.以下の例ではPodに s3_readonly
というIAMロールを割り当てています.
apiVersion: v1 kind: Pod metadata: annotations: iam.amazonaws.com/role: s3_readonly spec:
ここでは,以下のコマンドを実行して動作確認を行います.
kubectl run s3 -i --rm --image fstab/aws-cli --restart=Never --overrides '{"metadata":{"annotations":{"iam.amazonaws.com/role":"s3_readonly"}}}' -- /home/aws/aws/env/bin/aws s3 ls
S3バケットの一覧が表示されれば成功です.
kube2iamが適切に設定されていない場合,PodはworkerインスタンスのIAMロールを利用してしまうため,以下のエラーがでます.
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
アノテーションに指定したIAMロールが存在しない場合,以下のエラーが表示されます.
Unable to locate credentials. You can configure credentials by running "aws configure".
アノテーションを指定しない場合は何も割り当てられません.
最後に,動作確認用に作成した以下のIAMロールを削除しておきましょう.
resource "aws_iam_role" "s3_readonly" { name = "s3_readonly" assume_role_policy = module.kube2iam.assume_role_policy } resource "aws_iam_role_policy_attachment" "s3_readonly" { role = aws_iam_role.s3_readonly.id policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess" }