Skip to main content

Chapter 10: Security & RBAC

Authored by syscook.dev

What is Security and RBAC in Kubernetes?

Security in Kubernetes involves protecting your cluster, applications, and data from unauthorized access and threats. RBAC (Role-Based Access Control) provides fine-grained access control by defining roles and permissions for users and service accounts.

Key Concepts:

  • RBAC: Role-based access control for users and service accounts
  • Pod Security: Security contexts and policies
  • Network Security: Network policies and encryption
  • Secret Management: Secure storage and access to sensitive data
  • Admission Controllers: Policy enforcement at admission time
  • Security Scanning: Vulnerability assessment and compliance

Why Use Security and RBAC?

1. Access Control

Control who can access what resources in your cluster.

# Example: Role for application team
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-team-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses", "networkpolicies"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

2. Pod Security

Secure pod execution with security contexts and policies.

# Example: Pod with security context
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
namespace: production
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"

3. Network Security

Control network traffic with network policies.

# Example: Network policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: secure-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: load-balancer
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53

How to Implement Security and RBAC?

1. RBAC Configuration

Service Account and Role

# Example: Service account and role
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-team-sa
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-team-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-team-rolebinding
namespace: production
subjects:
- kind: ServiceAccount
name: app-team-sa
namespace: production
roleRef:
kind: Role
name: app-team-role
apiGroup: rbac.authorization.k8s.io

Cluster Role and Binding

# Example: Cluster role and binding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin-role
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["networking.k8s.io"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-binding
subjects:
- kind: User
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin-role
apiGroup: rbac.authorization.k8s.io

2. Pod Security Standards

Pod Security Policy

# Example: Pod security policy
apiVersion: v1
kind: Namespace
metadata:
name: secure-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
---
apiVersion: v1
kind: LimitRange
metadata:
name: secure-limit-range
namespace: secure-namespace
spec:
limits:
- default:
memory: "512Mi"
cpu: "500m"
defaultRequest:
memory: "256Mi"
cpu: "250m"
type: Container
- max:
memory: "1Gi"
cpu: "1000m"
min:
memory: "128Mi"
cpu: "100m"
type: Container

3. Network Security

Network Policies

# Example: Comprehensive network policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-nginx
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-database-access
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432

Practical Examples

1. Complete Security Setup

Step 1: Create Service Accounts and Roles

#!/bin/bash
# create-rbac.sh

# Create service accounts
kubectl create serviceaccount app-team-sa -n production
kubectl create serviceaccount monitoring-sa -n monitoring

# Create roles
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-team-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: monitoring
name: monitoring-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
EOF

# Create role bindings
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-team-rolebinding
namespace: production
subjects:
- kind: ServiceAccount
name: app-team-sa
namespace: production
roleRef:
kind: Role
name: app-team-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: monitoring-rolebinding
namespace: monitoring
subjects:
- kind: ServiceAccount
name: monitoring-sa
namespace: monitoring
roleRef:
kind: Role
name: monitoring-role
apiGroup: rbac.authorization.k8s.io
EOF

echo "RBAC configured successfully!"

Step 2: Configure Pod Security

#!/bin/bash
# configure-pod-security.sh

# Create secure namespace
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: secure-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
EOF

# Create limit range
kubectl apply -f - <<EOF
apiVersion: v1
kind: LimitRange
metadata:
name: secure-limit-range
namespace: secure-namespace
spec:
limits:
- default:
memory: "512Mi"
cpu: "500m"
defaultRequest:
memory: "256Mi"
cpu: "250m"
type: Container
- max:
memory: "1Gi"
cpu: "1000m"
min:
memory: "128Mi"
cpu: "100m"
type: Container
EOF

echo "Pod security configured successfully!"

Step 3: Configure Network Security

#!/bin/bash
# configure-network-security.sh

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-nginx
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-database-access
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432
EOF

echo "Network security configured successfully!"

Best Practices

1. Principle of Least Privilege

# Good: Minimal required permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: minimal-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]

2. Security Contexts

# Good: Secure pod configuration
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault

3. Network Policies

# Good: Comprehensive network policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: secure-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080

Common Pitfalls and Solutions

1. Overly Permissive Roles

# ❌ Bad: Too many permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: overly-permissive-role
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]

# ✅ Good: Minimal required permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: minimal-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]

2. Missing Security Contexts

# ❌ Bad: No security context
spec:
containers:
- name: app
image: myapp:latest

# ✅ Good: Proper security context
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true

3. Missing Network Policies

# ❌ Bad: No network policies
# All pods can communicate with each other

# ✅ Good: Proper network policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: secure-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080

Conclusion

Security and RBAC are essential for protecting your Kubernetes cluster and applications. By understanding:

  • What security and RBAC are and their importance
  • Why they're crucial for protecting your cluster and data
  • How to implement comprehensive security measures

You can create secure, compliant applications that protect against unauthorized access and threats. Proper security practices ensure that your cluster and applications are protected in production environments.

Next Steps

  • Practice with different security scenarios
  • Learn about advanced patterns
  • Move on to Chapter 11: Advanced Patterns

This tutorial is part of the Kubernetes Mastery series by syscook.dev