2019-10-17 13:31:40 -07:00
|
|
|
---
|
2023-06-02 21:41:36 -07:00
|
|
|
title_tag: Configure Kubernetes Access Control | Crosswalk
|
2019-12-18 09:59:20 -08:00
|
|
|
meta_desc: This page will walk you through how to configure Kubernetes
|
2023-05-15 15:25:28 -07:00
|
|
|
access control on AWS, Azure, and Google Cloud.
|
|
|
|
title: Access control
|
|
|
|
h1: Kubernetes access control
|
2023-06-08 16:15:52 -07:00
|
|
|
meta_image: /images/docs/meta-images/docs-clouds-kubernetes-meta-image.png
|
2019-10-17 13:31:40 -07:00
|
|
|
menu:
|
2023-05-15 15:25:28 -07:00
|
|
|
clouds:
|
|
|
|
parent: kubernetes-guides
|
|
|
|
identifier: kubernetes-guides-configure-authorization
|
2019-11-16 12:40:48 -08:00
|
|
|
weight: 6
|
2023-05-15 15:25:28 -07:00
|
|
|
aliases:
|
|
|
|
- /docs/guides/crosswalk/kubernetes/configure-access-control/
|
2019-10-17 13:31:40 -07:00
|
|
|
---
|
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{< chooser cloud "aws,azure,gcp" / >}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud aws %}}
|
2019-10-30 14:27:58 +01:00
|
|
|
|
2019-10-18 07:59:30 -07:00
|
|
|
Access control in Kubernetes is done by configuring permissions for IAM users
|
|
|
|
and roles to operate in the cluster.
|
|
|
|
|
|
|
|
The `kubeconfig` will be shared across users for access, and each IAM role
|
|
|
|
will have a particular binding into the cluster's auth to determine how it works
|
|
|
|
with the cluster.
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
The full code for this stack is on [GitHub][gh-repo-stack].
|
2019-12-18 09:59:20 -08:00
|
|
|
|
|
|
|
<!-- markdownlint-disable url -->
|
2019-11-13 09:53:50 -08:00
|
|
|
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/aws/03-cluster-configuration
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud azure %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2019-10-30 14:27:58 +01:00
|
|
|
Access control in Kubernetes is done by configuring permissions for Azure Active Directory (AD) users
|
|
|
|
and groups to operate in the cluster.
|
|
|
|
|
|
|
|
The `kubeconfig` will contain user authentication tokens for access, and each AD group
|
|
|
|
will have a particular binding into the cluster's auth to determine how it works
|
|
|
|
with the cluster.
|
|
|
|
|
2019-10-17 13:31:40 -07:00
|
|
|
The full code for this stack is on [GitHub][gh-repo-stack].
|
2019-12-18 09:59:20 -08:00
|
|
|
|
|
|
|
<!-- markdownlint-disable url -->
|
2019-11-13 09:53:50 -08:00
|
|
|
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/azure/03-cluster-configuration
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud gcp %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2019-11-07 14:41:50 -08:00
|
|
|
Access control in Kubernetes is done by configuring permissions for IAM
|
|
|
|
ServiceAccounts to operate in the cluster.
|
|
|
|
|
|
|
|
The `kubeconfig` will be shared across ServiceAccounts for access, and each
|
|
|
|
ServiceAccount will have a particular binding into the cluster's auth to determine how it works
|
|
|
|
with the cluster.
|
|
|
|
|
2019-10-17 13:31:40 -07:00
|
|
|
The full code for this stack is on [GitHub][gh-repo-stack].
|
2019-12-18 09:59:20 -08:00
|
|
|
|
|
|
|
<!-- markdownlint-disable url -->
|
2019-11-13 09:53:50 -08:00
|
|
|
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/gcp/03-cluster-configuration
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
|
|
|
We'll examine how to:
|
|
|
|
|
2022-12-08 15:41:39 -08:00
|
|
|
- [Overview](#overview)
|
|
|
|
- [Configure RBAC Authorization](#configure-rbac-authorization)
|
2019-11-07 14:32:35 -08:00
|
|
|
|
2019-11-12 11:09:27 -08:00
|
|
|
## Configure RBAC Authorization
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud azure %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2019-11-07 23:07:31 -08:00
|
|
|
Access control is not configured by default for **non-admins** with Kubernetes RBAC.
|
|
|
|
|
|
|
|
In [Identity][crosswalk-identity] developers can **authenticate** into the cluster
|
2019-11-12 10:30:40 -08:00
|
|
|
using the kubeconfig, but they are not yet **authorized** to do work in the cluster.
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
This means that the user cannot perform any operations in the cluster by
|
2019-11-12 10:30:40 -08:00
|
|
|
default, such as retrieve information, as shown in the `Error from server (Forbidden)`
|
2019-10-17 13:31:40 -07:00
|
|
|
messages.
|
|
|
|
|
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ az login --service-principal --username $ARM_CLIENT_ID --password $ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID
|
2019-11-07 23:07:31 -08:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-devs.json
|
2019-11-07 10:36:01 -08:00
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
2019-10-17 13:31:40 -07:00
|
|
|
Error from server (Forbidden): pods is forbidden: User "pulumi:alice" cannot create resource "pods" in API group "" in the namespace "apps-x1z818eg"
|
|
|
|
```
|
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
Below is an example of how to create a Kubernetes Role and RoleBiding for the `devs` to **only** deploy common
|
|
|
|
workloads in the `apps` namespace (created in [cluster defaults][crosswalk-configure-defaults]).
|
2019-11-08 22:38:19 -08:00
|
|
|
|
|
|
|
Assume the `admin` user.
|
|
|
|
|
|
|
|
```ts
|
|
|
|
$ az login --service-principal --username $ARM_CLIENT_ID --password $ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID
|
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-admin.json
|
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
|
|
|
<!-- markdownlint-disable url -->
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-configure-defaults]: /docs/clouds/kubernetes/guides/configure-defaults/
|
|
|
|
[crosswalk-identity]: /docs/clouds/kubernetes/guides/identity/
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-11-05 15:29:15 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud aws %}}
|
2019-11-07 23:07:31 -08:00
|
|
|
|
|
|
|
Access control is not configured by default for **non-admins** with Kubernetes RBAC.
|
|
|
|
|
|
|
|
In [Identity][crosswalk-identity] developers can **authenticate** into the cluster
|
|
|
|
using the IAM role and kubeconfig, but it is not yet **authorized** to do work in the cluster.
|
|
|
|
|
|
|
|
This means that the user cannot perform any operations in the cluster by
|
2019-11-08 01:00:31 -08:00
|
|
|
default such as retrieve information, as shown in the `Error from server (Forbidden)`
|
2019-11-07 23:07:31 -08:00
|
|
|
messages.
|
|
|
|
|
2019-11-07 10:36:01 -08:00
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ aws sts assume-role --role-arn `pulumi stack output devsIamRoleArn` --role-session-name k8s-devs
|
2019-11-07 23:07:31 -08:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-devs.json
|
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
|
|
|
Error from server (Forbidden): pods is forbidden: User "pulumi:alice" cannot create resource "pods" in API group "" in the namespace "apps-x1z818eg"
|
2019-11-07 10:36:01 -08:00
|
|
|
```
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
Below is an example of how to create a Kubernetes `Role` with the ability to **only** deploy common
|
|
|
|
workloads in the `apps` namespace (created in [cluster defaults][crosswalk-configure-defaults]). We also create a `RoleBinding`
|
2019-11-07 23:07:31 -08:00
|
|
|
to associate the Kubernetes `Role` to the IAM `devs` role.
|
|
|
|
|
|
|
|
Assume the `admin` user.
|
|
|
|
|
2019-11-07 20:19:44 -08:00
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ aws sts assume-role --role-arn `pulumi stack output adminsIamRoleArn` --role-session-name k8s-admins
|
2019-11-07 20:19:44 -08:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-admin.json
|
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
|
|
|
<!-- markdownlint-disable url -->
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-configure-defaults]: /docs/clouds/kubernetes/guides/configure-defaults/
|
|
|
|
[crosswalk-identity]: /docs/clouds/kubernetes/guides/identity/
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud gcp %}}
|
2019-11-07 23:07:31 -08:00
|
|
|
|
|
|
|
In [Identity][crosswalk-identity], access control is configured on the ServiceAccounts to bind to
|
2019-11-08 01:00:31 -08:00
|
|
|
[Predefined GKE Roles][gke-predefined-roles] for GKE managed Kubernetes RBAC.
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
If you wish to not bind a ServiceAccount to predefined GKE roles,
|
|
|
|
the user will be able to **authenticate** into the cluster, but they will not be
|
|
|
|
**authorized** to do work until given permissions.
|
2019-11-07 23:07:31 -08:00
|
|
|
|
|
|
|
This means that the user cannot perform any operations in the cluster by
|
2019-11-08 01:00:31 -08:00
|
|
|
default such as retrieve information, as shown in the `Error from server (Forbidden)`
|
2019-11-07 23:07:31 -08:00
|
|
|
messages.
|
|
|
|
|
2019-11-07 20:19:44 -08:00
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ gcloud auth activate-service-account --key-file k8s-devs-sa-key.json
|
2019-11-07 20:19:44 -08:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig.json
|
2019-11-07 23:07:31 -08:00
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
|
|
|
Error from server (Forbidden): pods is forbidden: User "pulumi:alice" cannot create resource "pods" in API group "" in the namespace "apps-x1z818eg"
|
|
|
|
```
|
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
As an example, if the `devs` ServiceAccount was not bound to the `roles/container.developer` permission,
|
|
|
|
an `admin` would need to create [Kubernetes RBAC][k8s-rbac-docs] resources to bind the ServiceAccount to certain privileges.
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
Below is an example of how to create a Kubernetes `Role` with the ability to **only** deploy common
|
|
|
|
workloads in the `apps` namespace (created in [cluster defaults][crosswalk-configure-defaults]), and a `RoleBinding` to associate
|
2019-11-07 23:07:31 -08:00
|
|
|
the Kubernetes `Role` to the IAM `devs` role.
|
|
|
|
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-disable url -->
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-configure-defaults]: /docs/clouds/kubernetes/guides/configure-defaults/
|
2019-11-08 01:00:31 -08:00
|
|
|
[k8s-rbac-docs]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
|
2019-11-07 23:07:31 -08:00
|
|
|
[gke-predefined-roles]: https://cloud.google.com/kubernetes-engine/docs/how-to/iam#predefined
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-identity]: /docs/clouds/kubernetes/guides/identity/
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|
2019-11-07 23:07:31 -08:00
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
Assume the `admin` user.
|
2019-11-07 23:07:31 -08:00
|
|
|
|
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ gcloud auth activate-service-account --key-file k8s-admin-sa-key.json
|
2019-11-07 23:07:31 -08:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-admin.json
|
2019-11-07 20:19:44 -08:00
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-11-07 10:36:01 -08:00
|
|
|
|
2019-11-07 23:07:31 -08:00
|
|
|
Create a Role and RoleBinding for the `pulumi-devs` group in the `apps`
|
|
|
|
Namespace.
|
|
|
|
|
2019-10-17 13:31:40 -07:00
|
|
|
```typescript
|
|
|
|
import * as k8s from "@pulumi/kubernetes";
|
|
|
|
|
|
|
|
// Create a limited role for the `pulumi:devs` to use in the apps namespace.
|
|
|
|
let devsGroupRole = new k8s.rbac.v1.Role("pulumi-devs",
|
|
|
|
{
|
|
|
|
metadata: {namespace: appNamespaceName},
|
|
|
|
rules: [
|
|
|
|
{
|
2019-11-05 15:29:15 -08:00
|
|
|
apiGroups: [""],
|
|
|
|
resources: ["pods", "secrets", "services", "persistentvolumeclaims"],
|
|
|
|
verbs: ["get", "list", "watch", "create", "update", "delete"],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
apiGroups: ["extensions", "apps"],
|
|
|
|
resources: ["replicasets", "deployments"],
|
2019-10-17 13:31:40 -07:00
|
|
|
verbs: ["get", "list", "watch", "create", "update", "delete"],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{provider: cluster.provider},
|
|
|
|
);
|
|
|
|
|
|
|
|
// Bind the `pulumi:devs` RBAC group to the new, limited role.
|
|
|
|
let devsGroupRoleBinding = new k8s.rbac.v1.RoleBinding("pulumi-devs", {
|
|
|
|
metadata: {namespace: appNamespaceName},
|
|
|
|
subjects: [{
|
|
|
|
kind: "Group",
|
|
|
|
name: "pulumi:devs",
|
|
|
|
}],
|
|
|
|
roleRef: {
|
|
|
|
kind: "Role",
|
|
|
|
name: devsGroupRole.metadata.name,
|
|
|
|
apiGroup: "rbac.authorization.k8s.io",
|
|
|
|
},
|
|
|
|
}, {provider: cluster.provider});
|
|
|
|
```
|
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud aws %}}
|
|
|
|
|
2019-11-07 23:07:31 -08:00
|
|
|
After creating the Role and RoleBinding in a Pulumi update, now try
|
2019-11-08 01:00:31 -08:00
|
|
|
deploying the workload using the `devs` role.
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
```bash
|
2019-11-08 01:00:31 -08:00
|
|
|
$ aws sts assume-role --role-arn `pulumi stack output devsIamRoleArn` --role-session-name k8s-devs
|
2019-10-17 13:31:40 -07:00
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-devs.json
|
2019-11-07 10:36:01 -08:00
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
2019-10-17 13:31:40 -07:00
|
|
|
service/nginx created
|
|
|
|
pod/nginx created
|
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable cloud azure %}}
|
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
After creating the Role and RoleBinding in a Pulumi update, now try
|
|
|
|
deploying the workload using the `devs` role.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ az login --service-principal --username $ARM_CLIENT_ID --password $ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID
|
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig-devs.json
|
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
|
|
|
service/nginx created
|
|
|
|
pod/nginx created
|
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable cloud gcp %}}
|
|
|
|
|
2019-11-08 01:00:31 -08:00
|
|
|
After creating the Role and RoleBinding in a Pulumi update, now try
|
|
|
|
deploying the workload using the `devs` role.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ gcloud auth activate-service-account --key-file k8s-devs-sa-key.json
|
|
|
|
$ export KUBECONFIG=`pwd`/kubeconfig.json
|
|
|
|
$ kubectl run --namespace=`pulumi stack output appsNamespaceName` --generator=run-pod/v1 nginx --image=nginx --port=80 --expose --service-overrides='{"spec":{"type":"LoadBalancer"}}' --limits cpu=200m,memory=256Mi
|
|
|
|
service/nginx created
|
|
|
|
pod/nginx created
|
|
|
|
```
|
2019-12-18 09:59:20 -08:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
Delete the pod and service.
|
|
|
|
|
|
|
|
```bash
|
2019-11-07 10:36:01 -08:00
|
|
|
$ kubectl delete --namespace=`pulumi stack output appsNamespaceName` pod/nginx svc/nginx
|
2019-10-17 13:31:40 -07:00
|
|
|
```
|
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% choosable cloud aws %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For a complete example of this in action, see [Simplifying Kubernetes
|
2019-10-17 13:31:40 -07:00
|
|
|
RBAC in Amazon EKS][simplify-rbac].
|
2019-10-18 07:59:30 -07:00
|
|
|
[simplify-rbac]: /blog/simplify-kubernetes-rbac-in-amazon-eks-with-open-source-pulumi-packages/
|
2019-10-17 13:31:40 -07:00
|
|
|
|
2020-03-20 09:32:19 -07:00
|
|
|
{{% /choosable %}}
|
2019-10-17 13:31:40 -07:00
|
|
|
|
|
|
|
See the [official Kubernetes RBAC docs][k8s-rbac-docs] for more details.
|
|
|
|
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-disable url -->
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-identity]: /docs/clouds/kubernetes/guides/identity/
|
2019-10-17 13:31:40 -07:00
|
|
|
[k8s-rbac-docs]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
|
2023-05-15 15:25:28 -07:00
|
|
|
[crosswalk-configure-defaults]: /docs/clouds/kubernetes/guides/configure-defaults/
|
2019-12-18 09:59:20 -08:00
|
|
|
<!-- markdownlint-enable url -->
|