Aller au contenu

Lab 04: Managing RBAC and Custom Kubeconfigs on OKS

In this lab, you will learn how to use OKS CLI to manage access to a Kubernetes cluster. You will discover how to create users, assign roles through RBAC (Role-Based Access Control), and generate secure kubeconfigs to manage access to Kubernetes resources with fine-grained control. We will also cover how to secure kubeconfigs through encryption.

  • Access to a Kubernetes cluster via OKS.
  • The OKS CLI tool installed and configured.
  • A project in OKS with sufficient permissions to create roles and generate kubeconfigs.

Make sure you have the required permissions to access the target cluster. You must have a user or role that allows you to export or retrieve the cluster configuration.

Terminal window
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project > kubeconfig.yaml
export KUBECONFIG=./kubeconfig.yaml
Terminal window
kubectl get nodes

In this section, we will create roles with different permissions to grant access to the cluster based on user needs.

The namespace-admin role grants full access to a specific namespace. This can be useful for namespace administrators who need to manage all resources within a given namespace.

First, we will create the dev namespace where we will work.

Either directly from the command line (imperative mode):

Terminal window
kubectl create namespace dev
namespace/dev created

Or declaratively using a ns-dev.yaml file like this:

apiVersion: v1
kind: Namespace
metadata:
name: dev
Terminal window
kubectl apply -f ns-dev.yaml

Then, create a YAML file to define a namespace-admin role and a RoleBinding in a namespace called dev.

# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: namespace-admin
namespace: dev
---
# Role (with all permissions in the namespace)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: namespace-admin-role
namespace: dev
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
# RoleBinding (bound to the ServiceAccount)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: namespace-admin-binding
namespace: dev
subjects:
- kind: Group
name: namespace-admin
namespace: dev
roleRef:
kind: Role
name: namespace-admin-role
apiGroup: rbac.authorization.k8s.io

Apply this manifest to your cluster with the following command:

Terminal window
kubectl apply -f namespace-admin-role.yaml

This creates a role that grants full access (*) to all resources in the dev namespace and binds it to the namespace-admin group.

Verify that all objects were created successfully:

Terminal window
kubectl get role,rolebindings,sa --namespace dev
NAME CREATED AT
role.rbac.authorization.k8s.io/namespace-admin-role 2025-06-16T13:44:08Z
NAME ROLE AGE
rolebinding.rbac.authorization.k8s.io/namespace-admin-binding Role/namespace-admin-role 65s
NAME SECRETS AGE
serviceaccount/default 0 3m4s
serviceaccount/namespace-admin 0 94s

For the rest of this lab, we will launch an nginx pod in the dev namespace and come back to it later.

Terminal window
kubectl run nginx --image=nginx --namespace dev
pod/nginx created

The readonly-users role will be used to grant read-only access to all cluster resources.

Create a YAML file to define a ClusterRole called readonly and a ClusterRoleBinding for the readonly-users group.

# ClusterRole (read-only)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: readonly
labels:
app.kubernetes.io/name: readonly
app.kubernetes.io/part-of: rbac-system
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
# ClusterRoleBinding (bound to the readonly-users group)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: readonly-binding
labels:
app.kubernetes.io/name: readonly-binding
app.kubernetes.io/part-of: rbac-system
subjects:
- kind: Group
name: readonly-users
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: readonly
apiGroup: rbac.authorization.k8s.io

Apply this manifest to your cluster:

Terminal window
kubectl apply -f readonly-role.yaml

This grants read-only access to all cluster resources for users in the readonly-users group.

Once the roles are created, we need to generate kubeconfig files for each user group so they can access the cluster with the appropriate permissions.

2.1 Generate a kubeconfig for the namespace-admin group

Section intitulée « 2.1 Generate a kubeconfig for the namespace-admin group »

To grant access to the namespace-admin group, generate a kubeconfig containing the authentication information and the required permissions.

Terminal window
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --group "namespace-admin" --refresh > namespace-admin-kubeconfig.yaml

This command generates a kubeconfig for the namespace-admin group and updates it with the permissions of the namespace-admin role in the dev namespace.

We will now verify that the namespace-admin group has access to all resources in the dev namespace, but not to other namespaces.

Start by using the configuration file to access the cluster as a user in the namespace-admin group:

Terminal window
export KUBECONFIG=./namespace-admin-kubeconfig.yaml

Let’s verify that we can create a new pod with our namespace-admin role:

Terminal window
kubectl run nginx2 --image=nginx --namespace dev
pod/nginx2 created

Now list the pods in the dev namespace. We should see the nginx pod created earlier when setting up the namespace-admin role, as well as the new nginx2 pod:

Terminal window
kubectl get pods --namespace dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 23m
nginx2 1/1 Running 0 1m

Now let’s verify that we cannot create or list anything in another namespace, for example the default namespace:

Terminal window
kubectl get pods --namespace default
Error from server (Forbidden): pods is forbidden: User "kube-user" cannot list resource "pods" in API group "" in the namespace "default"

This is the expected result: our role gives us access only to the dev namespace and no others.

2.2 Generate a kubeconfig for the readonly-users group

Section intitulée « 2.2 Generate a kubeconfig for the readonly-users group »

Similarly, generate a kubeconfig for users in the readonly-users group to allow them read-only access to the cluster.

Terminal window
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --group "readonly-users" --user user1 --ttl 2592000 > readonly-users-kubeconfig.yaml

This command generates a kubeconfig for the readonly-users group and updates it with read-only permissions.

We will now verify that we have read-only access to all cluster resources, but cannot create Kubernetes resources.

Start by using the configuration file to access the cluster as a user in the readonly-users group:

Terminal window
export KUBECONFIG=./readonly-users-kubeconfig.yaml

Let’s start by listing the cluster nodes:

Terminal window
kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-50-102-69 Ready <none> 27d v1.31.2
ip-10-50-62-80 Ready <none> 27d v1.31.2
ip-10-50-90-105 Ready <none> 27d v1.31.2

Let’s see whether we can list the pods in the kube-system namespace:

Terminal window
kubectl get pods -n kube-system
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
cilium-548fj 1/1 Running 0 27d
cilium-envoy-6jw85 1/1 Running 0 27d
cilium-envoy-82kvq 1/1 Running 0 27d
cilium-envoy-97qvx 1/1 Running 0 27d
cilium-n75s9 1/1 Running 0 27d
cilium-operator-5d59c9cd6d-j7g9v 1/1 Running 0 27d
cilium-z7kpt 1/1 Running 0 27d
coredns-5658776d8b-gdf7p 1/1 Running 0 27d
coredns-5658776d8b-lff49 1/1 Running 0 27d
imds-provider-ip-10-50-102-69 1/1 Running 0 27d
imds-provider-ip-10-50-62-80 1/1 Running 0 27d
imds-provider-ip-10-50-90-105 1/1 Running 0 27d
konnectivity-agent-655br 1/1 Running 0 6d
konnectivity-agent-b6hbf 1/1 Running 0 27d
konnectivity-agent-gs4m7 1/1 Running 0 27d
konnectivity-agent-ldqzc 1/1 Running 0 6d
konnectivity-agent-wlnp8 1/1 Running 0 6d
konnectivity-agent-wp29w 1/1 Running 0 27d
metrics-server-56478ff848-q7w4v 1/1 Running 0 27d
osc-csi-node-bbdsj 3/3 Running 0 27d
osc-csi-node-l25dn 3/3 Running 1 (27d ago) 27d
osc-csi-node-mx75h 3/3 Running 0 27d
snapshot-controller-9c8bd95c5-8f9rw 1/1 Running 0 27d
snapshot-controller-9c8bd95c5-cmp24 1/1 Running 0 27d

Try creating a pod in the default namespace:

Terminal window
kubectl run nginx --image=nginx --namespace default
Error from server (Forbidden): pods is forbidden: User "kube-user" cannot create resource "pods" in API group "" in the namespace "default"

This is the expected result: our readonly-users role only allows us to list and view resources across the entire cluster, but not to create any resources.

To strengthen security, you can encrypt kubeconfigs to prevent Man-in-the-Middle (MitM) attacks and ensure that only authorized people can access sensitive information.

To encrypt a kubeconfig, you can use the --nacl option with the oks-cli cluster kubeconfig command.

Terminal window
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --user USER2 --nacl

--nacl: This option ensures that your kubeconfig is retrieved using public-key encryption during transmission.

In this lab, you learned how to use OKS CLI to manage access to a Kubernetes cluster through RBAC. You created roles such as namespace-admin and readonly-users, and generated kubeconfigs to provide controlled access to users. You also learned how to secure your kubeconfigs by encrypting them to mitigate Man-in-the-Middle attacks.

This process allows you to manage permissions with fine granularity and protect access to your Kubernetes clusters effectively and securely.