| tags |
|---|
k8s, k8sking |
https://gist.github.com/apinter/f83ae95f8be378ece38e66bc37084bf4 https://developers.redhat.com/articles/2023/11/06/working-kubernetes-podman-desktop#
kubectl create secret docker-registry .dockerconfigjson --docker-server=registry.gitlab.com --docker-username=docker_pull --docker-password=glpat-somexyz --docker-email=pinter1@xund.ai --dry-run=client -o yaml
- Basic Pod & Deployment
apiVersion: v1
kind: Namespace
metadata:
name: suse
apiVersion: v1
kind: Pod
metadata:
name: tumbleweed-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
readOnlyRootFilesystem: true
apiVersion: apps/v1
kind: Deployment
metadata:
name: tumbleweed-deploy
spec:
replicas: 2
selector:
matchLabels:
app: tumbleweed
template:
metadata:
labels:
app: tumbleweed
spec:
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
runAsUser: 1000
runAsGroup: 3000
readOnlyRootFilesystem: true
- DaemonSet & StatefulSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: tumbleweed-ds
spec:
selector:
matchLabels:
app: ds-worker
template:
metadata:
labels:
app: ds-worker
spec:
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
runAsUser: 1000
runAsGroup: 3000
readOnlyRootFilesystem: true
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: tumbleweed-sts
spec:
serviceName: "tumbleweed-svc"
replicas: 1
selector:
matchLabels:
app: sts-worker
template:
metadata:
labels:
app: sts-worker
spec:
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
runAsUser: 1000
runAsGroup: 3000
readOnlyRootFilesystem: true
- Jobs & CronJobs
apiVersion: batch/v1
kind: Job
metadata:
name: tumbleweed-job
spec:
template:
spec:
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
runAsUser: 1000
runAsGroup: 3000
readOnlyRootFilesystem: true
restartPolicy: Never
CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: tumbleweed-cron
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
runAsUser: 1000
runAsGroup: 3000
readOnlyRootFilesystem: true
restartPolicy: OnFailure
- Secrets & Services The "glue" and the sensitive data. Note that Secret data must be base64 encoded.
apiVersion: v1
kind: Secret
metadata:
name: my-opaque-secret
type: Opaque
data:
username: YWRtaW4= # "admin"
password: MWYyZDM0NTY= # "1f2d3456"
Docker Registry Secret
apiVersion: v1
kind: Secret
metadata:
name: regcred
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5leGFtcGxlLmNvbSI6eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJwYXNzIiwiaW1haWwiOiJhZG1pbkBleC5jb20iLCJhdXRoIjoiWVdSdGFXNDZkR0Z6Y3c9PSJ9fX0=
Service (ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: tumbleweed-svc
spec:
selector:
app: tumbleweed
ports:
- protocol: TCP
port: 80
targetPort: 8080
Quick Tip for your Lesson: Since you’ve enabled readOnlyRootFilesystem: true, remind your students that the container will fail if the application tries to write to any local directory (like /tmp or /var/log) unless you mount an emptyDir volume to those locations! Persistent Volume Claim (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tumbleweed-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Updated Pod (Mounting the PVC) To make this useful for your class, here is how you attach that PVC to the Tumbleweed pod. This allows the container to write to /data even though the rest of the root filesystem is read-only.
apiVersion: v1
kind: Pod
metadata:
name: tumbleweed-pvc-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: main
image: registry.opensuse.org/opensuse/tumbleweed:latest
command: ["/usr/bin/sleep", "infinity"]
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: storage-volume
mountPath: /data
volumes:
- name: storage-volume
persistentVolumeClaim:
claimName: tumbleweed-pvc
Pro-tip for your demo: If you want to prove the security context is working during your live demo, you can have your students exec into the pod and try to create a file:
- kubectl exec -it tumbleweed-pvc-pod -- touch /test.txt → Should fail (Read-only file system).
- kubectl exec -it tumbleweed-pvc-pod -- touch /data/test.txt → Should succeed (Writing to the mounted volume).
- Deployment & Lifecycle Get your resources up and running, and check their status.
- Apply everything in a folder: kubectl apply -f .
- Check Pod status (with labels): kubectl get pods --show-labels
- Watch scaling in real-time: kubectl get deployment tumbleweed-deploy -w
- Scale the deployment on the fly: kubectl scale deployment tumbleweed-deploy --replicas=5
- Deep-Dive Inspection When a student asks, "Why isn't it working?", these are your go-to tools.
- The "Everything" view: kubectl describe pod (Check the Events section at the bottom!)
- Check container logs: kubectl logs
- Stream logs (Follow): kubectl logs -f
- View raw YAML of a running pod: kubectl get pod -o yaml
-
Verification (Security & Storage) Use these to prove the SecurityContext and PVC are working as intended. | Goal | Command | |---|---| | Check Current User | kubectl exec -- whoami | | Check User ID | kubectl exec -- id | | Test Read-Only FS | kubectl exec -- touch /root/test.txt (Should fail) | | Test PVC Write | kubectl exec -- touch /data/success.txt (Should work) | | Check Mounts | `kubectl exec -- mount |
-
Secrets & Troubleshooting How to see what's actually inside those encoded strings.
- List all secrets: kubectl get secrets
- Decode an Opaque Secret: kubectl get secret my-opaque-secret -o jsonpath='{.data.password}' | base64 --decode
- Restart a Deployment (Rollout): kubectl rollout restart deployment tumbleweed-deploy
- Cleanup Don't leave the cluster messy!
- Delete by file: kubectl delete -f manifest.yaml
- Delete all pods in namespace: kubectl delete pods --all
- Delete the PVC (Warning: wipes data): kubectl delete pvc tumbleweed-pvc 💡 A "Quick Win" Demo Idea If you want to show off the Self-Healing nature of Kubernetes:
- Run kubectl get pods -l app=tumbleweed -w in one terminal window.
- In another, "kill" one of the pods: kubectl delete pod .
- Watch as Kubernetes immediately spins up a replacement to maintain your 2-replica count. Would you like me to put these commands into a copy-pasteable bash script so you can clear the environment quickly between classes?
-
kubectl runwith overrideskubectl run -i --tty --rm debug2 -n argocd --image=docker.io/alpine:latest --restart=Never --overrides='{ "spec": { "serviceAccount": "gcs-k8sdiff-sa" } }' -- sh kubectl run -i --tty --rm debug2 -n argocd --image=docker.io/alpine:latest --restart=Never --overrides='{ "spec": { "serviceAccount": "gcs-k8sdiff-sa" } }' --overrides='{"spec": {"imagePullSecrets": [{"name": "dockerconfigjson"}]}}' -- bash
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-admin
namespace: gitlab-runner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gitlab-admin-role
namespace: gitlab-runner
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-admin-rb
namespace: gitlab-runner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gitlab-admin-role
subjects:
- kind: ServiceAccount
name: gitlab-admin
namespace: gitlab-runner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gitlab-mongo-access
namespace: default
rules:
- apiGroups: [""]
resources: ["services", "pods", "endpoints"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-mongo-access-rb
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gitlab-mongo-access
subjects:
- kind: ServiceAccount
name: gitlab-admin
namespace: gitlab-runner