Files
kubernetes/k3sup-script.sh
2026-07-20 10:51:03 +02:00

155 lines
5.2 KiB
Bash
Executable File

#!/bin/bash
rm ~/.kube/config # comment this out if you have more than one cluster
# ____________________ EDIT VARIABLES __________________________
export NODES=(
"sandy" # "192.168.1.14"
"gary" # "192.168.1.13"
"sheldon" # "192.168.1.16"
"pearl" # "192.168.1.19"
) # In this script you can replace --host and --server-host with --ip and --server-ip if you don't have DNS names
export USER="pleb"
export SSH_KEY="/home/pleb/.ssh/bikiniBottom"
export CLUSTER_NAME="bikinibottom"
export K3SVer="0.13.11"
export VIPIP="192.168.1.21" # Virtual IP address that the master nodes will share
export VIPHostname="bikinibotton"
export NETWORKSuffix="lan"
export EXTRAArgs="--disable traefik --disable servicelb"
export MetalLB_IPRange="192.168.1.21" # Range for MetalLB to use
# _______________________ END OF VARIABLES ______________________
GREEN='\033[32m'
RED='\033[0;31m'
ENDCOLOR='\033[0m'
for index in "${!NODES[@]}"; do
echo -e "${GREEN}------- Installing on ${NODES[$index]} -------${ENDCOLOR}"
# The first server starts the cluster
if [[ $index -eq 0 ]]; then
k3sup install \
--cluster \
--user $USER \
--host ${NODES[$index]} \
--ssh-key $SSH_KEY \
--k3s-version $K3SVer \
--local-path $HOME/.kube/config \
--context $CLUSTER_NAME \
--merge \
--tls-san $VIPIP --tls-san $VIPHostname --tls-san $VIPHostname.$NETWORKSuffix \
--k3s-extra-args "${EXTRAArgs}"
elif [[ $index -eq 1 || $index -eq 2 ]]; then
# The second and third nodes join as master nodes
k3sup join \
--server \
--host ${NODES[$index]} \
--user $USER \
--server-user $USER \
--server-host ${NODES[0]} \
--ssh-key $SSH_KEY \
--k3s-version $K3SVer \
--k3s-extra-args "${EXTRAArgs}"
else
# The rest of the nodes join as worker nodes
k3sup join \
--host ${NODES[$index]} \
--server-user $USER \
--server-host ${NODES[0]} \
--user $USER \
--ssh-key $SSH_KEY \
--k3s-version $K3SVer
fi
done
echo -e "${GREEN}------- k3s installed, moving to backend apps -------${ENDCOLOR}"
# MetalLB Installation
echo -e "${GREEN}------- Installing MetalLB Load Balancer -------${ENDCOLOR}"
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/metallb.yaml
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- $MetalLB_IPRange
EOF
# Traefik Installation
echo -e "${GREEN}------- Installing Traefik Ingress Controller -------${ENDCOLOR}"
helm repo add traefik https://traefik.github.io/charts
helm repo update
# create values.yaml for traefik. Need this to be "local" so that X-Forwarded-For headers are transmitted
echo "\
additionalArguments:
- '--serversTransport.insecureSkipVerify=true'
service:
spec:
externalTrafficPolicy: Local
" > /tmp/traefik-values.yaml
helm upgrade --install traefik traefik/traefik --create-namespace --namespace traefik --values /tmp/traefik-values.yaml
cat <<EOF | kubectl apply -f -
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: dashboard
namespace: traefik
spec:
entryPoints:
- web
routes:
- match: Host('traefik.localhost') && (PathPrefix('/dashboard') || PathPrefix('/api'))
kind: Rule
services:
- name: api@internal
kind: TraefikService
EOF
# Cert-Manager Installation
echo -e "${GREEN}------- Installing Cert Manager -------${ENDCOLOR}"
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
# Test out external IP address assignment with MetalLB
sleep 10
echo -e "${GREEN}------- Testing out MetalLB Load Balancer -------${ENDCOLOR}"
kubens default
kubectl create deploy nginx --image=nginx
sleep 5
kubectl expose deploy nginx --port=80 --target-port=80 --type=LoadBalancer
sleep 20
external_ip=$(kubectl get service nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
if [[ -n "$external_ip" ]]; then
echo -e "External IP: $external_ip"
if command -v open &> /dev/null; then
open "http://${external_ip}:80"
elif command -v xdg-open &> /dev/null; then
xdg-open "http://${external_ip}:80"
elif command -v google-chrome &> /dev/null; then
google-chrome "http://${external_ip}:80"
else
echo -e "${RED}Failed to open web browser. Please manually open a web browser and navigate to http://${external_ip}:80.${ENDCOLOR}"
fi
else
echo -e "${RED}LoadBalancer is still pending, may not be functional yet${ENDCOLOR}"
fi
# Print Traefik External IP
echo -e "${GREEN}------- Print Traefik Ingress Point -------${ENDCOLOR}"
kubectl get svc -n traefik
external_ip=$(kubectl get service traefik -n traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo -e "\nOn your router, ${GREEN}Port forward${ENDCOLOR} ports 80 and 443 to ${GREEN}$external_ip${ENDCOLOR}"
echo -e "\n${GREEN}------- Setup Complete -------${ENDCOLOR}\n"