Minikube, and LoadBalancer in “Pending” status

ServiceAccount from AWS IAM Role for Kubernetes Pod

We have Grafana Loki for logs, to which you need to connect AWS IAM Role with AWS IAM Policy, which gives access to AWS S3 bucket in which chunks and indexes will be stored (about setting up Loki itself with AWS S3 a little later in a separate post).

IAM roles for Kubernetes pods work the same way we do when we connect IAM roles to EC2 instances – a process inside the pod makes a request to the AWS API, and the AWS SDK or AWS CLI that makes the request makes the AssumeRole request , to which the IAM Role itself is transferred (see AWS: rotation of user IAM keys, EC2 IAM Roles and Jenkins).

To check how it will work in Kuber, let’s create a test IAM Role, ServiceAccount with the annotation of this role, and start a pod with this ServiceAccount.

Looking ahead – it still works in Loki itself due to some alternative reality, that is, even when you connect an already tested ServiceAccount to it – it crashes with errors. You will have to dig.

Documentation – IAM roles for service accounts.

The EKS cluster is deployed using the Terraform module aws_eks_clusterand the OpenID Connect (OIDC) provider should already be configured.

We go to the cluster page, find it OpenID Connect provider URL:

Or from the console:

aws –profile development –region us-west-2 eks describe-cluster –name dev_data_services –query “cluster.identity.oidc.issuer” –output text

Copy the URL without https://and check in IAM > Identity providers:

Okay, that’s it.

First, let’s create an IAM policy that gives rights to an AWS S3 bucket, then an IAM Role with a TrustedPolicy that allows you to perform an AssumeRole using the OIDC identity provider (IDP) of the cluster.

AWS IAM policy

We create a test policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBuckets"
            ],
            "Resource": [
                "arn:aws:s3:::development-dev-loki-object-store",
                "arn:aws:s3:::development-dev-loki-object-store/*"
            ]
        }
    ]
}

Add it to AWS IAM:

aws –profile development iam create-policy –policy-name test-iam-sa-pod-policy –policy-document file://test-iam-sa-pod-policy.json

Let’s move on to the role.

AWS IAM role та TrustedPolicy

Find the ARN of our Identity Provider:

The OIDC identity provider URL has already been found before:

aws –profile development –region us-west-2 eks describe-cluster –name dev_data_services –query “cluster.identity.oidc.issuer” –output text

Creating an IAM Role with the AWS CLI

We create a file with TustedPolicy, in Principal in which we specify the ARN of the IDP, and in the Condition the OIDC URL of the cluster to which we allow the request to be executed sts.amazonaws.com:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::638***021:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/537***A10"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "oidc.eks.us-west-2.amazonaws.com/id/537***A10:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

We create a role to which we pass this TrustedPolicy:

aws –profile development  iam create-role –role-name test-iam-sa-pod-role –assume-role-policy-document file://test-iam-sa-role-trusted-policy.json

We connect to it the IAM Policy with rights to S3, which was created earlier:

aws –profile development iam attach-role-policy –role-name test-iam-sa-pod-role –policy-arn=arn:aws:iam::638***021:policy/test-iam-sa-pod-policy

Create an IAM Role from the AWS Console

Or we also do it through the Amazon admin – we choose the type Web identity, Identity Provider cluster and Audience:

Add IAM Policy for S3:

We store:

We copy the ARN of the role:

Creating a Kubernetes ServiceAccount

We create a ServiceAccount manifest, in the annotation of which we indicate the ARN of the created role:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-iam-sa-pod-service-account
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::638***021:role/test-iam-sa-pod-role

And let’s go to the floor.

We add a description of the method through which serviceAccountName connect ServiceAccount, so the complete manifest will look like this:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-iam-sa-pod-service-account
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::638***021:role/test-iam-sa-pod-role
---
apiVersion: v1
kind: Pod
metadata:
  name: test-iam-sa-pod
  labels:
    app: test-iam-sa-app
spec:
  containers:
    - name: test-iam-sa
      image: amazon/aws-cli
      command: [ "/bin/bash", "-c", "--" ]
      args: [ "while true; do sleep 30; done;" ]
  serviceAccountName: test-iam-sa-pod-service-account

In the pod, we will use the docker image from the AWS CLI, which we will transfer to sleepto make it work after launch.

Let’s deploy ServiceAccount and Pod:

kk apply -f test-iam-sa-pod.yaml

serviceaccount/test-iam-sa-pod-service-account created

pod/test-iam-sa-pod created

We go into it:

kk exec -ti test-already-sa-pod — bash

And we check access to the basket:

bash-4.2# aws s3 ls development-dev-loki-object-store

PRE test/

Done.

Amazon Web Services,HOWTO’s,Kubernetes,Virtualization,AWS,

#ServiceAccount #AWS #IAM #Role #Kubernetes #Pod

Leave a Comment

Your email address will not be published. Required fields are marked *