From fundamentals to advanced operations: namespaces, RBAC, pod security, workloads, service meshes, multi-cluster, backups, and disaster recovery. Each lesson includes ready-to-run commands and practical tips.
Author, test, and ship policies for validation, mutation, and generation. Enforce image signatures, mandate labels and annotations, restrict capabilities, and standardize configurations across teams.
Build reliable delivery with Argo CD or Flux, templating with Helm and Kustomize, progressive delivery, and secure supply chains. Learn patterns for environments, rollbacks, and secrets management.

Each module contains a short concept overview and a set of copy-paste commands you can run locally or in a lab cluster. Content targets Kubernetes v1.27+ and Kyverno v1.10+, with frequent updates as new releases ship.
curl -sfL https://get.k3s.io | sh -
sudo systemctl restart k3s
sudo systemctl status k3s
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
export KUBECONFIG=~/.kube/config
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno --create-namespace --wait
helm repo add policy-reporter https://kyverno.github.io/policy-reporter
helm repo update
helm install policy-reporter policy-reporter/policy-reporter \
--create-namespace -n policy-reporter \
--set ui.enabled=true \
--set kyverno-plugin.enabled=true
kubectl port-forward service/policy-reporter-ui 8082:8080 -n policy-reporter
ssh -L 8082:localhost:8082 sama@[this-vm-ip]
http://localhost:8082/
helm install kyverno-policies kyverno/kyverno-policies -n kyverno
kubectl get cpol
1. A basic compliant workload
Create file nginx-compliant.yaml with the following:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-compliant
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-compliant
template:
metadata:
labels:
app: nginx-compliant
spec:
containers:
- name: nginx
image: nginx:1.27
resources:
limits:
cpu: \"200m\"
memory: \"256Mi\"
requests:
cpu: \"100m\"
memory: \"128Mi\"
Apply it:
kubectl create namespace demo
kubectl apply -f nginx-compliant.yaml
2. A non-compliant workload (no resource limits)
Create file redis-noncompliant.yaml with the following:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-noncompliant
namespace: demo
spec:
replicas: 1
selector:
matchLabels:
app: redis-noncompliant
template:
metadata:
labels:
app: redis-noncompliant
spec:
containers:
- name: redis
image: redis:7
Apply it:
kubectl apply -f redis-noncompliant.yaml
kubectl get cpol
Example output:
NAME ADMISSION BACKGROUND READY AGE MESSAGE
disallow-capabilities true true True 15m Ready
...
restrict-sysctls true true True 15m Ready
kubectl create deployment busybox --image=busybox --namespace=demo -- sleep 3600
kubectl run standalone-pod --image=alpine --namespace=demo -- sleep 3600
Every container image reference has this shape:
[registry]/[namespace]/[image]:[tag]
If you omit parts, defaults kick in silently:
No registry -> docker.io (Docker Hub)
No namespace -> library (official images)
No tag -> :latest
Equivalent explicit forms:
kubectl create deployment busybox --image=docker.io/library/busybox:latest --namespace=demo -- sleep 3600
kubectl run standalone-pod --image=docker.io/library/alpine:latest --namespace=demo -- sleep 3600
Check pod image path:
kubectl get pod standalone-pod -n demo -o jsonpath='{.status.containerStatuses[0].image}'
Check Kyverno registry endpoint:
curl -I https://reg.kyverno.io/v2/
kubectl create namespace keycloak
Create file keycloak.yaml with the following (Deployment + Service):
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.0
args: ["start-dev"]
env:
- name: KEYCLOAK_ADMIN
value: "admin"
- name: KEYCLOAK_ADMIN_PASSWORD
value: "admin"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: keycloak
spec:
type: NodePort
selector:
app: keycloak
ports:
- port: 8080
targetPort: 8080
Apply and verify:
kubectl apply -f keycloak.yaml
kubectl -n keycloak get pods
kubectl -n keycloak get svc keycloak
Get this VM's IP:
ip a | grep "inet " | grep -v 127.0.0.1
Port-forward to access admin console:
kubectl port-forward -n keycloak service/keycloak 8080:8080
Or SSH tunnel:
ssh -L 8080:localhost:8080 sama@192.168.142.130
Check node resource pressure
kubectl describe node sama | grep -A 5 "Conditions:"
kubectl top node
Disk space
df -h /
sudo du -sh /var/lib/rancher/* 2>/dev/null | sort -rh
sudo du -sh /var/log/* 2>/dev/null | sort -rh | head -10
sudo journalctl --disk-usage
sudo du -sh /var/lib/rancher/k3s/* 2>/dev/null | sort -rh
sudo du -sh /var/lib/rancher/k3s/agent/* 2>/dev/null | sort -rh
Logs
kubectl -n keycloak logs deployment/keycloak
Add your realm, client, and users here. I can expand this section with specific steps you provide.