Managing Kubernetes Users, Groups, and ServiceAccounts: A Deep Dive with Hands-On Scenarios
Bavithran M
Senior Cloud & DevOps Engineer | AWS & Azure Certified | Kubernetes & Automation Advocate | Training | Mentoring | Uplifting Many IT Professionals
Kubernetes provides a highly flexible authentication and authorization system, but managing users, groups, and ServiceAccounts requires a clear understanding of how Kubernetes handles security. Unlike traditional systems, Kubernetes does not store user credentials (usernames, passwords, etc.). Instead, it relies on external authentication providers and uses RBAC (Role-Based Access Control) for defining permissions.
This guide will provide a deep dive into Kubernetes authentication and authorization, along with real-world hands-on scenarios demonstrating how to:
? Create and authenticate users using certificates
? Group users for easier RBAC management
? Use ServiceAccounts for applications needing API access
? Secure workloads with namespace isolation
?? How Kubernetes Manages Users, Groups, and ServiceAccounts
?? User authentication is handled externally, while ServiceAccounts are managed natively within Kubernetes.
Scenario 1: Creating a Kubernetes User with Certificate Authentication and RBAC
?? Context
A developer (john-dev) needs read-only access to pods in the dev namespace. Since Kubernetes does not store user credentials, we need to generate an authentication certificate and configure RBAC permissions manually.
Step 1: Generate a Certificate for the User
We will create an X.509 certificate for user authentication.
Generate a Private Key
openssl genrsa -out john-dev.key 2048
Create a Certificate Signing Request (CSR)
openssl req -new -key john-dev.key -out john-dev.csr -subj "/CN=john-dev/O=developers"
Explanation:
?? The Kubernetes API uses the CN field as the username and the O field as the group.
Step 2: Sign the CSR with Kubernetes CA
Now, sign the certificate using the Kubernetes Certificate Authority (CA):
openssl x509 -req -in john-dev.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out john-dev.crt -days 365
This generates john-dev.crt, a valid certificate signed by Kubernetes CA.
Step 3: Configure kubectl for the New User
To allow kubectl to use the new certificate for authentication:
kubectl config set-credentials john-dev --client-certificate=john-dev.crt --client-key=john-dev.key
kubectl config set-context john-dev-context --cluster=kubernetes-cluster --namespace=dev --user=john-dev
kubectl config use-context john-dev-context
?? At this point, the user exists but has no permissions yet!
Step 4: Create a Role and RoleBinding for Read-Only Access
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
kubectl apply -f pod-reader-role.yaml
Now, bind this Role to john-dev:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: dev
subjects:
- kind: User
name: john-dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f role-binding.yaml
? John now has read-only access to pods in the dev namespace!
Step 5: Verify Access
Try listing pods:
kubectl get pods --namespace=dev --as=john-dev
Try deleting a pod:
kubectl delete pod my-pod --namespace=dev --as=john-dev
? RBAC is correctly restricting access!
Scenario 2: Using ServiceAccounts for CI/CD Workloads
?? Context
A CI/CD pipeline running inside a pod needs to deploy applications in the staging namespace. Since normal user accounts are not suitable, we use a ServiceAccount.
Step 1: Create a ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd-pipeline
namespace: staging
kubectl apply -f service-account.yaml
Step 2: Grant API Access to the ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pipeline-deployer
namespace: staging
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "delete"]
kubectl apply -f pipeline-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pipeline-role-binding
namespace: staging
subjects:
- kind: ServiceAccount
name: cicd-pipeline
namespace: staging
roleRef:
kind: Role
name: pipeline-deployer
apiGroup: rbac.authorization.k8s.io
kubectl apply -f pipeline-role-binding.yaml
? The cicd-pipeline ServiceAccount can now deploy workloads in the staging namespace.
Scenario 3: Namespace Isolation Using Groups
?? Context
The qa-team should have access to the qa namespace but be restricted from dev and prod namespaces.
Step 1: Define Namespace-Specific Permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: qa-access
namespace: qa
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
kubectl apply -f qa-role.yaml
Step 2: Bind the Role to the QA Group
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: qa-access-binding
namespace: qa
subjects:
- kind: Group
name: qa-team # This group is defined externally (IAM, Active Directory)
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: qa-access
apiGroup: rbac.authorization.k8s.io
kubectl apply -f qa-role-binding.yaml
? The qa-team now has exclusive access to the qa namespace while being restricted from dev and prod.
Key Takeaways
How Do You Manage Access in Kubernetes?
Do you use IAM, OpenID, or certificates for authentication? Let’s discuss best practices!
Senior Cloud & DevOps Engineer | AWS & Azure Certified | Kubernetes & Automation Advocate | Training | Mentoring | Uplifting Many IT Professionals
1 周#connections