|
|
|
@@ -67,6 +67,7 @@ function plan(target: K3sClusterTarget): Record<string, unknown> {
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wireguard: { ...target.wireguard, endpoint: target.wireguard.endpoint },
|
|
|
|
|
tcpTuning: target.tcpTuning,
|
|
|
|
|
k3s: {
|
|
|
|
|
serverUrl: target.k3s.serverUrl,
|
|
|
|
|
agentTokenFile: target.k3s.agentTokenFile,
|
|
|
|
@@ -433,6 +434,7 @@ spec:
|
|
|
|
|
function workerWireguardApplyScript(target: K3sClusterTarget, secret: SecretMaterial): string {
|
|
|
|
|
const wg = target.wireguard;
|
|
|
|
|
return `set -eu
|
|
|
|
|
${tcpTuningApplyScript(target)}
|
|
|
|
|
if ! command -v wg >/dev/null 2>&1; then
|
|
|
|
|
DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
|
|
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ${shellToken(wg.packageName)}
|
|
|
|
@@ -477,6 +479,7 @@ function controlPlaneApplyScript(target: K3sClusterTarget, secret: SecretMateria
|
|
|
|
|
const wg = target.wireguard;
|
|
|
|
|
return `set -eu
|
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
|
${tcpTuningApplyScript(target)}
|
|
|
|
|
if ! command -v wg >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq ${shQuote(wg.packageName)}; fi
|
|
|
|
|
umask 077
|
|
|
|
|
install -d -m 700 /etc/wireguard /etc/unidesk
|
|
|
|
@@ -513,6 +516,33 @@ wg show ${wg.interfaceName} >/dev/null
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tcpTuningApplyScript(target: K3sClusterTarget): string {
|
|
|
|
|
const tuning = target.tcpTuning;
|
|
|
|
|
const content = [
|
|
|
|
|
`net.core.default_qdisc=${tuning.defaultQdisc}`,
|
|
|
|
|
`net.ipv4.tcp_congestion_control=${tuning.congestionControl}`,
|
|
|
|
|
`net.ipv4.tcp_mtu_probing=${tuning.mtuProbing}`,
|
|
|
|
|
"",
|
|
|
|
|
].join("\n");
|
|
|
|
|
const encoded = Buffer.from(content, "utf8").toString("base64");
|
|
|
|
|
return `modprobe tcp_${tuning.congestionControl} 2>/dev/null || true
|
|
|
|
|
available="$(sysctl -n net.ipv4.tcp_available_congestion_control)"
|
|
|
|
|
case " $available " in
|
|
|
|
|
*" ${tuning.congestionControl} "*) ;;
|
|
|
|
|
*) echo "configured TCP congestion control is unavailable: ${tuning.congestionControl}" >&2; exit 1 ;;
|
|
|
|
|
esac
|
|
|
|
|
sysctl_candidate="$(mktemp)"
|
|
|
|
|
printf %s ${shQuote(encoded)} | base64 -d >"$sysctl_candidate"
|
|
|
|
|
if ! cmp -s "$sysctl_candidate" ${shQuote(tuning.sysctlPath)} 2>/dev/null; then
|
|
|
|
|
install -D -m 0644 "$sysctl_candidate" ${shQuote(tuning.sysctlPath)}
|
|
|
|
|
fi
|
|
|
|
|
rm -f "$sysctl_candidate"
|
|
|
|
|
[ "$(sysctl -n net.core.default_qdisc)" = ${shQuote(tuning.defaultQdisc)} ] || sysctl -q -w net.core.default_qdisc=${shellToken(tuning.defaultQdisc)}
|
|
|
|
|
[ "$(sysctl -n net.ipv4.tcp_congestion_control)" = ${shQuote(tuning.congestionControl)} ] || sysctl -q -w net.ipv4.tcp_congestion_control=${shellToken(tuning.congestionControl)}
|
|
|
|
|
[ "$(sysctl -n net.ipv4.tcp_mtu_probing)" = ${shQuote(String(tuning.mtuProbing))} ] || sysctl -q -w net.ipv4.tcp_mtu_probing=${tuning.mtuProbing}
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function workerApplyScript(target: K3sClusterTarget, secret: SecretMaterial): string {
|
|
|
|
|
const wg = target.wireguard;
|
|
|
|
|
const labels = Object.entries(target.worker.labels).flatMap(([key, value]) => ["--node-label", `${key}=${value}`]);
|
|
|
|
@@ -617,13 +647,15 @@ cp_ready=$(/usr/local/bin/kubectl get node ${shQuote(target.controlPlane.nodeNam
|
|
|
|
|
worker_ready=$(/usr/local/bin/kubectl get node ${shQuote(target.worker.nodeName)} -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || true)
|
|
|
|
|
worker_ip=$(/usr/local/bin/kubectl get node ${shQuote(target.worker.nodeName)} -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null || true)
|
|
|
|
|
handshake=$(wg show ${target.wireguard.interfaceName} latest-handshakes 2>/dev/null | awk '{print $2}' | head -n1)
|
|
|
|
|
python3 - "$wg_active" "$k3s_active" "$cp_ready" "$worker_ready" "$worker_ip" "$handshake" <<'PY'
|
|
|
|
|
tuning="$(sysctl -n net.ipv4.tcp_congestion_control)/$(sysctl -n net.core.default_qdisc)/$(sysctl -n net.ipv4.tcp_mtu_probing)"
|
|
|
|
|
python3 - "$wg_active" "$k3s_active" "$cp_ready" "$worker_ready" "$worker_ip" "$handshake" "$tuning" <<'PY'
|
|
|
|
|
import json, sys, time
|
|
|
|
|
wg, k3s, cp, worker, worker_ip, handshake = sys.argv[1:]
|
|
|
|
|
wg, k3s, cp, worker, worker_ip, handshake, tuning = sys.argv[1:]
|
|
|
|
|
stamp = int(handshake or 0)
|
|
|
|
|
age = None if stamp == 0 else max(0, int(time.time()) - stamp)
|
|
|
|
|
ok = wg == 'true' and k3s == 'true' and cp == 'True' and worker == 'True' and worker_ip == '${address(target.wireguard.workerAddress)}' and age is not None and age < 180
|
|
|
|
|
print(json.dumps({'ok': ok, 'wireguardActive': wg == 'true', 'k3sActive': k3s == 'true', 'controlPlaneReady': cp == 'True', 'workerReady': worker == 'True', 'workerInternalIp': worker_ip, 'handshakeAgeSeconds': age, 'controlPlaneAddress': '${cp}'}, separators=(',', ':')))
|
|
|
|
|
tuning_ready = tuning == '${target.tcpTuning.congestionControl}/${target.tcpTuning.defaultQdisc}/${target.tcpTuning.mtuProbing}'
|
|
|
|
|
ok = wg == 'true' and k3s == 'true' and cp == 'True' and worker == 'True' and worker_ip == '${address(target.wireguard.workerAddress)}' and age is not None and age < 180 and tuning_ready
|
|
|
|
|
print(json.dumps({'ok': ok, 'wireguardActive': wg == 'true', 'k3sActive': k3s == 'true', 'controlPlaneReady': cp == 'True', 'workerReady': worker == 'True', 'workerInternalIp': worker_ip, 'handshakeAgeSeconds': age, 'controlPlaneAddress': '${cp}', 'tcpTuningReady': tuning_ready, 'tcpTuning': tuning}, separators=(',', ':')))
|
|
|
|
|
PY
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
@@ -635,12 +667,14 @@ agent_state="$(systemctl show k3s-agent -p ActiveState --value 2>/dev/null || tr
|
|
|
|
|
agent_pid="$(systemctl show k3s-agent -p MainPID --value 2>/dev/null || true)"
|
|
|
|
|
old_server=false; systemctl is-active --quiet k3s && old_server=true
|
|
|
|
|
ip_present=false; ip -4 address show dev ${target.wireguard.interfaceName} | grep -F ${shQuote(address(target.wireguard.workerAddress))} >/dev/null 2>&1 && ip_present=true
|
|
|
|
|
python3 - "$wg_active" "$agent_state" "$agent_pid" "$old_server" "$ip_present" <<'PY'
|
|
|
|
|
tuning="$(sysctl -n net.ipv4.tcp_congestion_control)/$(sysctl -n net.core.default_qdisc)/$(sysctl -n net.ipv4.tcp_mtu_probing)"
|
|
|
|
|
python3 - "$wg_active" "$agent_state" "$agent_pid" "$old_server" "$ip_present" "$tuning" <<'PY'
|
|
|
|
|
import json, sys
|
|
|
|
|
wg, agent_state, agent_pid, old_server, ip_present = sys.argv[1:]
|
|
|
|
|
wg, agent_state, agent_pid, old_server, ip_present, tuning = sys.argv[1:]
|
|
|
|
|
agent_running = agent_state in ('active', 'activating') and int(agent_pid or 0) > 0
|
|
|
|
|
ok = wg == 'true' and agent_running and old_server == 'false' and ip_present == 'true'
|
|
|
|
|
print(json.dumps({'ok': ok, 'wireguardActive': wg == 'true', 'agentActive': agent_state == 'active', 'agentRunning': agent_running, 'agentState': agent_state, 'agentMainPidPresent': int(agent_pid or 0) > 0, 'standaloneServerActive': old_server == 'true', 'wireguardAddressPresent': ip_present == 'true'}, separators=(',', ':')))
|
|
|
|
|
tuning_ready = tuning == '${target.tcpTuning.congestionControl}/${target.tcpTuning.defaultQdisc}/${target.tcpTuning.mtuProbing}'
|
|
|
|
|
ok = wg == 'true' and agent_running and old_server == 'false' and ip_present == 'true' and tuning_ready
|
|
|
|
|
print(json.dumps({'ok': ok, 'wireguardActive': wg == 'true', 'agentActive': agent_state == 'active', 'agentRunning': agent_running, 'agentState': agent_state, 'agentMainPidPresent': int(agent_pid or 0) > 0, 'standaloneServerActive': old_server == 'true', 'wireguardAddressPresent': ip_present == 'true', 'tcpTuningReady': tuning_ready, 'tcpTuning': tuning}, separators=(',', ':')))
|
|
|
|
|
PY
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|