Container & Kubernetes Security

Kubernetes Security Essentials

4 min read

Kubernetes orchestrates containers at scale but introduces a complex attack surface. Securing the control plane, workloads, and network requires understanding RBAC, Pod Security Standards, and network policies.

Kubernetes Attack Surface

Critical Components

┌─────────────────────────────────────────────────────┐
│                    Control Plane                     │
│  ┌──────────┐  ┌──────────┐  ┌───────────────────┐ │
│  │ API      │  │ etcd     │  │ Controller/       │ │
│  │ Server   │  │ (secrets)│  │ Scheduler         │ │
│  └──────────┘  └──────────┘  └───────────────────┘ │
├─────────────────────────────────────────────────────┤
│                    Worker Nodes                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │ kubelet  │  │ kube-    │  │ Container        │  │
│  │          │  │ proxy    │  │ Runtime          │  │
│  └──────────┘  └──────────┘  └──────────────────┘  │
└─────────────────────────────────────────────────────┘
Component Risk Protection
API Server Unauthorized access RBAC, authentication
etcd Secrets exposure Encryption at rest
kubelet Node compromise Disable anonymous auth
Container runtime Container escape Pod security policies
Network Lateral movement Network policies

Role-Based Access Control (RBAC)

RBAC Components

# Role - defines permissions within a namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get"]

---
# RoleBinding - grants Role to users/groups
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: production
subjects:
- kind: User
  name: developer@example.com
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: developers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRole for Cluster-Wide Access

# ClusterRole - cluster-wide permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

---
# ClusterRoleBinding - grants ClusterRole cluster-wide
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: ServiceAccount
  name: security-scanner
  namespace: security
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

RBAC Best Practices

Practice Implementation
Least privilege Only grant required permissions
Namespace isolation Use Roles, not ClusterRoles when possible
Service account scoping Dedicated SA per application
No default SA Create specific service accounts
Audit RBAC Regular permission reviews

Pod Security Standards

Security Context Configuration

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
          - ALL
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
      requests:
        memory: "64Mi"
        cpu: "250m"

Pod Security Standards (PSS) Levels

Level Description Use Case
Privileged Unrestricted System workloads
Baseline Minimally restrictive Standard workloads
Restricted Heavily restricted Security-sensitive

Enforce via namespace labels:

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Network Policies

Default Deny Policy

# Deny all ingress and egress by default
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Allow Specific Traffic

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: web
    ports:
    - protocol: TCP
      port: 8080
---
# Allow API to access database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api
    ports:
    - protocol: TCP
      port: 5432

Secrets Management

Kubernetes Secrets Security

# Create secret
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=  # base64 encoded
  password: cGFzc3dvcmQxMjM=

Secrets are base64 encoded, not encrypted!

Enable Encryption at Rest

# /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <32-byte-base64-key>
      - identity: {}

External Secrets Management

# Using External Secrets Operator with AWS
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: SecretStore
  target:
    name: db-credentials
  data:
  - secretKey: password
    remoteRef:
      key: production/db
      property: password

Managed Kubernetes Security

Cloud Provider Controls

Feature EKS AKS GKE
Control plane security AWS managed Azure managed Google managed
Node security Managed node groups Node pools Autopilot
RBAC integration IAM roles for SA AAD integration Workload Identity
Network policies Calico Azure CNI GKE Dataplane V2
Secrets Secrets Manager Key Vault Secret Manager

Next, we'll explore cloud-native security tools like Falco, OPA, and admission controllers. :::

Quiz

Module 5: Container & Kubernetes Security

Take Quiz