Before you start
Environment: A disposable Linux Kubernetes cluster, kubectl access, Pod Security Admission enabled, and a network plugin that enforces NetworkPolicy. Use the documentation matching your cluster version.
Confirm the current context. Create a new, empty namespace named opsrung-security-lab only if it does not already exist. These examples must not target default, kube-system, or a production namespace.
Commands run in your own terminal. This website cannot inspect or secure your environment.
Inspect first · then create a dedicated lab namespace
1. Review the identity and namespace first
The same kubectl command can affect very different environments depending on the selected context.
kubectl config current-context
kubectl version
kubectl get namespace opsrung-security-lab
# Continue only if the previous result is NotFound, in your disposable cluster.
kubectl create namespace opsrung-security-lab
kubectl auth can-i --list -n opsrung-security-labWhat to check
You recognize the cluster and identity. Review whether your account can read secrets or alter workloads. Your administrator identity is not an appropriate default for application automation.
Try it deliberately
Design a namespace-scoped Role for a specific task, grant only needed resources and verbs, and test both allowed and forbidden actions using the actual test identity. Avoid wildcard verbs and cluster-admin for routine delivery. Never print secret values as proof.
Recovery & cleanup
These access checks do not change RBAC. Namespace creation is the only change here; keep a record that it belongs to this exercise.
Official guidance: Kubernetes security checklist ↗
Change · lab namespace labels
2. Warn before enforcing Pod Security
A new admission rule can stop future rollouts even when existing Pods keep running.
kubectl label namespace opsrung-security-lab \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
kubectl label --dry-run=server namespace opsrung-security-lab \
pod-security.kubernetes.io/enforce=restrictedWhat to check
The warning/audit labels apply. The enforce dry run evaluates the change without saving it. An empty namespace proves little: validate representative workload manifests and fix warnings before enforcing.
Try it deliberately
Use kubectl apply --dry-run=server -f workload.yaml -n opsrung-security-lab for your reviewed manifest. Test warn/audit with an intentionally noncompliant lab Pod, then add enforce=restricted only when the valid Pod passes and the invalid Pod is rejected. Pin the policy version to your reviewed cluster minor for repeatable production rollout.
Recovery & cleanup
In this new lab namespace, remove only the labels you added: kubectl label ns opsrung-security-lab pod-security.kubernetes.io/warn- pod-security.kubernetes.io/audit-. If you later added enforce, remove that label with pod-security.kubernetes.io/enforce-.
Official guidance: Namespace Pod Security labels ↗
Manifest fragment · merge into a reviewed Linux Pod spec
3. Set the workload security context
Admission validates a policy; the workload must also declare the runtime restrictions it needs.
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: YOUR_REVIEWED_IMAGE_BY_DIGEST
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]What to check
This is a fragment, not a complete deployable manifest. Replace the image with one that supports UID 10001, include required ports/resources/volumes, then server-dry-run and test its real startup and health path.
Try it deliberately
Use a dedicated ServiceAccount if the app needs API access and scope its RBAC. A read-only root filesystem may need an emptyDir for scratch space. Avoid privileged mode, host namespaces, and hostPath mounts unless their risk has been explicitly reviewed.
Recovery & cleanup
Keep the last working workload manifest in version control. If rollout health fails, restore that version; a dry run checks admission and schema, not application behavior.
Official guidance: Kubernetes Pod Security Standards ↗
Change · save as lab-deny-ingress.yaml in the empty lab namespace
4. Test blocked traffic, not just policy creation
A NetworkPolicy object can exist without blocking traffic when the network plugin does not implement it.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: lab-deny-ingress
namespace: opsrung-security-lab
spec:
podSelector: {}
policyTypes: [Ingress]kubectl apply --dry-run=server -f lab-deny-ingress.yaml
kubectl apply -f lab-deny-ingress.yaml
kubectl describe networkpolicy lab-deny-ingress -n opsrung-security-labWhat to check
With a test server and separate client Pod, a connection that worked before should time out after policy enforcement. This ingress-only example does not restrict outbound traffic; it leaves egress and DNS unchanged.
Try it deliberately
Before trying this on workloads, confirm the plugin supports enforcement and record a baseline TCP connection. Add a narrow allow rule for an intended client and test allowed and denied sources again. Inspect other policies: their allow rules combine. Plan egress/DNS controls separately.
Recovery & cleanup
Remove only this policy with kubectl delete networkpolicy lab-deny-ingress -n opsrung-security-lab. At the end, delete the namespace only after confirming it contains exclusively your disposable lab resources; namespace deletion destroys everything in it.
Official guidance: Kubernetes NetworkPolicy behavior ↗
Reviewed 31 October 2026. Adapt to your installed versions and environment; these guides cover selected controls, not a compliance certification.