ChaGPT added lab simulations

This commit is contained in:
Mosiur Rahman
2026-08-27 11:50:09 +06:00
parent eaef1c17a7
commit a89b4ed4c2
16 changed files with 425 additions and 75 deletions

View File

@@ -0,0 +1,28 @@
$ErrorActionPreference = 'Stop'
$principal = New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
$arguments = @(
'-NoProfile',
'-ExecutionPolicy', 'Bypass',
'-File', ('"{0}"' -f $PSCommandPath)
)
Start-Process -FilePath 'powershell.exe' -Verb RunAs -ArgumentList $arguments -Wait
exit $LASTEXITCODE
}
Write-Host 'Enabling Windows Subsystem for Linux...'
& dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
if ($LASTEXITCODE -notin 0, 3010) { throw "DISM failed with exit code $LASTEXITCODE" }
Write-Host 'Enabling Virtual Machine Platform...'
& dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
if ($LASTEXITCODE -notin 0, 3010) { throw "DISM failed with exit code $LASTEXITCODE" }
Write-Host ''
Write-Host 'Windows features are enabled. Restart Windows, then run:'
Write-Host ' .\02-install-and-build.ps1'

View File

@@ -0,0 +1,45 @@
$ErrorActionPreference = 'Stop'
$distribution = 'Ubuntu-24.04'
function Test-Distribution {
$names = @(& wsl.exe --list --quiet 2>$null) | ForEach-Object { $_.Trim("`0 ") }
return $names -contains $distribution
}
if (-not (Test-Distribution)) {
Write-Host "Installing $distribution..."
& wsl.exe --install --web-download --distribution $distribution --no-launch
if ($LASTEXITCODE -ne 0) {
throw 'Ubuntu installation failed. Confirm Windows was restarted after running 01-enable-wsl.ps1.'
}
}
& wsl.exe --set-default-version 2
if ($LASTEXITCODE -ne 0) { throw 'Could not set WSL2 as the default.' }
# Starting as root avoids an interactive Unix-user prompt in this disposable VM.
& wsl.exe --distribution $distribution --user root --exec /bin/true
if ($LASTEXITCODE -ne 0) { throw "$distribution did not initialize correctly." }
$linuxDirectory = (& wsl.exe --distribution $distribution --user root --exec wslpath -a $PSScriptRoot).Trim()
if (-not $linuxDirectory) { throw 'Could not translate the lab path into WSL.' }
Write-Host 'Installing pinned lab tools...'
& wsl.exe --distribution $distribution --user root --exec bash "$linuxDirectory/bootstrap.sh"
if ($LASTEXITCODE -ne 0) { throw 'Linux tool bootstrap failed.' }
# Reload WSL so systemd and Docker use the newly written WSL configuration.
& wsl.exe --shutdown
Start-Sleep -Seconds 3
Write-Host 'Creating the isolated Kubernetes cluster...'
& wsl.exe --distribution $distribution --user root --exec bash "$linuxDirectory/create-lab.sh" "$linuxDirectory/kind-v1.34.yaml"
if ($LASTEXITCODE -ne 0) { throw 'Cluster creation failed.' }
& wsl.exe --distribution $distribution --user root --exec bash "$linuxDirectory/verify-lab.sh"
if ($LASTEXITCODE -ne 0) { throw 'Lab verification failed.' }
Write-Host ''
Write-Host 'CKS lab is ready. Enter it with:'
Write-Host ' .\enter-lab.ps1'

64
lab-environment/README.md Normal file
View File

@@ -0,0 +1,64 @@
# CKS Local Lab
This lab runs entirely inside an Ubuntu 24.04 WSL2 virtual machine. It uses
Docker Engine and Kind to create a two-node Kubernetes cluster.
## Isolation contract
- Cluster name: `cks-lab`
- Kubernetes version: `v1.34.0`
- Lab kubeconfig: `/opt/cks-lab/kubeconfig`
- Lab context: `kind-cks-lab`
- The scripts never read, merge, or modify `$HOME/.kube/config`.
- All destructive commands are limited to the Kind cluster named `cks-lab`.
Kubernetes v1.34 is deliberate: kube-bench v0.16.0 contains a CIS mapping for
v1.34. The production cluster is not a suitable lesson environment.
## Installation
Run these commands from PowerShell in this directory:
```powershell
# Opens one UAC prompt and enables the required Windows features.
.\01-enable-wsl.ps1
```
Restart Windows when requested. Then run:
```powershell
.\02-install-and-build.ps1
```
The first Ubuntu launch can take a few minutes. The script installs Docker,
kubectl, Kind, kube-bench, creates the cluster, and installs Calico.
## Daily use
Open the lab shell:
```powershell
.\enter-lab.ps1
```
The shell sets `KUBECONFIG=/opt/cks-lab/kubeconfig` and refuses to continue if
the active context is not `kind-cks-lab`.
Verify or rebuild the lab:
```powershell
.\verify-lab.ps1
.\reset-lab.ps1
.\02-install-and-build.ps1
```
Run kube-bench against the Kind control-plane node:
```bash
docker exec -it cks-lab-control-plane \
/opt/kube-bench/kube-bench run --benchmark cis-1.12
```
Lesson answers and progress remain in this repository, so they can be carried
to another PC. Cluster state is disposable and should be rebuilt there.

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bash
set -Eeuo pipefail
KUBECTL_VERSION="v1.34.0"
KIND_VERSION="v0.32.0"
KUBE_BENCH_VERSION="0.16.0"
if [[ "${EUID}" -ne 0 ]]; then
echo "Run this script as root inside the lab WSL distribution." >&2
exit 1
fi
cat >/etc/wsl.conf <<'EOF'
[boot]
systemd=true
[user]
default=root
EOF
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y ca-certificates curl gnupg jq vim git iproute2 iptables conntrack socat
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
. /etc/os-release
cat >/etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: ${UBUNTU_CODENAME:-$VERSION_CODENAME}
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
curl -fsSLo "$tmp_dir/kubectl" "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
curl -fsSLo "$tmp_dir/kubectl.sha256" "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256"
printf '%s %s\n' "$(cat "$tmp_dir/kubectl.sha256")" "$tmp_dir/kubectl" | sha256sum --check --status
install -m 0755 "$tmp_dir/kubectl" /usr/local/bin/kubectl
curl -fsSLo "$tmp_dir/kind" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64"
curl -fsSLo "$tmp_dir/kind.sha256sum" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64.sha256sum"
(cd "$tmp_dir" && sha256sum --check --status kind.sha256sum)
install -m 0755 "$tmp_dir/kind" /usr/local/bin/kind
curl -fsSLo "$tmp_dir/kube-bench.tar.gz" \
"https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz"
curl -fsSLo "$tmp_dir/checksums.txt" \
"https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_checksums.txt"
(cd "$tmp_dir" && grep " kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz$" checksums.txt | sha256sum --check --status)
rm -rf /opt/cks-lab/tools/kube-bench
install -d /opt/cks-lab/tools/kube-bench
tar -xzf "$tmp_dir/kube-bench.tar.gz" -C /opt/cks-lab/tools/kube-bench
ln -sfn /opt/cks-lab/tools/kube-bench/kube-bench /usr/local/bin/kube-bench
printf 'Installed kubectl %s, Kind %s, and kube-bench %s.\n' \
"$KUBECTL_VERSION" "$KIND_VERSION" "$KUBE_BENCH_VERSION"

View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -Eeuo pipefail
CLUSTER_NAME="cks-lab"
KUBECONFIG_PATH="/opt/cks-lab/kubeconfig"
NODE_IMAGE="kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a"
CALICO_VERSION="v3.32.1"
CONFIG_PATH="${1:?Pass the Kind configuration path.}"
if [[ "${EUID}" -ne 0 ]]; then
echo "Run this script as root inside the lab WSL distribution." >&2
exit 1
fi
systemctl start docker 2>/dev/null || service docker start
install -d -m 0700 /opt/cks-lab
if ! kind get clusters | grep -Fxq "$CLUSTER_NAME"; then
kind create cluster \
--name "$CLUSTER_NAME" \
--image "$NODE_IMAGE" \
--config "$CONFIG_PATH" \
--kubeconfig "$KUBECONFIG_PATH"
fi
export KUBECONFIG="$KUBECONFIG_PATH"
chmod 0600 "$KUBECONFIG"
context="$(kubectl config current-context)"
if [[ "$context" != "kind-${CLUSTER_NAME}" ]]; then
echo "Safety check failed: unexpected context $context" >&2
exit 1
fi
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/operator-crds.yaml"
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/tigera-operator.yaml"
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/custom-resources.yaml"
kubectl wait --for=condition=Available deployment/tigera-operator -n tigera-operator --timeout=300s
kubectl wait --for=condition=Ready nodes --all --timeout=600s
for node in "${CLUSTER_NAME}-control-plane" "${CLUSTER_NAME}-worker"; do
docker exec "$node" rm -rf /opt/kube-bench
docker cp /opt/cks-lab/tools/kube-bench "$node":/opt/kube-bench
docker exec "$node" /opt/kube-bench/kube-bench version
done

View File

@@ -0,0 +1,17 @@
$ErrorActionPreference = 'Stop'
$distribution = 'Ubuntu-24.04'
& wsl.exe --distribution $distribution --user root --exec bash -lc @'
export KUBECONFIG=/opt/cks-lab/kubeconfig
context="$(kubectl config current-context 2>/dev/null || true)"
if [[ "$context" != "kind-cks-lab" ]]; then
echo "Safety check failed: expected kind-cks-lab, got ${context:-none}." >&2
exit 1
fi
echo "CKS lab: $(kubectl version --output=json | jq -r .serverVersion.gitVersion)"
echo "Context: $context"
exec bash
'@
if ($LASTEXITCODE -ne 0) { throw 'Could not enter the isolated CKS lab.' }

View File

@@ -0,0 +1,10 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: cks-lab
nodes:
- role: control-plane
- role: worker
networking:
disableDefaultCNI: true
podSubnet: 192.168.0.0/16

View File

@@ -0,0 +1,5 @@
$ErrorActionPreference = 'Stop'
$linuxDirectory = (& wsl.exe --distribution Ubuntu-24.04 --user root --exec wslpath -a $PSScriptRoot).Trim()
& wsl.exe --distribution Ubuntu-24.04 --user root --exec bash "$linuxDirectory/reset-lab.sh"
if ($LASTEXITCODE -ne 0) { throw 'Lab reset failed.' }

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -Eeuo pipefail
CLUSTER_NAME="cks-lab"
export KUBECONFIG="/opt/cks-lab/kubeconfig"
if [[ "$CLUSTER_NAME" != "cks-lab" ]]; then
echo "Refusing to delete an unexpected cluster name." >&2
exit 1
fi
systemctl start docker 2>/dev/null || service docker start
if kind get clusters | grep -Fxq "$CLUSTER_NAME"; then
kind delete cluster --name "$CLUSTER_NAME"
else
echo "The cks-lab cluster does not exist."
fi
rm -f "$KUBECONFIG"

View File

@@ -0,0 +1,5 @@
$ErrorActionPreference = 'Stop'
$linuxDirectory = (& wsl.exe --distribution Ubuntu-24.04 --user root --exec wslpath -a $PSScriptRoot).Trim()
& wsl.exe --distribution Ubuntu-24.04 --user root --exec bash "$linuxDirectory/verify-lab.sh"
if ($LASTEXITCODE -ne 0) { throw 'Lab verification failed.' }

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -Eeuo pipefail
export KUBECONFIG="/opt/cks-lab/kubeconfig"
expected_context="kind-cks-lab"
context="$(kubectl config current-context 2>/dev/null || true)"
if [[ "$context" != "$expected_context" ]]; then
echo "Safety check failed: expected $expected_context, got ${context:-none}." >&2
exit 1
fi
kubectl wait --for=condition=Ready nodes --all --timeout=60s
kubectl get nodes -o wide
kubectl get pods -A
for node in cks-lab-control-plane cks-lab-worker; do
docker inspect "$node" >/dev/null
docker exec "$node" /opt/kube-bench/kube-bench version
done
echo "Verified isolated context: $context"