2 - Install node
This machine stops being a “Docker app server” and becomes a Kubernetes-managed worker node.
List running container
First list running containers with docker ps -a. You need to know what will be disrupted.
My result:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05a3e66f7531 ipeseserv3.epfl.ch:88/mote-school-tool:staging "/app/entrypoint.sh" 2 weeks ago Up 2 weeks 0.0.0.0:4213->8501/tcp mote-tool
0f1fb2e42cd7 ipeseserv3.epfl.ch:88/env-421-school-tool:staging "/app/entrypoint.sh" 3 weeks ago Up 3 weeks 0.0.0.0:4211->8501/tcp env-421-school-tool
3b963cd402bc ipeseserv3.epfl.ch:88/cas-sese-iaet-tool:staging "/app/entrypoint.sh" 3 months ago Up 3 months 0.0.0.0:4212->8501/tcp iaet-tool
0faa9c6b90ba ipeseserv3.epfl.ch:88/energyscope-calculator:staging "streamlit run calcu…" 5 months ago Up 5 months 0.0.0.0:6061->8501/tcp energyscope-calculator
c2f15f3c4403 ipeseserv3.epfl.ch:88/reho-fm:staging "gunicorn --bind 0.0…" 9 months ago Up 9 months 8000/tcp, 0.0.0.0:8000->80/tcp reho-fm
ddc9031d49c3 ipeseserv3.epfl.ch:88/energyscope-quebec:staging "streamlit run calcu…" 9 months ago Up 9 months 0.0.0.0:6081->8501/tcp energyscope-quebec
a0b0e3f21f51 ipeseserv3.epfl.ch:88/energyscope-main:staging "/docker-entrypoint.…" 9 months ago Up 9 months 0.0.0.0:6041->80/tcp energyscope.ch
6bfaea78e14b ipeseserv3.epfl.ch:88/flask-entra:v0.4.4 "gunicorn -w 1 -b 0.…" 9 months ago Up 9 months 8000/tcp, 0.0.0.0:5050->5000/tcp model-documentation
ad38d45342dc traefik:v2.10 "/entrypoint.sh --lo…" 9 months ago Up 6 weeks 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8080->8080/tcp traefikWe currently have:
- multiple production apps (Streamlit, Flask, etc.)
- Traefik reverse proxy
- exposed ports (80, 443, 8080, etc.)
👉 This will NOT coexist nicely with Kubernetes workloads.
Step 1 — Stop and clean up Docker
Kubernetes uses containerd, not Docker engine. Keeping both = chaos.
Stop all running containers
sudo docker stop $(sudo docker ps -q)Remove containers, images, volumes
sudo docker system prune -a --volumes -fUninstall Docker completely
sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo apt-get autoremove -y
#Remove leftover files
sudo rm -rf /var/lib/docker /etc/docker
sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /etc/apt/keyrings/docker.gpg
sudo apt-get updateStep 2 — System prep
update system
sudo apt-get update && sudo apt-get upgrade -ydeactivate swap memory
Kubernetes needs predictable resources - not stricltly true anymore but gives a easier and more predictable installation
# Turn off swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# Verify swap is off (should return empty)
free -h | grep SwapStep 3 — Kernel modules
Preparing the Linux kernel so Kubernetes networking works properly - When the system boots, always load these kernel modules. - then load them manually for the current session
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# Verify both loaded
lsmod | grep -E 'overlay|br_netfilter'Step 4 — Network settings
tell Linux how to handle network traffic for containers and Kubernetes pods: - “If container traffic goes through a virtual network bridge, still apply firewall rules (iptables) to it.”
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
#Apply
sudo sysctl --system
# Verify
sysctl net.ipv4.ip_forwardStep 5 — Install containerd
This replaces Docker as the container runtime.
Kubernetes → kubelet → containerd → containers
sudo apt-get install -y containerdGenerate config
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.tomlEnable systemd cgroups (Required on Ubuntu 24.04)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.tomlRestart and enable
sudo systemctl restart containerd
sudo systemctl enable containerd
# Verify
sudo systemctl status containerdStep 6 — Install kubeadm, kubelet, kubectl
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# Verify
kubeadm versionStep 7 — Join the cluster
This node connects to the control plane and becomes a worker.
Run this on stivm0052 (control plane) if not done yet
kubeadm token create --print-join-commandThis will give you the command to execute in your node to join the control pane. Something like this:
sudo kubeadm join <control-plane-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>Step 8 — Verify from control plane
On the control pane run:
kubectl get nodesyou should see your node here