|
| 1 | +# Pod Security Standards (PSS): Overview and Implementation Guide |
| 2 | + |
| 3 | +## Introduction to Pod Security Standards |
| 4 | + |
| 5 | +Pod Security Standards (PSS) is a feature in Kubernetes that defines different levels of security for pods. It replaced the deprecated PodSecurityPolicy (PSP) in Kubernetes 1.25. The PSS provides a standardized way to enforce security controls for pods, helping cluster administrators ensure workloads meet specific security requirements without needing to create and manage custom policies. |
| 6 | + |
| 7 | +## PSS Profiles |
| 8 | + |
| 9 | +PSS defines three security profiles with increasing levels of restriction: |
| 10 | + |
| 11 | +1. **Privileged**: Unrestricted policy, providing the widest possible level of permissions. This profile has essentially no restrictions on pod configuration. |
| 12 | + |
| 13 | +2. **Baseline**: Minimally restrictive policy which prevents known privilege escalations. Allows the default (minimally specified) pod configuration. |
| 14 | + |
| 15 | +3. **Restricted**: Heavily restricted policy, following current pod hardening best practices. This is the most secure profile, designed to enforce security best practices. |
| 16 | + |
| 17 | +## PSS Implementation Methods |
| 18 | + |
| 19 | +There are three ways to implement Pod Security Standards: |
| 20 | + |
| 21 | +1. **Pod Security Admission Controller**: Built into Kubernetes since v1.23, it can enforce the standards at the namespace level. |
| 22 | + |
| 23 | +2. **Namespace Labels**: Used to configure the Pod Security Admission Controller with different modes (enforce, audit, warn). |
| 24 | + |
| 25 | +3. **3rd Party Solutions**: Various tools like OPA/Gatekeeper, Kyverno, etc. can enforce PSS. |
| 26 | + |
| 27 | +## PSS Modes |
| 28 | + |
| 29 | +Each profile can be applied in one of three modes: |
| 30 | + |
| 31 | +1. **enforce**: Policy violations will cause the pod to be rejected |
| 32 | +2. **audit**: Policy violations trigger audit annotations, but are allowed |
| 33 | +3. **warn**: Policy violations trigger user-facing warnings, but are allowed |
| 34 | + |
| 35 | +## Exam Task Example: Making a Deployment Compatible with PSS-Restricted |
| 36 | + |
| 37 | +### Task Description |
| 38 | + |
| 39 | +Create a deployment that is compatible with the Pod Security Standard "restricted" profile in enforce mode. The deployment should run a container that: |
| 40 | +1. Reads and writes to a persistent volume |
| 41 | +2. Exposes port 8080 |
| 42 | +3. Runs as a non-root user |
| 43 | +4. Meets all the requirements of the restricted profile |
| 44 | + |
| 45 | +### Solution |
| 46 | + |
| 47 | +#### Step 1: Configure Namespace with PSS |
| 48 | + |
| 49 | +First, let's create a namespace with the restricted profile in enforce mode: |
| 50 | + |
| 51 | +```bash |
| 52 | +kubectl create namespace pss-restricted |
| 53 | +kubectl label --overwrite ns pss-restricted \ |
| 54 | + pod-security.kubernetes.io/enforce=restricted \ |
| 55 | + pod-security.kubernetes.io/warn=restricted \ |
| 56 | + pod-security.kubernetes.io/audit=restricted |
| 57 | +``` |
| 58 | + |
| 59 | +#### Step 2: Create a Compliant Deployment |
| 60 | + |
| 61 | +```yaml |
| 62 | +apiVersion: apps/v1 |
| 63 | +kind: Deployment |
| 64 | +metadata: |
| 65 | + name: pss-restricted-app |
| 66 | + namespace: pss-restricted |
| 67 | +spec: |
| 68 | + replicas: 1 |
| 69 | + selector: |
| 70 | + matchLabels: |
| 71 | + app: pss-restricted-app |
| 72 | + template: |
| 73 | + metadata: |
| 74 | + labels: |
| 75 | + app: pss-restricted-app |
| 76 | + spec: |
| 77 | + # Security Context at Pod level |
| 78 | + securityContext: |
| 79 | + runAsNonRoot: true |
| 80 | + seccompProfile: |
| 81 | + type: RuntimeDefault |
| 82 | + containers: |
| 83 | + - name: app |
| 84 | + image: nginx:1.21 |
| 85 | + # Container Security Context |
| 86 | + securityContext: |
| 87 | + allowPrivilegeEscalation: false |
| 88 | + capabilities: |
| 89 | + drop: |
| 90 | + - ALL |
| 91 | + runAsUser: 1000 |
| 92 | + runAsGroup: 3000 |
| 93 | + seccompProfile: |
| 94 | + type: RuntimeDefault |
| 95 | + readOnlyRootFilesystem: true |
| 96 | + ports: |
| 97 | + - containerPort: 8080 |
| 98 | + resources: |
| 99 | + limits: |
| 100 | + cpu: "500m" |
| 101 | + memory: "512Mi" |
| 102 | + requests: |
| 103 | + cpu: "100m" |
| 104 | + memory: "128Mi" |
| 105 | + volumeMounts: |
| 106 | + - name: data-volume |
| 107 | + mountPath: /data |
| 108 | + readOnly: false |
| 109 | + - name: tmp-volume |
| 110 | + mountPath: /tmp |
| 111 | + volumes: |
| 112 | + - name: data-volume |
| 113 | + persistentVolumeClaim: |
| 114 | + claimName: pss-restricted-pvc |
| 115 | + - name: tmp-volume |
| 116 | + emptyDir: {} |
| 117 | +``` |
| 118 | +
|
| 119 | +#### Step 3: Create the Persistent Volume Claim |
| 120 | +
|
| 121 | +```yaml |
| 122 | +apiVersion: v1 |
| 123 | +kind: PersistentVolumeClaim |
| 124 | +metadata: |
| 125 | + name: pss-restricted-pvc |
| 126 | + namespace: pss-restricted |
| 127 | +spec: |
| 128 | + accessModes: |
| 129 | + - ReadWriteOnce |
| 130 | + resources: |
| 131 | + requests: |
| 132 | + storage: 1Gi |
| 133 | + storageClassName: standard |
| 134 | +``` |
| 135 | +
|
| 136 | +#### Step 4: Apply the Configuration |
| 137 | +
|
| 138 | +```bash |
| 139 | +kubectl apply -f pss-pvc.yaml |
| 140 | +kubectl apply -f pss-deployment.yaml |
| 141 | +``` |
| 142 | + |
| 143 | +#### Step 5: Verify Deployment Status |
| 144 | + |
| 145 | +```bash |
| 146 | +kubectl get deployment -n pss-restricted |
| 147 | +kubectl describe deployment pss-restricted-app -n pss-restricted |
| 148 | +``` |
| 149 | + |
| 150 | +### Key PSS Restricted Requirements Explained |
| 151 | + |
| 152 | +When the Pod Security Standard enforces the restricted profile, the following security requirements must be met: |
| 153 | + |
| 154 | +1. **Pod-level Requirements**: |
| 155 | + - `securityContext.runAsNonRoot: true`: Ensures pods run as non-root users |
| 156 | + - `securityContext.seccompProfile.type: RuntimeDefault`: Enables default seccomp profile |
| 157 | + |
| 158 | +2. **Container-level Requirements**: |
| 159 | + - `securityContext.allowPrivilegeEscalation: false`: Prevents privilege escalation |
| 160 | + - `securityContext.capabilities.drop: ["ALL"]`: Drops all Linux capabilities |
| 161 | + - `securityContext.runAsUser` and `runAsGroup`: Explicit non-zero user/group IDs |
| 162 | + - `securityContext.seccompProfile.type: RuntimeDefault`: Enables seccomp at container level |
| 163 | + - `readOnlyRootFilesystem: true`: Makes root filesystem read-only |
| 164 | + |
| 165 | +3. **Volume-related Considerations**: |
| 166 | + - When a read-only root filesystem is used, you must provide writable volumes for paths like `/tmp` |
| 167 | + - PersistentVolumeClaims are allowed and need appropriate mount paths |
| 168 | + |
| 169 | +4. **Prohibited configurations**: |
| 170 | + - `hostPath` volumes |
| 171 | + - `hostNetwork`, `hostIPC`, and `hostPID` set to true |
| 172 | + - `privileged` containers |
| 173 | + - Adding capabilities beyond a minimal set |
| 174 | + - HostPort usage |
| 175 | + |
| 176 | +## Common Issues and Troubleshooting |
| 177 | + |
| 178 | +When working with PSS in restricted mode, you might encounter the following issues: |
| 179 | + |
| 180 | +1. **Pod Rejection Errors**: If a pod is rejected, check the error message from kubectl, which will specify which PSS policy was violated. |
| 181 | + |
| 182 | +2. **Runtime Failures**: Even if a pod starts, it might fail if it needs to write to locations that are now read-only. |
| 183 | + |
| 184 | +3. **Legacy Applications**: Older applications often assume root access or specific capabilities, requiring refactoring. |
| 185 | + |
| 186 | +### Troubleshooting Commands |
| 187 | + |
| 188 | +```bash |
| 189 | +# Check if pod was rejected due to PSS violations |
| 190 | +kubectl get events -n pss-restricted |
| 191 | + |
| 192 | +# Check audit annotations for violations |
| 193 | +kubectl get pod <pod-name> -n pss-restricted -o yaml | grep "audit" |
| 194 | + |
| 195 | +# Check warning events |
| 196 | +kubectl get events -n pss-restricted | grep Warning |
| 197 | +``` |
| 198 | + |
| 199 | +## Additional Exam Task Examples |
| 200 | + |
| 201 | +### Task 1: Configure a Namespace for PSS Audit Mode |
| 202 | + |
| 203 | +Create a namespace that audits according to the restricted profile but only enforces the baseline profile. |
| 204 | + |
| 205 | +```bash |
| 206 | +kubectl create namespace mixed-pss |
| 207 | +kubectl label --overwrite ns mixed-pss \ |
| 208 | + pod-security.kubernetes.io/enforce=baseline \ |
| 209 | + pod-security.kubernetes.io/audit=restricted \ |
| 210 | + pod-security.kubernetes.io/warn=restricted |
| 211 | +``` |
| 212 | + |
| 213 | +### Task 2: Troubleshoot a Pod Failing Due to PSS Restrictions |
| 214 | + |
| 215 | +Given a pod that is failing to deploy in a namespace with PSS restricted enforcement, identify and fix the issues. |
| 216 | + |
| 217 | +Original pod manifest: |
| 218 | +```yaml |
| 219 | +apiVersion: v1 |
| 220 | +kind: Pod |
| 221 | +metadata: |
| 222 | + name: privileged-pod |
| 223 | + namespace: pss-restricted |
| 224 | +spec: |
| 225 | + containers: |
| 226 | + - name: web |
| 227 | + image: nginx |
| 228 | + ports: |
| 229 | + - containerPort: 80 |
| 230 | + securityContext: |
| 231 | + privileged: true # Violation! |
| 232 | +``` |
| 233 | +
|
| 234 | +Fixed pod manifest: |
| 235 | +```yaml |
| 236 | +apiVersion: v1 |
| 237 | +kind: Pod |
| 238 | +metadata: |
| 239 | + name: compliant-pod |
| 240 | + namespace: pss-restricted |
| 241 | +spec: |
| 242 | + securityContext: |
| 243 | + runAsNonRoot: true |
| 244 | + seccompProfile: |
| 245 | + type: RuntimeDefault |
| 246 | + containers: |
| 247 | + - name: web |
| 248 | + image: nginx |
| 249 | + ports: |
| 250 | + - containerPort: 80 |
| 251 | + securityContext: |
| 252 | + allowPrivilegeEscalation: false |
| 253 | + capabilities: |
| 254 | + drop: |
| 255 | + - ALL |
| 256 | + runAsUser: 101 # nginx user |
| 257 | + runAsGroup: 101 |
| 258 | + seccompProfile: |
| 259 | + type: RuntimeDefault |
| 260 | +``` |
| 261 | +
|
| 262 | +## Conclusion |
| 263 | +
|
| 264 | +Pod Security Standards provide a robust framework for securing Kubernetes workloads. Understanding the different profiles and their requirements is essential for creating secure deployments that can run in restricted environments. When working with the restricted profile: |
| 265 | +
|
| 266 | +1. Always specify non-root users |
| 267 | +2. Drop ALL capabilities at the container level |
| 268 | +3. Prevent privilege escalation |
| 269 | +4. Use appropriate seccomp profiles |
| 270 | +5. Make root filesystems read-only when possible |
| 271 | +6. Use emptyDir volumes for temporary writable storage |
| 272 | +
|
| 273 | +By following these practices, you can ensure your workloads are compatible with Kubernetes security best practices and can run in environments with strict security requirements. |
0 commit comments