From 18e02d0d9d9dc7c96f627ff1e5c9b09c3d4a7962 Mon Sep 17 00:00:00 2001 From: Fabian Hardt Date: Fri, 5 Dec 2025 14:27:54 +0100 Subject: [PATCH 1/4] fix CKAD lab2 question 2 --- facilitator/assets/exams/ckad/002/answers.md | 3 +++ .../scripts/validation/q2_s4_validate_shared_volume.sh | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/facilitator/assets/exams/ckad/002/answers.md b/facilitator/assets/exams/ckad/002/answers.md index f2f7042..b0b2541 100644 --- a/facilitator/assets/exams/ckad/002/answers.md +++ b/facilitator/assets/exams/ckad/002/answers.md @@ -62,6 +62,9 @@ spec: volumeMounts: - name: log-volume mountPath: /var/log + - name: log-volume + mountPath: /var/log/nginx + subPath: nginx - name: sidecar-container image: busybox command: ['sh', '-c', 'while true; do echo $(date) >> /var/log/app.log; sleep 5; done'] diff --git a/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh b/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh index f9d7201..6d19a34 100755 --- a/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh +++ b/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh @@ -6,10 +6,10 @@ VOLUME_NAME=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath if [[ "$VOLUME_NAME" == "log-volume" ]]; then # Volume exists, now check if it's mounted in both containers - MAIN_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="main-container")].volumeMounts[?(@.name=="log-volume")].mountPath}' 2>/dev/null) - SIDECAR_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="sidecar-container")].volumeMounts[?(@.name=="log-volume")].mountPath}' 2>/dev/null) - - if [[ "$MAIN_CONTAINER_MOUNT" == "/var/log" && "$SIDECAR_CONTAINER_MOUNT" == "/var/log" ]]; then + MAIN_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="main-container")].volumeMounts[?(@.name=="log-volume")]}' 2>/dev/null) + SIDECAR_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="sidecar-container")].volumeMounts[?(@.name=="log-volume")]}' 2>/dev/null) + + if [[ "$MAIN_CONTAINER_MOUNT" == *"/var/log"* && "$SIDECAR_CONTAINER_MOUNT" == "/var/log" ]]; then # Both containers have the volume mounted at the correct path exit 0 else @@ -21,4 +21,4 @@ if [[ "$VOLUME_NAME" == "log-volume" ]]; then else echo "Volume 'log-volume' does not exist in pod 'multi-container-pod'" exit 1 -fi \ No newline at end of file +fi \ No newline at end of file From b88dcd7f4002cb86321749b2e3f58adf7539e7d4 Mon Sep 17 00:00:00 2001 From: Fabian Hardt Date: Fri, 5 Dec 2025 14:46:57 +0100 Subject: [PATCH 2/4] use exact match for sidecar container --- .../ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh b/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh index 6d19a34..a6ddf03 100755 --- a/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh +++ b/facilitator/assets/exams/ckad/002/scripts/validation/q2_s4_validate_shared_volume.sh @@ -7,7 +7,7 @@ VOLUME_NAME=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath if [[ "$VOLUME_NAME" == "log-volume" ]]; then # Volume exists, now check if it's mounted in both containers MAIN_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="main-container")].volumeMounts[?(@.name=="log-volume")]}' 2>/dev/null) - SIDECAR_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="sidecar-container")].volumeMounts[?(@.name=="log-volume")]}' 2>/dev/null) + SIDECAR_CONTAINER_MOUNT=$(kubectl get pod multi-container-pod -n multi-container -o jsonpath='{.spec.containers[?(@.name=="sidecar-container")].volumeMounts[?(@.name=="log-volume")].mountPath}' 2>/dev/null) if [[ "$MAIN_CONTAINER_MOUNT" == *"/var/log"* && "$SIDECAR_CONTAINER_MOUNT" == "/var/log" ]]; then # Both containers have the volume mounted at the correct path From e64499074920426c65808d7748af9970fecae7a3 Mon Sep 17 00:00:00 2001 From: Fabian Hardt Date: Thu, 11 Dec 2025 17:41:34 +0100 Subject: [PATCH 3/4] fix q10, make it clearer for students --- facilitator/assets/exams/ckad/001/answers.md | 8 ++++---- facilitator/assets/exams/ckad/001/assessment.json | 2 +- .../001/scripts/validation/q10_s1_validate_secret.sh | 9 +++++---- .../scripts/validation/q10_s3_validate_pod_env_vars.sh | 8 +++++++- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/facilitator/assets/exams/ckad/001/answers.md b/facilitator/assets/exams/ckad/001/answers.md index 4add7da..8f360e0 100644 --- a/facilitator/assets/exams/ckad/001/answers.md +++ b/facilitator/assets/exams/ckad/001/answers.md @@ -249,11 +249,11 @@ Save as `config-pod.yaml` and apply: kubectl apply -f config-pod.yaml ``` -## Question 10: Create a Secret named 'db-credentials' in namespace 'workloads' containing username=admin and password=securepass. Then create a Pod named 'secure-pod' using 'mysql:5.7' image with these credentials set as environment variables DB_USER and DB_PASSWORD +## Question 10: Create a Secret named 'db-credentials' in namespace 'workloads' containing username=admin, random=true and password=securepass. Then create a Pod named 'secure-pod' using 'mysql:9.5.0' image with these credentials set as environment variables DB_USER, MYSQL_RANDOM_ROOT_PASSWORD and DB_PASSWORD ```bash # Create the Secret -kubectl create secret generic db-credentials -n workloads --from-literal=username=admin --from-literal=password=securepass +kubectl create secret generic db-credentials -n workloads --from-literal=username=admin --from-literal=password=securepass --from-literal=random=true ``` Create the Pod with Secret environment variables: @@ -278,11 +278,11 @@ spec: secretKeyRef: name: db-credentials key: password - - name: MYSQL_ROOT_PASSWORD + - name: MYSQL_RANDOM_ROOT_PASSWORD valueFrom: secretKeyRef: name: db-credentials - key: password + key: random restartPolicy: Always ``` diff --git a/facilitator/assets/exams/ckad/001/assessment.json b/facilitator/assets/exams/ckad/001/assessment.json index e4f75f4..27664f2 100644 --- a/facilitator/assets/exams/ckad/001/assessment.json +++ b/facilitator/assets/exams/ckad/001/assessment.json @@ -274,7 +274,7 @@ "id": "10", "namespace": "workloads", "machineHostname": "ckad9999", - "question": "The database team needs to securely deploy a MySQL instance with proper credential management. \n\nCreate a Secret named `db-credentials` in namespace `workloads` containing two sensitive values: `username=admin` and `password=securepass`. \n\nThen create a Pod named `secure-pod` using the `mysql:5.7` image that uses these credentials. \n\nConfigure the pod to access the Secret values as environment variables named `DB_USER` and `DB_PASSWORD` respectively. \n\nThis pattern demonstrates secure handling of sensitive information in Kubernetes without hardcoding credentials in the pod specification. Ensure the MySQL container is properly configured to use these environment variables for authentication.", + "question": "The database team needs to securely deploy a MySQL instance with proper credential management. \n\nCreate a Secret named `db-credentials` in namespace `workloads` containing three sensitive values: `username=admin`, `random=true` and `password=securepass`. \n\nThen create a Pod named `secure-pod` using the `mysql:9.5.0` image that uses these credentials. \n\nConfigure the pod to access the Secret values as environment variables named `DB_USER`, `MYSQL_RANDOM_ROOT_PASSWORD` and `DB_PASSWORD` respectively. \n\nThis pattern demonstrates secure handling of sensitive information in Kubernetes without hardcoding credentials in the pod specification. Ensure the MySQL container is properly configured to use these environment variables for authentication.", "concepts": ["secrets", "pods", "environment-variables", "mysql"], "verification": [ { diff --git a/facilitator/assets/exams/ckad/001/scripts/validation/q10_s1_validate_secret.sh b/facilitator/assets/exams/ckad/001/scripts/validation/q10_s1_validate_secret.sh index bfd5e43..4e65620 100755 --- a/facilitator/assets/exams/ckad/001/scripts/validation/q10_s1_validate_secret.sh +++ b/facilitator/assets/exams/ckad/001/scripts/validation/q10_s1_validate_secret.sh @@ -3,13 +3,14 @@ # Validate if the Secret 'db-credentials' exists in the 'workloads' namespace with correct data USERNAME=$(kubectl get secret db-credentials -n workloads -o jsonpath='{.data.username}' 2>/dev/null | base64 --decode) PASSWORD=$(kubectl get secret db-credentials -n workloads -o jsonpath='{.data.password}' 2>/dev/null | base64 --decode) +RANDOM=$(kubectl get secret db-credentials -n workloads -o jsonpath='{.data.random}' 2>/dev/null | base64 --decode) -if [ "$USERNAME" = "admin" ] && [ "$PASSWORD" = "securepass" ]; then +if [ "$USERNAME" = "admin" ] && [ "$PASSWORD" = "securepass" ] && [ "$RANDOM" = "true" ]; then echo "Success: Secret 'db-credentials' exists with correct data" exit 0 else echo "Error: Secret 'db-credentials' does not have the correct data." - echo "Expected: username=admin, password=securepass" - echo "Found: username=$USERNAME, password=$PASSWORD" + echo "Expected: username=admin, password=securepass, random=true" + echo "Found: username=$USERNAME, password=$PASSWORD, random=$RANDOM" exit 1 -fi \ No newline at end of file +fi \ No newline at end of file diff --git a/facilitator/assets/exams/ckad/001/scripts/validation/q10_s3_validate_pod_env_vars.sh b/facilitator/assets/exams/ckad/001/scripts/validation/q10_s3_validate_pod_env_vars.sh index 4173ce4..e9acd30 100644 --- a/facilitator/assets/exams/ckad/001/scripts/validation/q10_s3_validate_pod_env_vars.sh +++ b/facilitator/assets/exams/ckad/001/scripts/validation/q10_s3_validate_pod_env_vars.sh @@ -8,6 +8,7 @@ NAMESPACE="workloads" EXPECTED_SECRET="db-credentials" EXPECTED_USER_KEY="username" EXPECTED_PASSWORD_KEY="password" +EXPECTED_RANDOM_KEY="random" # Extract secret name and key used for DB_USER DB_USER_SECRET=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.containers[0].env[?(@.name=='DB_USER')].valueFrom.secretKeyRef.name}") @@ -17,9 +18,14 @@ DB_USER_KEY=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.co DB_PASSWORD_SECRET=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.containers[0].env[?(@.name=='DB_PASSWORD')].valueFrom.secretKeyRef.name}") DB_PASSWORD_KEY=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.containers[0].env[?(@.name=='DB_PASSWORD')].valueFrom.secretKeyRef.key}") +# Extract secret name and key used for MYSQL_RANDOM_ROOT_PASSWORD +MYSQL_RANDOM_ROOT_PASSWORD_SECRET=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.containers[0].env[?(@.name=='MYSQL_RANDOM_ROOT_PASSWORD')].valueFrom.secretKeyRef.name}") +MYSQL_RANDOM_ROOT_PASSWORD_KEY=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.spec.containers[0].env[?(@.name=='MYSQL_RANDOM_ROOT_PASSWORD')].valueFrom.secretKeyRef.key}") + # Validate all if [[ "$DB_USER_SECRET" == "$EXPECTED_SECRET" && "$DB_USER_KEY" == "$EXPECTED_USER_KEY" && - "$DB_PASSWORD_SECRET" == "$EXPECTED_SECRET" && "$DB_PASSWORD_KEY" == "$EXPECTED_PASSWORD_KEY" ]]; then + "$DB_PASSWORD_SECRET" == "$EXPECTED_SECRET" && "$DB_PASSWORD_KEY" == "$EXPECTED_PASSWORD_KEY" && + "$MYSQL_RANDOM_ROOT_PASSWORD_SECRET" == "$EXPECTED_SECRET" && "$MYSQL_RANDOM_ROOT_PASSWORD_KEY" == "$EXPECTED_RANDOM_KEY" ]]; then echo "✅ Success: Pod '$POD_NAME' has correct secret name and keys for env variables" exit 0 else From 70c1a5e55c59a1d21ef6973e24e482ee3e8019c0 Mon Sep 17 00:00:00 2001 From: Fabian Hardt Date: Thu, 11 Dec 2025 18:12:31 +0100 Subject: [PATCH 4/4] use correct image version --- facilitator/assets/exams/ckad/001/answers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facilitator/assets/exams/ckad/001/answers.md b/facilitator/assets/exams/ckad/001/answers.md index 8f360e0..c5a8773 100644 --- a/facilitator/assets/exams/ckad/001/answers.md +++ b/facilitator/assets/exams/ckad/001/answers.md @@ -266,7 +266,7 @@ metadata: spec: containers: - name: mysql - image: mysql:latest + image: mysql:9.5.0 env: - name: DB_USER valueFrom: