provisioning-catalog/components/k0s/taskserv/install-k0s.sh

126 lines
4.5 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
set -euo pipefail
[ -r "./env-k0s" ] && . ./env-k0s
K0S_VERSION="${K0S_VERSION:-1.35.3+k0s.0}"
K0S_ROLE="${K0S_ROLE:-controller+worker}"
K0S_DATA_DIR="${K0S_DATA_DIR:-/var/lib/k0s}"
K0S_DISABLE_IPV6="${K0S_DISABLE_IPV6:-true}"
K0S_CLUSTER_NAME="${K0S_CLUSTER_NAME:-k0s}"
K0S_DISABLE_KUBE_PROXY="${K0S_DISABLE_KUBE_PROXY:-true}"
K0S_STORAGE_BACKEND="${K0S_STORAGE_BACKEND:-dqlite}"
K0S_KINE_DIR="${K0S_KINE_DIR:-}"
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/' -e 's/armv7l/arm/')"
K0S_TAG="v${K0S_VERSION}"
K0S_BINARY_URL="https://github.com/k0sproject/k0s/releases/download/${K0S_TAG}/k0s-${K0S_TAG}-${ARCH}"
CMD_TASK="${1:-install}"
echo "=== k0s: checking prerequisites (cmd=${CMD_TASK}) ==="
if [ "${CMD_TASK}" = "reinstall" ]; then
echo "=== k0s: reinstall — stopping and resetting cluster ==="
systemctl stop k0scontroller 2>/dev/null || true
k0s reset --data-dir "${K0S_DATA_DIR}" 2>/dev/null || true
systemctl daemon-reload
echo "=== k0s: cluster reset complete, proceeding with fresh install ==="
elif k0s version 2>/dev/null | grep -q "${K0S_VERSION}"; then
if systemctl is-active --quiet k0scontroller 2>/dev/null; then
echo "=== k0s: v${K0S_VERSION} already running — skipping install ==="
exit 0
fi
# Service stopped but binary present: run reset to clean partial state before reinstall
echo "=== k0s: binary present but service stopped — cleaning state ==="
systemctl stop k0scontroller 2>/dev/null || true
k0s reset --data-dir "${K0S_DATA_DIR}" 2>/dev/null || true
systemctl daemon-reload
fi
echo "=== k0s: installing v${K0S_VERSION} (${ARCH}, role=${K0S_ROLE}) ==="
# Disable IPv6 before k0s starts — avoids dual-stack complexity
if [ "${K0S_DISABLE_IPV6}" = "true" ]; then
echo "=== k0s: disabling IPv6 ==="
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
sysctl -w net.ipv6.conf.lo.disable_ipv6=1
if ! grep -q "net.ipv6.conf.all.disable_ipv6" /etc/sysctl.d/99-k0s.conf 2>/dev/null; then
cat > /etc/sysctl.d/99-k0s.conf <<'EOF'
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
EOF
fi
fi
# Download and install k0s binary
curl -sSfL "${K0S_BINARY_URL}" -o /usr/local/bin/k0s
chmod 0755 /usr/local/bin/k0s
echo "=== k0s: version $(k0s version) installed ==="
KINE_DIR="${K0S_KINE_DIR:-${K0S_DATA_DIR}/kine}"
mkdir -p /etc/k0s "${K0S_DATA_DIR}" "${KINE_DIR}"
if [ -f ./templates/k0s.yaml ]; then
cp ./templates/k0s.yaml /etc/k0s/k0s.yaml
echo "=== k0s: config deployed from bundle ==="
elif [ ! -f /etc/k0s/k0s.yaml ]; then
echo "ERROR: /etc/k0s/k0s.yaml not found and templates/k0s.yaml not in bundle" >&2
exit 1
fi
echo "=== k0s: config at /etc/k0s/k0s.yaml (storage=${K0S_STORAGE_BACKEND}, kubeProxy.disabled=${K0S_DISABLE_KUBE_PROXY}) ==="
# Install as systemd service
echo "=== k0s: installing systemd service (role=${K0S_ROLE}) ==="
k0s install controller \
--enable-worker \
--config /etc/k0s/k0s.yaml \
--data-dir "${K0S_DATA_DIR}"
echo "=== k0s: starting service ==="
k0s start
echo "=== k0s: waiting for API server ==="
RETRIES=30
for i in $(seq 1 ${RETRIES}); do
if k0s kubectl get nodes --no-headers 2>/dev/null | grep -q "Ready"; then
echo "=== k0s: node Ready ==="
break
fi
if [ "${i}" -eq "${RETRIES}" ]; then
echo "ERROR: k0s node did not reach Ready after ${RETRIES} attempts" >&2
exit 1
fi
sleep 10
done
# Single-node (controller+worker): remove control-plane taint so workloads can schedule
if [ "${K0S_ROLE}" = "controller_worker" ] || [ "${K0S_ROLE}" = "controller+worker" ]; then
NODE_NAME="$(k0s kubectl get nodes --no-headers -o custom-columns=':metadata.name' | head -1)"
if [ -n "${NODE_NAME}" ]; then
k0s kubectl taint nodes "${NODE_NAME}" node-role.kubernetes.io/control-plane:NoSchedule- 2>/dev/null || true
echo "=== k0s: removed control-plane taint from ${NODE_NAME} ==="
fi
fi
# Symlink kubelet paths for CSI drivers that expect /var/lib/kubelet/
if [ "${K0S_DATA_DIR}" != "/var/lib/k0s" ]; then
mkdir -p /var/lib/kubelet
for subdir in plugins_registry plugins pods; do
[ -d "${K0S_DATA_DIR}/kubelet/${subdir}" ] && \
ln -sfn "${K0S_DATA_DIR}/kubelet/${subdir}" "/var/lib/kubelet/${subdir}" 2>/dev/null || true
done
echo "=== k0s: kubelet symlinks created for CSI compatibility ==="
fi
# Export kubeconfig to standard location
mkdir -p /root/.kube
k0s kubeconfig admin > /root/.kube/config
chmod 600 /root/.kube/config
echo "=== k0s: ready (version=v${K0S_VERSION}, cluster=${K0S_CLUSTER_NAME}, data_dir=${K0S_DATA_DIR}) ==="