diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e55b4eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.envrc +.vagrant +*.cast diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a118f3e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# Debian Bookworm image with basic tools, kubectl and k3d +FROM debian:bookworm-slim + +LABEL maintainer="you " + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="/usr/local/bin:${PATH}" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN set -eux; \ + apt-get update; \ + apt-get upgrade -y; \ + apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg lsb-release wget git vim less procps iproute2 bash; \ + apt-get clean; \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; + +# Install modern Docker CLI (docker-ce-cli) from Docker's official APT repository +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends gnupg2; \ + mkdir -p /etc/apt/keyrings; \ + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg; \ + echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list; \ + apt-get update; \ + apt-get install -y --no-install-recommends docker-ce-cli; \ + apt-get purge -y --auto-remove gnupg2; \ + rm -rf /etc/apt/keyrings/docker.gpg /etc/apt/sources.list.d/docker.list /var/lib/apt/lists/* /tmp/* /var/tmp/*; + +# Install kubectl (stable) +RUN set -eux; \ + KUBECTL_VERSION="$(curl -L -s https://dl.k8s.io/release/stable.txt)"; \ + curl -fsSLO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"; \ + install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl; \ + rm -f kubectl; \ + kubectl version --client --kubeconfig=/dev/null || true + +# Install k3d via official install script (use --no-sudo; -b is not supported) +RUN set -eux; \ + curl -fsSL https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash -s -- --no-sudo; \ + command -v k3d >/dev/null && k3d --version || true + +# Default to an interactive shell +CMD ["/bin/bash"] diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..faeb3d0 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,21 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + config.vm.box = "debian/bookworm64" + config.vm.provider "virtualbox" do |vb| + vb.memory = "2048" # raise if you can + vb.cpus = 2 + end + + config.vm.provider :libvirt do |lv| + lv.memory = 8192 + lv.cpus = 4 + end + + config.vm.provision "shell", inline: <<-SHELL + sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get install curl -y + sudo curl -fsSL https://get.docker.com -o /tmp/get-docker.sh && sudo sh /tmp/get-docker.sh + sudo usermod -aG docker vagrant + SHELL +end diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..c5ba513 --- /dev/null +++ b/build.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +# Ensure the helper image is built locally. If missing, build from the +# Dockerfile adjacent to this script (same `contws` directory). + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +IMAGE_NAME="inftools-cn:latest" + +if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then + echo "Docker image $IMAGE_NAME not found. Building from $script_dir/Dockerfile..." + docker build -t "$IMAGE_NAME" -f "$script_dir/Dockerfile" "$script_dir" || { + echo "Failed to build Docker image $IMAGE_NAME" >&2 + exit 1 + } +fi + +# Check if the Docker network 'student-net' exists, if not, create it +if ! docker network inspect student-net >/dev/null 2>&1; then + echo "Docker network 'student-net' not found. Creating it..." + docker network create student-net || { + echo "Failed to create Docker network 'student-net'" >&2 + exit 1 + } +fi + +# docker ps | grep mycluster | wc -l +# 2 + +if docker ps | grep -q mycluster; then + echo "Cluster already exists. Skipping creation." + docker run --rm -it \ + --network student-net \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v mykube:/root/.kube \ + $IMAGE_NAME bash + exit 0 +fi + +# create cluster +# +# Capture k3d output and extract the load-balancer node name. +# Example line in output: "INFO[0005] Starting node 'k3d-mycluster-serverlb'" +# +tmpfile=$(mktemp) +# Stream docker output live to terminal and save it to a temp file for parsing +docker run --rm \ + --network student-net \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v mykube:/root/.kube \ + $IMAGE_NAME k3d cluster create mycluster --network student-net 2>&1 | tee "$tmpfile" + +# Read captured output into a variable for parsing +output=$(cat "$tmpfile") +rm -f "$tmpfile" + +# Prefer the node name that contains 'serverlb' (most likely the LB), +# otherwise fall back to the last "Starting node '..." match. +# First try to find a line that includes 'serverlb'. +LB_NODE=$(printf "%s" "$output" | grep "Starting node" | grep -E "serverlb" | sed -n "s/.*Starting node '\\([^']*\\)'.*/\\1/p" | head -n1 || true) + +if [ -z "$LB_NODE" ]; then + # Fallback: take the last Starting node match (in case serverlb isn't present) + LB_NODE=$(printf "%s" "$output" | sed -n "s/.*Starting node '\\([^']*\\)'.*/\\1/p" | tail -n1) +fi + +if [ -n "$LB_NODE" ]; then + echo "Load balancer node: $LB_NODE" + export LB_NODE +else + echo "Warning: could not parse load balancer node from k3d output" >&2 +fi + +# edit kubeconfig to use load-balancer node IP +# server: https://0.0.0.0:40115 +# needs to be changed to be sed -i 's/:34791/:6443/g' ~/.kube/config +# 0.0.0.0:40115 -> :6443 +docker run --rm \ + --network student-net \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v mykube:/root/.kube \ + $IMAGE_NAME sed -i "s/0.0.0.0:[0-9]*/${LB_NODE}:6443/g" /root/.kube/config + + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..a0b7aa9 --- /dev/null +++ b/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +IMAGE_NAME="inftools-cn:latest" + +# run shell +docker run --rm -it \ + --network student-net \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v mykube:/root/.kube \ + $IMAGE_NAME bash + +