docs: add Kubernetes CKS study notes
This commit is contained in:
162
kubernetes/cks/exam-by-claude/seed.sh
Normal file
162
kubernetes/cks/exam-by-claude/seed.sh
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env bash
|
||||
# CKS mock — seed the cluster with the objects each task expects. Idempotent-ish.
|
||||
set -euo pipefail
|
||||
kubectl config use-context kind-cks >/dev/null
|
||||
|
||||
echo "[*] Namespaces..."
|
||||
for ns in prod web dev apps restricted-ns images sysh runtime; do
|
||||
kubectl create ns "$ns" --dry-run=client -o yaml | kubectl apply -f - >/dev/null
|
||||
done
|
||||
|
||||
# ---------- Task 1: NetworkPolicy ----------
|
||||
kubectl -n prod apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: db, namespace: prod, labels: {app: db}}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: {matchLabels: {app: db}}
|
||||
template:
|
||||
metadata: {labels: {app: db}}
|
||||
spec:
|
||||
containers:
|
||||
- name: db
|
||||
image: hashicorp/http-echo:1.0
|
||||
args: ["-text=db-ok", "-listen=:5432"]
|
||||
ports: [{containerPort: 5432}]
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: {name: db, namespace: prod}
|
||||
spec:
|
||||
selector: {app: db}
|
||||
ports: [{port: 5432, targetPort: 5432}]
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: frontend, namespace: prod, labels: {app: frontend}}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: {matchLabels: {app: frontend}}
|
||||
template:
|
||||
metadata: {labels: {app: frontend}}
|
||||
spec: {containers: [{name: c, image: curlimages/curl:8.11.1, command: ["sleep","infinity"]}]}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: attacker, namespace: prod, labels: {app: attacker}}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: {matchLabels: {app: attacker}}
|
||||
template:
|
||||
metadata: {labels: {app: attacker}}
|
||||
spec: {containers: [{name: c, image: curlimages/curl:8.11.1, command: ["sleep","infinity"]}]}
|
||||
EOF
|
||||
|
||||
# ---------- Task 2: Ingress TLS ----------
|
||||
kubectl -n web apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: hello, namespace: web}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: {matchLabels: {app: hello}}
|
||||
template:
|
||||
metadata: {labels: {app: hello}}
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: hashicorp/http-echo:1.0
|
||||
args: ["-text=hello-tls", "-listen=:5678"]
|
||||
ports: [{containerPort: 5678}]
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: {name: hello, namespace: web}
|
||||
spec:
|
||||
selector: {app: hello}
|
||||
ports: [{port: 80, targetPort: 5678}]
|
||||
EOF
|
||||
|
||||
# ---------- Task 4: RBAC least-privilege (over-permissive to fix) ----------
|
||||
kubectl -n dev apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata: {name: ci-runner, namespace: dev}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata: {name: ci-runner-role, namespace: dev}
|
||||
rules:
|
||||
- apiGroups: ["*"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"] # WAY too broad — task: restrict to get/list/watch on pods & configmaps
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata: {name: ci-runner-rb, namespace: dev}
|
||||
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: ci-runner-role}
|
||||
subjects: [{kind: ServiceAccount, name: ci-runner, namespace: dev}]
|
||||
EOF
|
||||
|
||||
# ---------- Task 6: automountServiceAccountToken ----------
|
||||
kubectl -n apps apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata: {name: web-sa, namespace: apps}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: web, namespace: apps}
|
||||
spec:
|
||||
replicas: 2
|
||||
selector: {matchLabels: {app: web}}
|
||||
template:
|
||||
metadata: {labels: {app: web}}
|
||||
spec:
|
||||
serviceAccountName: web-sa
|
||||
containers: [{name: c, image: nginx:1.27, ports: [{containerPort: 80}]}]
|
||||
EOF
|
||||
|
||||
# ---------- Task 9: Pod Security Admission (violating workload) ----------
|
||||
kubectl -n restricted-ns apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: payments, namespace: restricted-ns}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: {matchLabels: {app: payments}}
|
||||
template:
|
||||
metadata: {labels: {app: payments}}
|
||||
spec:
|
||||
containers:
|
||||
- name: c
|
||||
image: nginx:1.27
|
||||
securityContext:
|
||||
privileged: true # violates restricted
|
||||
allowPrivilegeEscalation: true
|
||||
EOF
|
||||
|
||||
# ---------- Task 13: Trivy image scan (mixed vuln levels) ----------
|
||||
kubectl -n images apply -f - >/dev/null <<'EOF'
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata: {name: legacy-app, namespace: images, labels: {scan: "true"}}
|
||||
spec:
|
||||
containers: [{name: c, image: nginx:1.19.0}] # old, HIGH/CRITICAL CVEs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata: {name: old-debian, namespace: images, labels: {scan: "true"}}
|
||||
spec:
|
||||
containers: [{name: c, image: debian:10}] # EOL, plenty of CVEs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata: {name: clean-app, namespace: images, labels: {scan: "true"}}
|
||||
spec:
|
||||
containers: [{name: c, image: nginx:1.27}] # relatively clean
|
||||
EOF
|
||||
|
||||
echo "[*] Seed complete. Namespaces: prod web dev apps restricted-ns images sysh runtime"
|
||||
echo "[*] Note: Kyverno / Falco / gVisor get installed inside their own task setup blocks."
|
||||
Reference in New Issue
Block a user