Skip to content

Instantly share code, notes, and snippets.

@finnie2006
Last active November 18, 2025 08:56
Show Gist options
  • Select an option

  • Save finnie2006/2dcc50251df3d93cd3e39c9794d1eab9 to your computer and use it in GitHub Desktop.

Select an option

Save finnie2006/2dcc50251df3d93cd3e39c9794d1eab9 to your computer and use it in GitHub Desktop.
Bash script to install k3s node / worker node with option for kubernetes dashboard, interactive bash script
#!/bin/bash
# K3s Interactive Installer
# This script provides a menu-driven interface to install a k3s master or worker node,
# and to install the Kubernetes Dashboard.
# --- Colors for better readability ---
NC='\033[0m' # No Color
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
# --- Function to check for root privileges ---
check_root() {
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Error: This script must be run as root. Please use 'sudo bash k3s_installer.sh'.${NC}"
exit 1
fi
}
# --- Function to install k3s master node ---
install_master() {
echo -e "${BLUE}Starting k3s master node installation...${NC}"
# The --write-kubeconfig-mode 644 makes the kubeconfig file readable by non-root users.
# The --disable traefik is optional, but many users prefer to install their own ingress controller.
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644 --disable traefik" sh -
if [ $? -eq 0 ]; then
echo -e "${GREEN}k3s master node installed successfully!${NC}"
echo -e "${BLUE}Configuring firewall for master node...${NC}"
# Port 6443 is required for workers to join the cluster.
configure_firewall "6443"
echo -e "${YELLOW}Wait for the node to be ready...${NC}"
sleep 15
# Verify node status
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
if kubectl get node | grep -q "Ready"; then
echo -e "${GREEN}Master node is Ready.${NC}"
install_dashboard_prompt
else
echo -e "${RED}Master node installation seems to have failed or is taking too long to start.${NC}"
echo -e "${YELLOW}Please check the service status with: 'sudo systemctl status k3s'${NC}"
fi
else
echo -e "${RED}k3s master node installation failed.${NC}"
fi
show_token
}
# --- Function to prompt for Kubernetes Dashboard installation ---
install_dashboard_prompt() {
while true; do
read -p "Do you want to install the Kubernetes Dashboard? (y/n): " yn
case $yn in
[Yy]* ) install_dashboard; break;;
[Nn]* ) echo -e "${YELLOW}Skipping Kubernetes Dashboard installation.${NC}"; break;;
* ) echo "Please answer yes or no.";;
esac
done
}
# --- Function to configure firewall for a specific port ---
configure_firewall() {
local port=$1
if [ -z "$port" ]; then
echo -e "${RED}Error: No port provided to configure_firewall function.${NC}"
return
fi
echo -e "${BLUE}Checking for active firewalls to open port ${port}...${NC}"
# Check for firewalld
if systemctl is-active --quiet firewalld; then
echo -e "${YELLOW}Firewalld is active. Opening port ${port}/tcp...${NC}"
firewall-cmd --permanent --add-port=${port}/tcp > /dev/null 2>&1
firewall-cmd --reload > /dev/null 2>&1
echo -e "${GREEN}Firewall rule for port ${port} added to firewalld.${NC}"
# Check for ufw
elif command -v ufw &> /dev/null && ufw status | grep -q 'Status: active'; then
echo -e "${YELLOW}UFW is active. Allowing port ${port}/tcp...${NC}"
ufw allow ${port}/tcp > /dev/null 2>&1
echo -e "${GREEN}Firewall rule for port ${port} added to UFW.${NC}"
else
echo -e "${YELLOW}No common active firewall (firewalld, ufw) detected.${NC}"
read -p "Would you like to install and configure UFW (Uncomplicated Firewall)? (y/n): " install_ufw
if [[ "$install_ufw" =~ ^[Yy]$ ]]; then
echo -e "${BLUE}Installing UFW...${NC}"
apt-get update -y > /dev/null 2>&1
apt-get install -y ufw > /dev/null 2>&1
echo -e "${GREEN}UFW installed.${NC}"
echo -e "${BLUE}Configuring UFW rules...${NC}"
ufw allow 22/tcp # SSH
ufw allow 6443/tcp # Kubernetes API Server
ufw allow 10250/tcp # Kubelet
ufw allow ${port}/tcp # Dashboard NodePort or other ports
ufw --force enable
echo -e "${GREEN}UFW has been enabled and configured.${NC}"
ufw status
else
echo -e "${YELLOW}Skipping UFW installation. You may need to configure your firewall manually for port ${port}.${NC}"
fi
fi
}
# --- Function to display Dashboard access info and token ---
show_dashboard_info() {
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
echo -e "${BLUE}Retrieving Dashboard access information...${NC}"
NODE_PORT=$(kubectl -n kubernetes-dashboard get svc kubernetes-dashboard -o=jsonpath='{.spec.ports[0].nodePort}')
if [ -z "$NODE_PORT" ]; then
echo -e "${RED}Could not determine Dashboard NodePort. Is the dashboard installed?${NC}"
return
fi
echo -e "${YELLOW}Generating a new access token for the Dashboard...${NC}"
DASHBOARD_TOKEN=$(kubectl -n kubernetes-dashboard create token admin-user --duration=8760h)
echo -e "${GREEN}--- Kubernetes Dashboard Access Token ---${NC}"
echo -e "Use the token below to log in to the Dashboard."
echo -e "${YELLOW}$DASHBOARD_TOKEN${NC}"
echo -e "${GREEN}------------------------------------------${NC}"
IP_ADDR=$(hostname -I | awk '{print $1}')
echo -e "\n${BLUE}You can access the dashboard securely at:${NC}"
echo -e "${YELLOW}https://${IP_ADDR}:${NODE_PORT}${NC}"
echo -e "${YELLOW}Note: Your browser will show a security warning for a self-signed certificate. This is expected. Please accept the risk to proceed.${NC}"
}
# --- Function to install Kubernetes Dashboard ---
install_dashboard() {
echo -e "${BLUE}Installing Kubernetes Dashboard...${NC}"
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# Using the recommended manifest from the official Kubernetes Dashboard project
DASHBOARD_VERSION="v2.7.0"
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/${DASHBOARD_VERSION}/aio/deploy/recommended.yaml
# Create a service account for the dashboard
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
if [ $? -eq 0 ]; then
echo -e "${GREEN}Kubernetes Dashboard deployed successfully.${NC}"
echo -e "${BLUE}Switching Dashboard to NodePort service for secure HTTPS access...${NC}"
kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard -p '{"spec": {"type": "NodePort"}}'
echo -e "${YELLOW}Waiting for NodePort to be assigned...${NC}"
sleep 5
NODE_PORT_CHECK=$(kubectl -n kubernetes-dashboard get svc kubernetes-dashboard -o=jsonpath='{.spec.ports[0].nodePort}')
if [ -z "$NODE_PORT_CHECK" ]; then
echo -e "${RED}Could not determine Dashboard NodePort. Please check the service manually with 'kubectl -n kubernetes-dashboard get svc'.${NC}"
return
fi
# Configure firewall for the newly assigned port
configure_firewall "$NODE_PORT_CHECK"
# Show access info
show_dashboard_info
else
echo -e "${RED}Failed to install Kubernetes Dashboard.${NC}"
fi
}
# --- Function to show master token ---
show_token() {
echo -e "${BLUE}Retrieving the join token for worker nodes...${NC}"
if [ -f /var/lib/rancher/k3s/server/node-token ]; then
TOKEN=$(cat /var/lib/rancher/k3s/server/node-token)
IP_ADDR=$(hostname -I | awk '{print $1}')
echo -e "${GREEN}--- Worker Join Information ---${NC}"
echo -e "Run the installer on your worker nodes and choose the 'worker' option."
echo -e "You will need the following information:"
echo -e "Master IP: ${YELLOW}$IP_ADDR${NC}"
echo -e "Join Token: ${YELLOW}$TOKEN${NC}"
echo -e "${GREEN}-----------------------------${NC}"
else
echo -e "${RED}Could not find the node-token file. Is this a master node?${NC}"
fi
}
# --- Function to install k3s worker node ---
install_worker() {
echo -e "${BLUE}Starting k3s worker node installation...${NC}"
# Prompt for master IP and token
read -p "Enter the IP address of the master node: " MASTER_IP
read -p "Enter the join token from the master node: " K3S_TOKEN
if [ -z "$MASTER_IP" ] || [ -z "$K3S_TOKEN" ]; then
echo -e "${RED}Master IP and Token cannot be empty. Aborting.${NC}"
return
fi
echo -e "${YELLOW}Installing worker node and connecting to master at ${MASTER_IP}...${NC}"
# Install k3s agent
curl -sfL https://get.k3s.io | K3S_URL="https://${MASTER_IP}:6443" K3S_TOKEN="${K3S_TOKEN}" sh -
if [ $? -eq 0 ]; then
echo -e "${GREEN}k3s worker node installed and connected successfully!${NC}"
echo -e "${YELLOW}--- Important ---"
echo -e "All 'kubectl' commands should be run from the MASTER node."
echo -e "To verify the new node, go to your master and run: ${BLUE}kubectl get nodes${NC}"
echo -e "${YELLOW}-----------------${NC}"
else
echo -e "${RED}k3s worker node installation failed.${NC}"
echo -e "${YELLOW}Please check the master IP, token, and network connectivity.${NC}"
fi
}
# --- Function to uninstall k3s ---
uninstall_k3s() {
echo -e "${YELLOW}This will completely remove k3s and all related data.${NC}"
read -p "Are you sure you want to continue? (y/n): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Uninstall cancelled."
return
fi
if [ -f /usr/local/bin/k3s-uninstall.sh ]; then
echo -e "${BLUE}Running master node uninstall script...${NC}"
/usr/local/bin/k3s-uninstall.sh
echo -e "${GREEN}k3s master uninstalled.${NC}"
elif [ -f /usr/local/bin/k3s-agent-uninstall.sh ]; then
echo -e "${BLUE}Running agent/worker node uninstall script...${NC}"
/usr/local/bin/k3s-agent-uninstall.sh
echo -e "${GREEN}k3s worker uninstalled.${NC}"
else
echo -e "${RED}Could not find a k3s uninstall script. Has k3s been installed on this node?${NC}"
fi
}
# --- Main Menu ---
main_menu() {
echo -e "\n${BLUE}--- k3s Interactive Installer Menu ---${NC}"
echo "1. Install k3s Master Node"
echo "2. Install k3s Worker Node"
echo "3. Show Master Join Token (run on master)"
echo "4. Show Dashboard Access Info (run on master)"
echo "5. Uninstall k3s (Master or Worker)"
echo "6. Exit"
echo -e "----------------------------------------"
read -p "Enter your choice [1-6]: " choice
case $choice in
1)
install_master
;;
2)
install_worker
;;
3)
show_token
;;
4)
show_dashboard_info
;;
5)
uninstall_k3s
;;
6)
echo "Exiting."
exit 0
;;
*)
echo -e "${RED}Invalid option. Please try again.${NC}"
main_menu
;;
esac
}
# --- Script Start ---
check_root
main_menu
@finnie2006
Copy link
Author

finnie2006 commented Sep 11, 2025

curl -sfL -o k3s-installer.sh https://gist.githubusercontent.com/finnie2006/2dcc50251df3d93cd3e39c9794d1eab9/raw/383255b1fb07b24d8899ce35ed5d2bf650fd8b06/k3s-installer.sh
chmod +x k3s-installer.sh
sudo ./k3s-installer.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment