Mastering Kubernetes Security: Authentication, Authorization, and Admission Controls
This article explains how Kubernetes secures a cluster by protecting the API Server through authentication methods, role‑based authorization, admission controller plugins, and resource‑quota limits, providing practical examples and YAML configurations for each security layer.
Kubernetes Cluster Security Mechanisms
Kubernetes, as a distributed cluster management tool, must protect its API Server, which mediates communication between components and serves as the external control entry point. Security mechanisms therefore focus on safeguarding the API Server.
1. Authentication
1.1 Three authentication methods in a k8s cluster
HTTP Token authentication : Uses a long, unique token string stored on the API Server to identify users. Clients include the token in the HTTP Header when making API requests.
HTTP Basic authentication : Sends a Base64‑encoded username:password in the Authorization header.
HTTPS certificate authentication (most strict) : Client certificates signed by a CA root certificate enable mutual TLS authentication.
Note: Token and Basic authentication provide one‑way server‑to‑client verification, while HTTPS certificate authentication supports two‑way verification.
1.2 Authentication details
Components that need to authenticate to the API Server include kubectl, kubelet, kube‑proxy, and Pods (e.g., coredns, dashboard). kubelet obtains a certificate automatically after an initial token‑based handshake. The kubeconfig file contains cluster parameters (CA certificate, API Server address) and client credentials (certificate, private key) and is typically located at ~/.kube/config.
ServiceAccount objects simplify Pod access to the API Server by providing a token that is automatically mounted into each Pod. Secrets store ServiceAccount tokens and user‑defined opaque data.
1.3 ServiceAccount components
Each ServiceAccount consists of a token (signed by the API Server private key), a ca.crt root certificate, and a namespace identifier.
Note: Every namespace has a default ServiceAccount; Pods that do not specify one use the namespace’s default ServiceAccount.
2. Authorization
2.1 Authorization modes
Kubernetes supports several authorization strategies, selectable via the --authorization-mode flag:
AlwaysDeny – rejects all requests (useful for testing).
AlwaysAllow – accepts all requests (useful for testing).
ABAC (Attribute‑Based Access Control) – matches user attributes against policy rules.
Webhook – calls an external REST service to decide authorization.
RBAC (Role‑Based Access Control) – default since v1.6, defines permissions through Role, ClusterRole, RoleBinding, and ClusterRoleBinding objects.
2.2 Advantages of RBAC
Covers both resource (Pod, Deployment, Service) and non‑resource (metadata, status) access.
Managed entirely via API objects, manipulable with kubectl or direct API calls.
Changes take effect at runtime without restarting the API Server.
2.3 RBAC API objects
RBAC introduces four top‑level resources: Role, ClusterRole, RoleBinding, and ClusterRoleBinding. Official documentation: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
2.4 Role and RoleBinding examples
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]Note: Granting the pod-reader Role to a user allows get, watch, and list operations on Pods in the default namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get","watch","list"] apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: zhangsan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io3. Admission Control
3.1 Concept
Admission controllers are plugins that intercept every request to the API Server, enforcing additional policies. The default set of admission controllers is recommended.
Common default plugins include NamespaceLifecycle, LimitRanger, ServiceAccount, DefaultStorageClass, DefaultTolerationSeconds, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota, and NodeRestriction.
3.2 Example plugins
NamespaceLifecycle – prevents creation of objects in non‑existent namespaces and cleans up resources when a namespace is deleted.
LimitRanger – enforces resource quotas within a namespace.
ServiceAccount – automatically injects ServiceAccount credentials into Pods.
ResourceQuota – limits the total amount of resources a namespace can consume.
NodeRestriction – restricts node‑related operations to minimal privileges.
Reference: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
4. Resource Limits
4.1 Pod resource limits
Kubernetes uses cgroups to enforce CPU and memory limits. By default, Pods have no limits, allowing them to consume host resources freely. Limits are set via resources.requests and resources.limits in the Pod spec.
spec:
containers:
- image: xxxx
name: auth
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: "2"
memory: 1Gi
requests:
cpu: 250m
memory: 250Mi4.2 Namespace resource quotas
ResourceQuota objects restrict the total number of objects and aggregate resource consumption in a namespace.
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: spark-cluster
spec:
hard:
pods: "20"
requests.cpu: "2"
requests.memory: 1Gi
limits.cpu: "4"
limits.memory: 2GiObject count quotas can also be defined:
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: spark-cluster
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"If a Pod lacks explicit requests and limits, it inherits the namespace’s maximum resources; if the namespace also lacks limits, the cluster defaults apply. When memory usage exceeds limits, cgroups trigger OOM, so a LimitRange can be created to set default limits for containers.
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
namespace: test
spec:
limits:
- default:
memory: 512Mi
cpu: 500m
defaultRequest:
memory: 256Mi
cpu: 100m
type: ContainerSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
