fix(bootstrap): 在源码构建后安装分布式节点防火墙

首次源码安装或旧发布版升级时,等待新二进制构建完成后调用 node firewall;worker 的源码安装也按所请求的版本重新构建。补充安装顺序回归检查和 main 接入说明,更新单机默认与多节点运维边界。

验证:Linux VM 上 bootstrap shell 测试全量通过;go test ./cmd/felis;shell 语法和 git diff --check。
This commit is contained in:
Lemon-miaow committed 2026-10-01 19:57:17 +08:00
1 parent adf563ffe3
commit b01aae77a2
4 files changed
+28 -13

No files matched your search

+7 -5
View File
@@ -6082,7 +6082,7 @@ main_worker() {
# Reuse the release binary path for the local admission checks, without importing game/platform images. # Reuse the release binary path for the local admission checks, without importing game/platform images.
bootstrap_from_tui || [ -n "$FELIS_ARTIFACT_DIR" ] || [ -n "${FELIS_SKIP_FETCH:-}" ] || resolve_install_ref bootstrap_from_tui || [ -n "$FELIS_ARTIFACT_DIR" ] || [ -n "${FELIS_SKIP_FETCH:-}" ] || resolve_install_ref
acquire_felis_binary acquire_felis_binary
if [ ! -x "$HOST_BIN" ]; then install_go_toolchain; build_nano_binary; fi if [ -z "$HAVE_PREBUILT_BINARY" ]; then install_go_toolchain; build_nano_binary; fi
mkdir -p /etc/rancher/k3s/config.yaml.d mkdir -p /etc/rancher/k3s/config.yaml.d
(umask 077; printf '%s\n' "$token" > /etc/rancher/k3s/felis-bootstrap-token) (umask 077; printf '%s\n' "$token" > /etc/rancher/k3s/felis-bootstrap-token)
unset token unset token
@@ -6160,10 +6160,6 @@ main() {
# before any re-run's rollouts). # before any re-run's rollouts).
configure_registry_mirror configure_registry_mirror
acquire_felis_binary acquire_felis_binary
if [ "${DISTRIBUTED:-0}" = 1 ]; then
[ -n "$WORKER_PEERS" ] || WORKER_PEERS="${NODE_EXTERNAL_IP:-$NODE_IP}/32"
"$HOST_BIN" node firewall --controller --controller-ip "${NODE_EXTERNAL_IP:-$NODE_IP}" --peers "$WORKER_PEERS" --pod-cidr "$POD_CIDR" --node-port "$FELIS_PANEL_NODEPORT" --control-namespace "$CONTROL_NS" --namespace "$MINECRAFT_NS"
fi
select_release_artifacts select_release_artifacts
resolve_felis_image resolve_felis_image
# The registry's and the database's own images must be in containerd before their # The registry's and the database's own images must be in containerd before their
@@ -6171,6 +6167,12 @@ main() {
import_release_images felis registry postgres import_release_images felis registry postgres
import_platform_images import_platform_images
build_image build_image
# Source builds install the new HOST_BIN here; an earlier call may execute the
# old release's binary, which has no distributed node commands.
if [ "${DISTRIBUTED:-0}" = 1 ]; then
[ -n "$WORKER_PEERS" ] || WORKER_PEERS="${NODE_EXTERNAL_IP:-$NODE_IP}/32"
"$HOST_BIN" node firewall --controller --controller-ip "${NODE_EXTERNAL_IP:-$NODE_IP}" --peers "$WORKER_PEERS" --pod-cidr "$POD_CIDR" --node-port "$FELIS_PANEL_NODEPORT" --control-namespace "$CONTROL_NS" --namespace "$MINECRAFT_NS"
fi
# After build_image imported the felis image: the registry pod's gate runs it. # After build_image imported the felis image: the registry pod's gate runs it.
pin_platform_images pin_platform_images
# Before build_game_stack: the builds user servers run must be read off the # Before build_game_stack: the builds user servers run must be read off the
+6
View File
@@ -4911,9 +4911,15 @@ esac
rm -rf "$credir" "$credcalls" rm -rf "$credir" "$credcalls"
# Worker admission reuses the installer but must never enter host control-plane setup. # Worker admission reuses the installer but must never enter host control-plane setup.
before "distributed host firewall runs the newly built binary" \
' build_image' '"$HOST_BIN" node firewall --controller' "$(bsfn main)"
before "distributed host firewall is installed before platform deployment" \
'"$HOST_BIN" node firewall --controller' ' deploy_postgres' "$(bsfn main)"
expect "distributed admission preserves existing API-server arguments" \ expect "distributed admission preserves existing API-server arguments" \
"echo 'kube-apiserver-arg+:'" "$(bsfn write_k3s_config)" "echo 'kube-apiserver-arg+:'" "$(bsfn write_k3s_config)"
worker="$(bsfn main_worker)" worker="$(bsfn main_worker)"
expect "source worker install builds the requested binary even when an older binary exists" \
'if [ -z "$HAVE_PREBUILT_BINARY" ]; then install_go_toolchain; build_nano_binary; fi' "$worker"
before "worker identity is checked before the agent config is written" \ before "worker identity is checked before the agent config is written" \
'refusing to rename it' 'cat > "$K3S_CONFIG_DROPIN"' "$worker" 'refusing to rename it' 'cat > "$K3S_CONFIG_DROPIN"' "$worker"
expect "worker rejects server tokens and verifies the CA-pinned bootstrap shape" \ expect "worker rejects server tokens and verifies the CA-pinned bootstrap shape" \
+8
View File
@@ -25,6 +25,14 @@ done
用包含此功能的 Felis 安装器在 A 重跑安装:`FELIS_DISTRIBUTED=1`、`FELIS_NODE_EXTERNAL_IP=<A 固定公网 IP>`、`FELIS_PEER_CIDRS="$PEERS"`,保留现有安装参数。该步骤会启用 `wireguard-native`、`flannel-external-ip`、NodeRestriction 和独立 agent token,并安装归档服务、最小 RBAC 和宿主机隔离规则。WireGuard 更换需要停服维护窗口。已有 worker 的对等地址列表也必须提前更新。 用包含此功能的 Felis 安装器在 A 重跑安装:`FELIS_DISTRIBUTED=1`、`FELIS_NODE_EXTERNAL_IP=<A 固定公网 IP>`、`FELIS_PEER_CIDRS="$PEERS"`,保留现有安装参数。该步骤会启用 `wireguard-native`、`flannel-external-ip`、NodeRestriction 和独立 agent token,并安装归档服务、最小 RBAC 和宿主机隔离规则。WireGuard 更换需要停服维护窗口。已有 worker 的对等地址列表也必须提前更新。
仅推送 main 不会自动发布 release。还未使用包含这些变更的发布资产时,在新版源码目录中以 root 执行下面的命令,显式从 main 构建;其他原安装参数继续保留。只更新安装脚本、仍使用默认 release 通道,可能下载到不支持分布式命令的旧二进制。
```bash
FELIS_REF=main FELIS_DISTRIBUTED=1 \
FELIS_NODE_EXTERNAL_IP=<A固定公网IP> \
FELIS_PEER_CIDRS="$PEERS" bash deploy/bootstrap.sh
```
直接生成部署清单时,增加: 直接生成部署清单时,增加:
```bash ```bash
+7 -8
View File
@@ -97,14 +97,13 @@ The installer also makes the system journal persistent (capped at
`FELIS_JOURNAL_MAX_USE`, default 1G; `FELIS_MANAGE_JOURNAL=0` skips it) and writes the `FELIS_JOURNAL_MAX_USE`, default 1G; `FELIS_MANAGE_JOURNAL=0` skips it) and writes the
admin kubeconfig `/etc/rancher/k3s/k3s.yaml` root-only: run `sudo k3s kubectl`. admin kubeconfig `/etc/rancher/k3s/k3s.yaml` root-only: run `sudo k3s kubectl`.
One node is the whole supported shape. A world volume is a ReadWriteOnce claim on the Single-node deployment remains the default. The opt-in [distributed mode](distributed.md)
node's local-path storage, so a game server's pod is pinned to the node that first keeps the sole API and operator on A and runs games on approved k3s agents. A world is
scheduled it and cannot move when that node fails; the operator and felis-api each run a ReadWriteOnce claim on its node's local-path storage; moving it requires an explicit
as a single replica without leader election, so an upgrade or a node restart pauses stopped migration through A's archive service. There is no automatic failover or
wakes and stops until their pod is back. Joining k3s agents to the cluster is untested standby controller. An A restart pauses control operations until its workloads return;
and gains no failover. A multi-node shape would need, at least, storage that can follow a a lost worker leaves its worlds on that node. Cross-node networking still requires the
pod to another node and leader election in felis-operator (controller-runtime's three-machine acceptance described in the distributed runbook.
`LeaderElection`) so a second replica can stand by.
### Where the binary and the images come from ### Where the binary and the images come from