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>
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.
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.
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