avatarRocky Chen

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

4288

Abstract

what is the Kubernetes User <code>testing-services-admin-user</code>? Where does it get defined? It would be introduced in the latter section.</p><h1 id="030a">3. Setup Tenant Admin Role in AWS</h1><p id="396d">In order to manage permission easily, we create an AWS IAM Role for the testing team with the permission to access the <code>testing-services</code> Namespace.</p><p id="d442"><b>Please note</b>: this AWS IAM Role should be created in the same account with the AWS Kubernetes cluster (EKS) in case the team members are hosted in another AWS account. If your team members locate in the same account with your AWS EKS, then feel free to ignore this.</p><h2 id="06f7">AWS IAM Role: TestingServicesTenantAdmin</h2><p id="81e8">An AWS IAM Role <code>TestingServicesTenantAdmin</code> is created in the same account of the Kubernetes (EKS) cluster. It is used as the Kubernete User <code>testing-services-admin-user</code>.</p><figure id="1b92"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*tqmsv36h9eyKmf57kkyPgw.png"><figcaption></figcaption></figure><p id="e3f9">An IAM Role is not enough and we also need to provide a limitation for it: a Policy. That is the attached policy: <code>EKSReadOnly</code>.</p><h2 id="787f">Attached Policy: EKSReadOnly</h2><p id="0b62">This policy allows the Role <code>TestingServicesTenantAdmin</code> to be assumed and the read operations to the EKS clusters.</p><div id="416e"><pre>{ <span class="hljs-string">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>, <span class="hljs-string">"Statement"</span>: [ { <span class="hljs-string">"Effect"</span>: <span class="hljs-string">"Allow"</span>, <span class="hljs-string">"Action"</span>: <span class="hljs-string">"sts:AssumeRole"</span>, <span class="hljs-string">"Resource"</span>: <span class="hljs-string">"arn:aws:iam::account:role/"</span> }, { <span class="hljs-string">"Effect"</span>: <span class="hljs-string">"Allow"</span>, <span class="hljs-string">"Action"</span>: [ <span class="hljs-string">"eks:DescribeCluster"</span>, <span class="hljs-string">"eks:ListClusters"</span> ], <span class="hljs-string">"Resource"</span>: <span class="hljs-string">""</span> } ] }</pre></div><h1 id="cc15">4. Group Permission to Assume Tenant Admin Role</h1><p id="9b76">Putting team members into an IAM Group is a convenient way to manage permissions for a team. Once we have the Group for our testing team, I would add a group policy to allow it to assume the IAM Role <code>TestingServicesTenantAdmin</code> and then all the group member are able to assume that Role as well.</p><h2 id="5c6b">IAM Group: TestingServicesTeam</h2><p id="a06a">It is simple to create a Group from AWS IAM console page by providing a Group name and leaving attached policy empty.</p><p id="22f7">Let me create an IAM Group <code>TestingServicesTeam</code> for testing service team and add myself to the members.</p><h2 id="7315">IAM Group Policy</h2><p id="6032">A Group Policy needs to be attached to the Group <code>TestingServicesTeam</code> as Inline Policies.</p><div id="4798"><pre>{ <span class="hljs-string">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>, <span class="hljs-string">"Statement"</span>: [ { <span class="hljs-string">"Sid"</span>: <span class="hljs-string">"Stmt_id"</span>, <span class="hljs-string">"Effect"</span>: <span class="hljs-string">"Allow"</span>, <span class="hljs-string">"Action"</span>: [ <span class="hljs-string">"sts:AssumeRole"</span> ], <span class="hljs-string">"Resource"</span>: [ <span class="hljs-string">"arn:aws:iam::account_id:role/TestingServicesTenantAdmin"</span> ] } ] }</pre></div><h1 id="49c2">5. Map Tenant Admin Role to K8s Cluster User</h1><p id="dfd2">Now, the settings are ready on both Kubernetes cluster side and AWS IAM side.</p><h2 id="cbba">The settings on Kubernetes side:</h2><ul><li>Kubernetes Namespace <code>testing-services</code> for the tenant</li><li>Kubernetes Role <code>testing-services-admin-role</code> for the tenant admin permission</li><li>Kubernetes

Options

RoleBinding for binding the Kubernetes Role to the Kubernetes User <code>testing-services-admin-user</code></li></ul><h2 id="ca54">The setting on AWS IAM side:</h2><ul><li>IAM Role <code>TestingServicesTenantAdmin</code> for the tenant admin permission</li><li>IAM Group <code>TestingServicesTeam</code> for the testing services team</li></ul><p id="c39b">Now, we missed the last connection — between the Kubernetes User <code>testing-services-admin-user</code> and IAM Role <code>TestingServicesTenantAdmin</code>.</p><p id="ef8a">In AWS, the users or IAM Roles for EKS cluster are managed in <code>aws-auth</code> ConfigMap in the <code>kube-system</code> Namespace.</p><h2 id="b517">Update ConfigMap aws-auth</h2><p id="b29c">To grant additional AWS users or roles the ability to interact with your cluster, you must edit the <code>aws-auth</code> ConfigMap within Kubernetes.</p><p id="b20c">Run the following command to check the current <code>aws-auth</code> ConfigMap:</p><div id="2cbe"><pre>kubectl <span class="hljs-built_in">describe</span> configmap -n kube-<span class="hljs-built_in">system</span> aws-auth</pre></div><p id="8f92">In the <code>Data</code> section, there should have a map: <code>mapRoles</code>.</p><p id="9b2d">The connection between the Kubernetes User <code>testing-services-admin-user</code> and IAM Role <code>TestingServicesTenantAdmin</code> can be added here, like:</p><div id="df02"><pre>- rolearn: arn:aws:<span class="hljs-title function_">iam::account_id</span>:role/TestingServicesTenantAdmin username: testing-services-<span class="hljs-literal">admin</span>-<span class="hljs-literal">user</span></pre></div><p id="b97d">More details could be found <a href="https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html">here</a>.</p><h1 id="07eb">6. Setup Local K8s Config</h1><p id="bae8">The last step is to enable testing services team members to be able to run <code>kubectl</code> command against the tenant in the Kubernetes cluster on their local machines. I would assume team members are using MacOS.</p><p id="7e34">First, <code>kubectl</code> should have been installed on their local environment.</p><h2 id="cd12">aws-iam-authenticator</h2><p id="6499">aws-iam-authenticator is needed and should be installed if not:</p><div id="65bc"><pre><span class="hljs-keyword">brew </span><span class="hljs-keyword">install </span>aws-iam-authenticator</pre></div><h2 id="024c">Update Local AWS Configuration File: HOME/.aws/config</h2><p id="77b8">Add a new profile section to <code>HOME/.aws/config</code>:</p><div id="31b6"><pre><span class="hljs-section">[profile testing-services-tenant]</span> <span class="hljs-attr">role_arn</span> = arn:aws:iam::account_id:role/TestingServicesTenantAdmin <span class="hljs-attr">region</span> = your-region <span class="hljs-attr">source_profile</span> = default</pre></div><h2 id="524c">Update Local Kubernetes Config File</h2><div id="1a8e"><pre>aws eks --profile testing-services-tenant <span class="hljs-keyword">update</span>-kubeconfig --name your-eks-<span class="hljs-keyword">cluster</span>-name --<span class="hljs-keyword">role</span>-arn arn:aws:iam::account_id:<span class="hljs-keyword">role</span>/TestingServicesTenantAdmin</pre></div><h1 id="10e7">7. Verify with Kubectl Commands</h1><p id="2615">The simple way to verify the team members able to access the tenant Namespace <code>testing-services</code> is to run a simple <code>kubectl</code> command:</p><div id="7556"><pre>kubectl <span class="hljs-built_in">get</span> pods -n testing-services</pre></div><p id="2fd8">If everything goes well, a normal output message shows:</p><div id="6e3c"><pre><span class="hljs-keyword">No</span> resources <span class="hljs-built_in">found</span> <span class="hljs-keyword">in</span> testing-services namespace.</pre></div><p id="f99f">It means no Pods found in the Namespace <code>testing-services</code> since it was just setup.</p><h1 id="a85e">8. End</h1><p id="8a1b">The most important part is to assign proper permission to the tenant team members, which depends on the real situation.</p><p id="de51">Another challenge is to make the entire setting process automated. In this post, all steps are manual for demo purpose but it is not a good practice.</p></article></body>

Photo by Joshua Sortino on Unsplash

CODEX

Setup Kubernetes Cluster Multi-tenancy with AWS EKS

0. What is multi-tenancy?

A multi-tenant cluster is shared by multiple users and/or workloads which are referred to as “tenants”. The operators of multi-tenant clusters must isolate tenants from each other to minimize the damage that a compromised or malicious tenant can do to the cluster and other tenants. Also, cluster resources must be fairly allocated among tenants.

There are many articles discussing multi-tenancy on Kubernetes clusters. Typically, Kubernetes Namespace is used for setting up multi-tenancy in Kubernetes clusters. The biggest benefit here is that Namespace is a native scope or border for most Kubernetes resources, so it would be easy for Cloud Ops to manage and organize the cluster.

For example, I want to create a namespace for testing team so they are able to access their resources via Kubectl in the Kubernetes cluster including Deployments, Services, Pods, etc.

Let’s assign the Namespace testing-services as the tenant namespace which is assigned to testing team, so they can access the Kubernetes resources in this Namespace.

The follow steps focus on setting up the tenant environment in the Kubernetes cluster managed by AWS, known as AWS EKS.

1. Setup Namespace

The namespace is created as a normal space and it would be used for hosting the tenant resources. Here is the yaml file for testing-services namespace.

Apply the yaml file and check if the namespace created successfully.

$ kubectl get namespace
NAME                      STATUS   AGE
...
default                   Active   39m
kube-system               Active   39m
testing-services          Active   16s

2. Setup RBAC Rules

In order to limit the access only for the specific namespace in the Kubernetes cluster, a Role needs to be created to define what operations are allowed to be executed. Then, a RoleBinding is also needed to connect the Role and the Kubernetes User who operates the resource indeed.

Setup Role

In this post, I created a Role of testing-services-admin-role which has fully permission to operate the resources hosted in the namespace of testing-services.

Setup RoleBinding

In the same yaml file, a RoleBinding is also created under the namespace testing-services. It connects the Kubernetes User testing-services-admin-user to the Role testing-services-admin-role that means the Role is assigned to the user. Therefore, the User testing-services-admin-user has the permission defined by the Role to access the Namespace testing-services.

Then, what is the Kubernetes User testing-services-admin-user? Where does it get defined? It would be introduced in the latter section.

3. Setup Tenant Admin Role in AWS

In order to manage permission easily, we create an AWS IAM Role for the testing team with the permission to access the testing-services Namespace.

Please note: this AWS IAM Role should be created in the same account with the AWS Kubernetes cluster (EKS) in case the team members are hosted in another AWS account. If your team members locate in the same account with your AWS EKS, then feel free to ignore this.

AWS IAM Role: TestingServicesTenantAdmin

An AWS IAM Role TestingServicesTenantAdmin is created in the same account of the Kubernetes (EKS) cluster. It is used as the Kubernete User testing-services-admin-user.

An IAM Role is not enough and we also need to provide a limitation for it: a Policy. That is the attached policy: EKSReadOnly.

Attached Policy: EKSReadOnly

This policy allows the Role TestingServicesTenantAdmin to be assumed and the read operations to the EKS clusters.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::account:role/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "eks:DescribeCluster",
                "eks:ListClusters"
            ],
            "Resource": "*"
        }
    ]
}

4. Group Permission to Assume Tenant Admin Role

Putting team members into an IAM Group is a convenient way to manage permissions for a team. Once we have the Group for our testing team, I would add a group policy to allow it to assume the IAM Role TestingServicesTenantAdmin and then all the group member are able to assume that Role as well.

IAM Group: TestingServicesTeam

It is simple to create a Group from AWS IAM console page by providing a Group name and leaving attached policy empty.

Let me create an IAM Group TestingServicesTeam for testing service team and add myself to the members.

IAM Group Policy

A Group Policy needs to be attached to the Group TestingServicesTeam as Inline Policies.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt_id",
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Resource": [
        "arn:aws:iam::account_id:role/TestingServicesTenantAdmin"
      ]
    }
  ]
}

5. Map Tenant Admin Role to K8s Cluster User

Now, the settings are ready on both Kubernetes cluster side and AWS IAM side.

The settings on Kubernetes side:

  • Kubernetes Namespace testing-services for the tenant
  • Kubernetes Role testing-services-admin-role for the tenant admin permission
  • Kubernetes RoleBinding for binding the Kubernetes Role to the Kubernetes User testing-services-admin-user

The setting on AWS IAM side:

  • IAM Role TestingServicesTenantAdmin for the tenant admin permission
  • IAM Group TestingServicesTeam for the testing services team

Now, we missed the last connection — between the Kubernetes User testing-services-admin-user and IAM Role TestingServicesTenantAdmin.

In AWS, the users or IAM Roles for EKS cluster are managed in aws-auth ConfigMap in the kube-system Namespace.

Update ConfigMap aws-auth

To grant additional AWS users or roles the ability to interact with your cluster, you must edit the aws-auth ConfigMap within Kubernetes.

Run the following command to check the current aws-auth ConfigMap:

kubectl describe configmap -n kube-system aws-auth

In the Data section, there should have a map: mapRoles.

The connection between the Kubernetes User testing-services-admin-user and IAM Role TestingServicesTenantAdmin can be added here, like:

- rolearn: arn:aws:iam::account_id:role/TestingServicesTenantAdmin
  username: testing-services-admin-user

More details could be found here.

6. Setup Local K8s Config

The last step is to enable testing services team members to be able to run kubectl command against the tenant in the Kubernetes cluster on their local machines. I would assume team members are using MacOS.

First, kubectl should have been installed on their local environment.

aws-iam-authenticator

aws-iam-authenticator is needed and should be installed if not:

brew install aws-iam-authenticator

Update Local AWS Configuration File: $HOME/.aws/config

Add a new profile section to $HOME/.aws/config:

[profile testing-services-tenant] role_arn = arn:aws:iam::account_id:role/TestingServicesTenantAdmin
region = your-region
source_profile = default

Update Local Kubernetes Config File

aws eks --profile testing-services-tenant update-kubeconfig --name your-eks-cluster-name --role-arn arn:aws:iam::account_id:role/TestingServicesTenantAdmin

7. Verify with Kubectl Commands

The simple way to verify the team members able to access the tenant Namespace testing-services is to run a simple kubectl command:

kubectl get pods -n testing-services

If everything goes well, a normal output message shows:

No resources found in testing-services namespace.

It means no Pods found in the Namespace testing-services since it was just setup.

8. End

The most important part is to assign proper permission to the tenant team members, which depends on the real situation.

Another challenge is to make the entire setting process automated. In this post, all steps are manual for demo purpose but it is not a good practice.

Kubernetes
Kubernetes Multitenancy
Namespace
Multitenancy
Recommended from ReadMedium