You as an administrator running a Kubernetes cluster on AWS can use AWS IAM to manage users for Kubernetes access. You won’t need to manage separate list of users in Kubernetes. Authentication of users for Kubernetes access can be done by aws_iam_authenticator. AWS created the AWS IAM Authenticator, which allows you to have federated authentication using AWS Identity and Access Management (IAM).

Steps to setup:

Create AWS Kubernetes cluster using  kops cluster.yaml template. Follow the steps in this article BUT make these changes in cluster.yaml before creating the cluster-

> Add authentication: aws: {} as shown below. This will create aws_iam_authenticator pod in kube-system namespace in cluster.

spec: 
   api: 
     loadBalancer: 
       type: Internal 
   authorization: 
     rbac: {} 
   authentication:
     aws: {}
   channel: stable 
   kubeDNS:

 

> Add “authenticationTokenWebhook: true” and “auhtorizationMode: Webhook” under kubelet

iam: 
    allowContainerRegistry: true 
    legacy: false
kubelet:
    anonymousAuth: false
    authenticationTokenWebhook: true
    authorizationMode: Webhook
kubernetesApiAccess: 
- 0.0.0.0/0

Now create the cluster using the updated kops cluster.yaml file.

Login to Bastion Server

Verify the status of the cluster by running the validate command:

kops export kubecfg --name ${CLUSTER_NAME} --state ${STATE} 
kops validate cluster --name ${CLUSTER_NAME} --state ${STATE}

Check that iam-authenticator pod is running under kube-system namespace-

kubectl -n kube-system get pods | grep aws-iam-authenticator

Initially it will show that aws-iam-authenticator pod couldn’t be started: because the pod is waiting for a ConfigMap to be created so it can boot.

Now iam-authenticator can authenticate AWS user or  role based. We will create ConfigMap to authenticate AWS User.

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: kube-system
  name: aws-iam-authenticator
  labels:
    k8s-app: aws-iam-authenticator
data:
  config.yaml: |
    # a unique-per-cluster identifier to prevent replay attacks
    # (good choices are a random token or a domain name that will be unique to your cluster)
    clusterID: <GIVE a unique NAME, best is to use CLUSTER NAME>
    server:
      # each mapRoles entry maps an IAM role to a username and set of groups
      # Each username and group can optionally contain template parameters:
      #  1) "{{AccountID}}" is the 12 digit AWS ID.
      #  2) "{{SessionName}}" is the role session name.
      mapRoles:
      # statically map arn:aws:iam::000000000000:role/KubernetesAdmin to a cluster admin
      #- roleARN: arn:aws:iam::000000000000:role/KubernetesAdmin
      #  username: kubernetes-admin
      #  groups:
      #  - system:masters
      # map EC2 instances in my "KubernetesNode" role to users like
      # "aws:000000000000:instance:i-0123456789abcdef0". Only use this if you
      # trust that the role can only be assumed by EC2 instances. If an IAM user
      # can assume this role directly (with sts:AssumeRole) they can control
      # SessionName.
      #- roleARN: arn:aws:iam::000000000000:role/KubernetesNode
      #  username: aws:{{AccountID}}:instance:{{SessionName}}
      #  groups:
      #  - system:bootstrappers
      #  - aws:instances
      # map federated users in my "KubernetesAdmin" role to users like
      # "admin:alice-example.com". The SessionName is an arbitrary role name
      # like an e-mail address passed by the identity provider. Note that if this
      # role is assumed directly by an IAM User (not via federation), the user
      # can control the SessionName.
      #- roleARN: arn:aws:iam::000000000000:role/KubernetesAdmin
      #  username: admin:{{SessionName}}
      #  groups:
      #  - system:masters
      # each mapUsers entry maps an IAM role to a static username and set of groups
      mapUsers:
      # map user IAM user Alice in 000000000000 to user "alice" in "system:masters"
      - userARN: arn:aws:iam::12345678987654:user/testuser
        username: test.user
        groups:
        - system:masters

Add your ClusterID and userARN in the above configmap file and save it as iam-authenticator-configmap.yaml

Create this configmap in cluster using the command

kubectl apply -f iam-authenticator-configmap.yaml

After creating configmap, you have to restart aws-iam-authenticator pods-

kubectl get pods -n kube-system | grep aws-iam-authenticator | awk '{print $1}' | xargs kubectl delete pod -n kube-system

Now make a new user in kubeconfig. Open ~/.kube/config for editing, create a user by replacing “testuser” with your username and replace CLUSTER NAME.

contexts:
- context:
    cluster: {replace with CLUSTER_NAME}
    user: testuser
  name: {replace with CLUSTER_NAME}
current-context: {replace with CLUSTER_NAME}
kind: Config
preferences: {}
users:
- name: testuser
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: aws-iam-authenticator
      args:
        - "token"
        - "-i"
        - "{replace with CLUSTER_NAME}"
      env:
      - name: AWS_PROFILE
        value: testuser

 

Create AWS profile by editing ~/.aws/credentials or use aws cli command aws configure to create the settings-

[profile testuser]
aws_access_key_id=
aws_secret_access_key=
region=

Now you run kubectl commands to access cluster resources.

In this article we saw how to assign pre-built groups in kubernetes like system:masters. Actually you can create your own RBAC roles and groups and assign user to those groups. Based on the kubernetes group and assigned kubernetes role to the group, the user will have access to kubernetes resources. AWS iam-authenticator will authenticate the user using AWS IAM and kubeternetes will authorize based on the group and assigned roles.

Reference: If you want to use iam-authenticator to authenticate based on AWS Role, then follow this article –

https://aws.amazon.com/blogs/opensource/deploying-aws-iam-authenticator-kubernetes-kops/