177 lines
4.8 KiB
Bash
177 lines
4.8 KiB
Bash
#!/bin/bash
|
|
set -e
|
|
|
|
# Script to create and configure a Proxmox LXC container with k3s, kubectl, Helm, NGINX Ingress, and MetalLB
|
|
|
|
# Variables
|
|
CTID=117
|
|
HOSTNAME="k3s-master"
|
|
CORES=4
|
|
MEMORY=8192
|
|
SWAP=512
|
|
DISK_SIZE=20
|
|
BRIDGE="vmbr0"
|
|
IP="dhcp" # Change to static IP like "192.168.1.100/24" if needed
|
|
GATEWAY=""
|
|
TEMPLATE="/var/lib/vz/template/cache/debian-12-standard_12.7-1_amd64.tar.zst"
|
|
K3S_VERSION="v1.30.1+k3s1"
|
|
KUBECTL_VERSION="v1.30.0"
|
|
|
|
# Verify template
|
|
if [ ! -f "$TEMPLATE" ]; then
|
|
echo "Error: Template $TEMPLATE not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Check kernel modules
|
|
echo "Checking kernel modules on host..."
|
|
for module in br_netfilter overlay; do
|
|
if ! lsmod | grep -q "$module"; then
|
|
modprobe "$module" || {
|
|
echo "Error: Kernel module $module missing!"
|
|
exit 1
|
|
}
|
|
fi
|
|
done
|
|
echo -e "br_netfilter\noverlay" > /etc/modules-load.d/k3s.conf
|
|
|
|
# Enable IP forwarding
|
|
sysctl -w net.ipv4.ip_forward=1
|
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
|
sed -i '/net.ipv4.ip_forward/s/^#//g' /etc/sysctl.conf
|
|
sed -i '/net.ipv6.conf.all.forwarding/s/^#//g' /etc/sysctl.conf
|
|
|
|
# Create LXC container
|
|
pct create $CTID $TEMPLATE \
|
|
--ostype debian \
|
|
--hostname $HOSTNAME \
|
|
--cores $CORES \
|
|
--memory $MEMORY \
|
|
--swap $SWAP \
|
|
--rootfs local-lvm:$DISK_SIZE \
|
|
--net0 name=eth0,bridge=$BRIDGE,ip=$IP \
|
|
--features nesting=1,keyctl=1 \
|
|
--unprivileged 0
|
|
|
|
# Modify LXC config
|
|
cat <<EOF >> /etc/pve/lxc/$CTID.conf
|
|
lxc.apparmor.profile: unconfined
|
|
lxc.cap.drop:
|
|
lxc.mount.auto: proc:rw sys:rw
|
|
lxc.cgroup2.devices.allow: c 10:200 rwm
|
|
EOF
|
|
|
|
# Start container
|
|
pct start $CTID
|
|
|
|
# Setup inside the container
|
|
pct exec $CTID -- bash -c "
|
|
set -e
|
|
|
|
# Install dependencies
|
|
apt-get update && apt-get install -y curl ca-certificates bash-completion iptables iproute2 gnupg2
|
|
|
|
# Install the English UTF-8 locale
|
|
apt-get update
|
|
apt-get install -y locales
|
|
|
|
# Generate the locale
|
|
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
|
|
locale-gen
|
|
|
|
# Set environment variables for locale
|
|
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
|
|
|
# Export for current shell (needed for script to work immediately)
|
|
export LANG=en_US.UTF-8
|
|
export LANGUAGE=en_US:en
|
|
export LC_ALL=en_US.UTF-8
|
|
|
|
# Create /dev/kmsg link for k3s
|
|
ln -sf /dev/console /dev/kmsg
|
|
echo -e '#!/bin/sh -e\nln -sf /dev/console /dev/kmsg\nmount --make-rshared /' > /etc/rc.local
|
|
chmod +x /etc/rc.local
|
|
|
|
# Install k3s
|
|
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=$K3S_VERSION sh -s - \
|
|
--disable=traefik \
|
|
--disable=servicelb \
|
|
--write-kubeconfig-mode 644 \
|
|
--node-name $HOSTNAME
|
|
|
|
# Setup kubectl
|
|
mkdir -p /root/.kube
|
|
cp /etc/rancher/k3s/k3s.yaml /root/.kube/config
|
|
chmod 600 /root/.kube/config
|
|
export KUBECONFIG=/root/.kube/config
|
|
|
|
# Install kubectl binary
|
|
cd /usr/local/bin
|
|
ARCH=amd64
|
|
OS=linux
|
|
curl -LO https://dl.k8s.io/release/$KUBECTL_VERSION/bin/\$OS/\$ARCH/kubectl
|
|
curl -LO https://dl.k8s.io/release/$KUBECTL_VERSION/bin/\$OS/\$ARCH/kubectl.sha256
|
|
echo \"\$(cat kubectl.sha256) kubectl\" | sha256sum --check || exit 1
|
|
chmod +x kubectl
|
|
rm kubectl.sha256
|
|
|
|
# Fix PATH
|
|
echo 'export PATH=\$PATH:/usr/local/bin' >> /root/.bashrc
|
|
echo 'export KUBECONFIG=/root/.kube/config' >> /root/.bashrc
|
|
echo 'alias k=kubectl' >> /root/.bashrc
|
|
echo 'source <(kubectl completion bash)' >> /root/.bashrc
|
|
echo 'complete -o default -F __start_kubectl k' >> /root/.bashrc
|
|
|
|
# Install git for Helm plugins
|
|
apt-get install -y git
|
|
|
|
# Fixed Helm installation: manual download and extraction
|
|
echo "Installing Helm manually..."
|
|
HELM_VERSION="v3.18.0"
|
|
curl -LO "https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
|
tar -zxvf "helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
|
mv linux-amd64/helm /usr/local/bin/helm
|
|
chmod +x /usr/local/bin/helm
|
|
rm -rf linux-amd64 "helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
|
|
|
# Verify Helm installation
|
|
helm version
|
|
|
|
# Add Ingress-NGINX via Helm
|
|
kubectl create namespace ingress-nginx
|
|
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
|
|
helm repo update
|
|
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx
|
|
|
|
# Install MetalLB
|
|
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml
|
|
kubectl wait --namespace metallb-system --for=condition=ready pod --selector=app=controller --timeout=120s
|
|
|
|
# Configure MetalLB IP address pool (change CIDR to your local subnet range)
|
|
cat <<EOF2 | kubectl apply -f -
|
|
apiVersion: metallb.io/v1beta1
|
|
kind: IPAddressPool
|
|
metadata:
|
|
name: clinic-pool
|
|
namespace: metallb-system
|
|
spec:
|
|
addresses:
|
|
- 192.168.100.240-192.168.100.250
|
|
---
|
|
apiVersion: metallb.io/v1beta1
|
|
kind: L2Advertisement
|
|
metadata:
|
|
name: clinic-adv
|
|
namespace: metallb-system
|
|
EOF2
|
|
|
|
"
|
|
|
|
# Wait and test cluster
|
|
echo "Waiting for k3s to stabilize..."
|
|
sleep 60
|
|
pct exec $CTID -- kubectl get nodes
|
|
|
|
echo " k3s + kubectl + Helm + Ingress + MetalLB setup complete!"
|
|
echo " Access KUBECONFIG inside container: /root/.kube/config"
|