ChaGPT added lab simulations
This commit is contained in:
28
lab-environment/01-enable-wsl.ps1
Normal file
28
lab-environment/01-enable-wsl.ps1
Normal 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'
|
||||
|
||||
45
lab-environment/02-install-and-build.ps1
Normal file
45
lab-environment/02-install-and-build.ps1
Normal 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
64
lab-environment/README.md
Normal 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.
|
||||
|
||||
64
lab-environment/bootstrap.sh
Normal file
64
lab-environment/bootstrap.sh
Normal 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"
|
||||
46
lab-environment/create-lab.sh
Normal file
46
lab-environment/create-lab.sh
Normal 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
|
||||
|
||||
17
lab-environment/enter-lab.ps1
Normal file
17
lab-environment/enter-lab.ps1
Normal 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.' }
|
||||
|
||||
10
lab-environment/kind-v1.34.yaml
Normal file
10
lab-environment/kind-v1.34.yaml
Normal 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
|
||||
|
||||
5
lab-environment/reset-lab.ps1
Normal file
5
lab-environment/reset-lab.ps1
Normal 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.' }
|
||||
|
||||
19
lab-environment/reset-lab.sh
Normal file
19
lab-environment/reset-lab.sh
Normal 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"
|
||||
|
||||
5
lab-environment/verify-lab.ps1
Normal file
5
lab-environment/verify-lab.ps1
Normal 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.' }
|
||||
|
||||
23
lab-environment/verify-lab.sh
Normal file
23
lab-environment/verify-lab.sh
Normal 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"
|
||||
|
||||
Reference in New Issue
Block a user