mirror of
https://github.com/ghndrx/k8s-manifests.git
synced 2026-02-10 06:45:09 +00:00
- Add namespace templates for privileged, baseline, and restricted levels - Include compliant deployment examples for baseline and restricted - Add migration audit script for checking namespace compliance - Document PSA levels, enforcement modes, and migration strategy Follows Kubernetes Pod Security Admission best practices for 2025+. Reference: https://kubernetes.io/docs/concepts/security/pod-security-standards/
106 lines
2.7 KiB
YAML
106 lines
2.7 KiB
YAML
# Example deployment compliant with RESTRICTED Pod Security Standard
|
|
# This is the gold standard for secure workloads
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: secure-app
|
|
namespace: restricted-apps
|
|
labels:
|
|
app: secure-app
|
|
security.kubernetes.io/compliant: "restricted"
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels:
|
|
app: secure-app
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: secure-app
|
|
spec:
|
|
# Pod-level security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65534 # nobody user
|
|
runAsGroup: 65534
|
|
fsGroup: 65534
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
|
|
# Prevent service account token auto-mount unless needed
|
|
automountServiceAccountToken: false
|
|
|
|
containers:
|
|
- name: app
|
|
image: nginx:1.27-alpine
|
|
ports:
|
|
- containerPort: 8080
|
|
protocol: TCP
|
|
|
|
# Container-level security context
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
runAsNonRoot: true
|
|
runAsUser: 65534
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
# Only add NET_BIND_SERVICE if binding to ports < 1024
|
|
# add:
|
|
# - NET_BIND_SERVICE
|
|
|
|
# Resource limits (required for production)
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 128Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 256Mi
|
|
|
|
# Probes for reliability
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ready
|
|
port: 8080
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
|
|
# Volume mounts for writable paths (since root is read-only)
|
|
volumeMounts:
|
|
- name: tmp
|
|
mountPath: /tmp
|
|
- name: cache
|
|
mountPath: /var/cache/nginx
|
|
- name: run
|
|
mountPath: /var/run
|
|
|
|
volumes:
|
|
# EmptyDir for ephemeral writable storage
|
|
- name: tmp
|
|
emptyDir:
|
|
sizeLimit: 100Mi
|
|
- name: cache
|
|
emptyDir:
|
|
sizeLimit: 100Mi
|
|
- name: run
|
|
emptyDir:
|
|
sizeLimit: 10Mi
|
|
|
|
# Topology spread for high availability
|
|
topologySpreadConstraints:
|
|
- maxSkew: 1
|
|
topologyKey: kubernetes.io/hostname
|
|
whenUnsatisfiable: ScheduleAnyway
|
|
labelSelector:
|
|
matchLabels:
|
|
app: secure-app
|