移除深圳节点及中继拓扑,新增第二台宁波 K3s agent 的全互联 WireGuard 接入和严格 UFW 门禁。\n\nWorker Deployment 与容量控制器仅选择 easyai.io/worker=true 节点,使原宁波混部节点退出 Worker 资源预算,生产基线恢复为宁波专用节点与香港节点各一实例。\n\n已通过 Go 全量测试、go vet、gofmt、迁移安全检查、bash -n、ShellCheck、发布脚本测试和 Kubernetes 清单渲染。
101 lines
2.7 KiB
Bash
Executable File
101 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
cluster_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
|
|
cluster_env_file=${AI_GATEWAY_CLUSTER_ENV_FILE:-"$cluster_root/.env.local"}
|
|
cluster_ssh_key=${AI_GATEWAY_CLUSTER_SSH_KEY:-"$HOME/.ssh/id_ed25519_easyai_gateway_cluster"}
|
|
|
|
load_cluster_env() {
|
|
[[ -f $cluster_env_file && ! -L $cluster_env_file ]] || {
|
|
echo "missing local cluster environment file: $cluster_env_file" >&2
|
|
return 1
|
|
}
|
|
set -a
|
|
# shellcheck source=/dev/null
|
|
source "$cluster_env_file"
|
|
set +a
|
|
cluster_ssh_key=${AI_GATEWAY_CLUSTER_SSH_KEY:-$cluster_ssh_key}
|
|
|
|
: "${AI_GATEWAY_DEPLOY_HOST:?}"
|
|
: "${AI_GATEWAY_DEPLOY_HOST_2:?}"
|
|
: "${AI_GATEWAY_DEPLOY_HOST_3:?}"
|
|
: "${ALI_KEY:?}"
|
|
: "${ALI_SECRET:?}"
|
|
: "${ALI_REGION:?}"
|
|
: "${ALI_BUCKET:?}"
|
|
|
|
CLUSTER_NINGBO_HOST=${AI_GATEWAY_NINGBO_HOST:-$AI_GATEWAY_DEPLOY_HOST}
|
|
CLUSTER_LOS_ANGELES_HOST=${AI_GATEWAY_LOS_ANGELES_HOST:-$AI_GATEWAY_DEPLOY_HOST_2}
|
|
CLUSTER_HONGKONG_HOST=${AI_GATEWAY_HONGKONG_HOST:-$AI_GATEWAY_DEPLOY_HOST_3}
|
|
CLUSTER_NINGBO_WORKER_HOST=${AI_GATEWAY_NINGBO_WORKER_HOST:-}
|
|
export CLUSTER_NINGBO_HOST CLUSTER_LOS_ANGELES_HOST CLUSTER_HONGKONG_HOST CLUSTER_NINGBO_WORKER_HOST
|
|
|
|
for host in "$CLUSTER_NINGBO_HOST" "$CLUSTER_HONGKONG_HOST" "$CLUSTER_LOS_ANGELES_HOST"; do
|
|
[[ $host =~ ^root@[A-Za-z0-9.-]+$ ]] || {
|
|
echo "cluster hosts must use root@host syntax" >&2
|
|
return 1
|
|
}
|
|
done
|
|
if [[ -n $CLUSTER_NINGBO_WORKER_HOST && ! $CLUSTER_NINGBO_WORKER_HOST =~ ^root@[A-Za-z0-9.-]+$ ]]; then
|
|
echo "dedicated Ningbo Worker host must use root@host syntax" >&2
|
|
return 1
|
|
fi
|
|
[[ $ALI_REGION =~ ^[a-z0-9-]+$ && $ALI_BUCKET =~ ^[A-Za-z0-9.-]+$ ]] || {
|
|
echo 'invalid OSS region or bucket' >&2
|
|
return 1
|
|
}
|
|
[[ -f $cluster_ssh_key && ! -L $cluster_ssh_key ]] || {
|
|
echo "missing cluster SSH key: $cluster_ssh_key" >&2
|
|
return 1
|
|
}
|
|
}
|
|
|
|
cluster_ssh() {
|
|
local host=$1
|
|
shift
|
|
ssh \
|
|
-i "$cluster_ssh_key" \
|
|
-o BatchMode=yes \
|
|
-o ConnectTimeout=10 \
|
|
-o ServerAliveInterval=15 \
|
|
-o ServerAliveCountMax=3 \
|
|
"$host" "$@"
|
|
}
|
|
|
|
cluster_scp() {
|
|
scp \
|
|
-i "$cluster_ssh_key" \
|
|
-o BatchMode=yes \
|
|
-o ConnectTimeout=10 \
|
|
"$@"
|
|
}
|
|
|
|
require_commands() {
|
|
local command
|
|
for command in "$@"; do
|
|
command -v "$command" >/dev/null 2>&1 || {
|
|
echo "$command is required" >&2
|
|
return 1
|
|
}
|
|
done
|
|
}
|
|
|
|
assert_private_file() {
|
|
local path=$1
|
|
local mode
|
|
[[ -f $path && ! -L $path ]] || {
|
|
echo "missing private file: $path" >&2
|
|
return 1
|
|
}
|
|
if [[ $(uname -s) == Darwin ]]; then
|
|
mode=$(stat -f '%Lp' "$path")
|
|
else
|
|
mode=$(stat -c '%a' "$path")
|
|
fi
|
|
[[ $mode == 600 ]] || {
|
|
echo "private file must have mode 0600: $path" >&2
|
|
return 1
|
|
}
|
|
}
|