KubeBYON 后端 Docker Compose 部署

最后更新:2026-05-11

本文档记录一套基于 deployments/single-node/docker-composeKubeBYON 后端远程部署流程

当前推荐模式是:

  • 本地只改代码 / 校验文档
  • 源码同步到远程 Linux 主机
  • 镜像构建与 Compose 启动全部在远程执行

如果你还需要开启 cluster 级 workload admission webhook,请同时参考:

  • docs/runbooks/deploy-cluster-workload-admission-webhook.md
  • docs/runbooks/enable-console-https-on-443.md(如需让控制台 / API 与 HAProxy 共用 443)

1. 适用场景

适用于以下情况:

  • 目标机器是 Linux 主机
  • 后端运行模式为 vcluster
  • PostgreSQL 也希望一起交给 Compose 管理
  • 宿主机上已有可访问的 Kubernetes 集群 kubeconfig,或者这台机本身就要承载 k3s / host cluster
  • 希望用一条 docker compose up -d --build 拉起 KubeBYON 后端

注意:这套 Compose 不会自动创建宿主 Kubernetes 集群本身。 它负责启动:

  • postgres
  • kubebyon-platform-secret-bootstrap
  • kubebyon-api

2. 推荐部署模式

2.1 Fresh Host / 云主机部署

最常见场景:

  • 先准备一台新机器
  • 安装 Docker / Docker Compose
  • 安装 k3s(或使用现成 kubeconfig)
  • 同步源码到远程目录
  • 在远程目录执行 Compose 构建与启动

2.2 已有后端机滚动更新

如果服务器上已经存在 /opt/kubebyon

  • 更新源码
  • 更新 deployments/single-node/docker-compose/.env
  • 按需更新 runtime/ 下的 values / admission 文件
  • 在远程机重新执行:
docker compose --env-file .env up -d --build

2.3 关于 scripts/install/up-backend-compose.sh

scripts/install/up-backend-compose.sh 更适合“当前机器就是目标机”的场景。

因为它会在当前执行机器上先做一次:

docker build ...

如果你的要求是“本地不构建镜像,只允许远程构建”,请不要在本地运行这个脚本,直接在远程服务器执行 Compose 即可。


3. Fresh Host 前置准备

下面示例假设目标机是 Debian 12。

3.1 安装基础工具

apt-get update
apt-get install -y curl ca-certificates git openssl tar

3.2 安装 Docker / Docker Compose

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker

docker compose version

3.3 安装 k3s(如果这台机本身就是宿主集群)

以公网 IP 为 YOUR_PUBLIC_IP 为例:

curl -sfL https://get.k3s.io | \
  INSTALL_K3S_EXEC="server --write-kubeconfig-mode 644 --tls-san YOUR_PUBLIC_IP" sh -

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get nodes -o wide

如果你已经有现成集群,只要保证 KUBEBYON_HOST_KUBECONFIG_PATH 指向的 kubeconfig 在宿主机可用即可。


4. 同步源码到远程服务器

如果远程 /opt/kubebyon 不是 git 仓库,建议直接同步最小构建上下文。

至少需要:

  • cmd/
  • internal/
  • go.mod
  • go.sum
  • deployments/single-node/docker-compose/

示例:

ssh root@YOUR_SERVER 'mkdir -p /opt/kubebyon'

tar czf - cmd internal go.mod go.sum deployments/single-node/docker-compose \
  | ssh root@YOUR_SERVER 'cd /opt/kubebyon && tar xzf -'

如果你还想把部署文档一起同步:

tar czf - \
  docs/runbooks/deploy-kubebyon-backend-docker-compose.md \
  docs/runbooks/deploy-cluster-workload-admission-webhook.md \
  docs/runbooks/enable-console-https-on-443.md \
  | ssh root@YOUR_SERVER 'cd /opt/kubebyon && tar xzf -'

5. 远程准备 Compose 文件

进入远程目录:

cd /opt/kubebyon/deployments/single-node/docker-compose

复制模板:

cp .env.example .env
cp kubebyon-vcluster-values.example.yaml runtime/kubebyon-vcluster-values.yaml

5.1 .env 里至少要改的字段

  • POSTGRES_PASSWORD
  • KUBEBYON_ADMIN_PASSWORD
  • KUBEBYON_HOST_KUBECONFIG_PATH

如果这是正式或公网环境,必须显式打开生产模式:

  • KUBEBYON_ENV=productionKUBEBYON_PRODUCTION=true

否则仍会按开发模式启动,不会执行生产安全拒启动校验。KUBEBYON_ENV=production 会强制进入生产模式,KUBEBYON_PRODUCTION=false 不能覆盖它。

所有环境都会拒绝缺失 KUBEBYON_DATABASE_DSN。生产模式会额外在启动时拒绝以下不安全配置:

  • 默认管理员密码 ChangeMe123!
  • KUBEBYON_CORS_ALLOWED_ORIGINS=*
  • KUBEBYON_SESSION_COOKIE_SECURE=false
  • 启用 admission webhook 时缺失 TLS cert/key 或 shared secret

首次部署完成后,请先用管理员账号登录控制台,在“系统设置”里配置:

  • public_base_url
  • join_base_url
  • GitHub / Google OAuth2(如需)

如果你希望把控制台页面和后端 API 统一收敛到同一个 https://<DOMAIN>:443,同时又保留 HAProxy 对 vCluster 控制面的 443 承接能力,请参考:

  • docs/runbooks/enable-console-https-on-443.md

常见最小示例:

COMPOSE_PROJECT_NAME=kubebyon-backend
KUBEBYON_HTTP_PORT=8080
KUBEBYON_ENV=development
KUBEBYON_PRODUCTION=false
POSTGRES_DB=kubebyon
POSTGRES_USER=kubebyon
POSTGRES_PASSWORD=<CHANGE_ME>
KUBEBYON_POSTGRES_HOST_PORT=5432
KUBEBYON_CORS_ALLOWED_ORIGINS=http://localhost:3000
KUBEBYON_SESSION_COOKIE_SECURE=false
KUBEBYON_JOIN_RATE_LIMIT_WINDOW_SECONDS=3
KUBEBYON_JOIN_RATE_LIMIT_BURST=5
KUBEBYON_JOIN_RATE_LIMIT_MAX_ENTRIES=10000
KUBEBYON_AUTH_RATE_LIMIT_WINDOW_SECONDS=30
KUBEBYON_AUTH_RATE_LIMIT_BURST=5
KUBEBYON_AUTH_RATE_LIMIT_MAX_ENTRIES=5000
# Set to the CIDRs of your trusted reverse proxies before relying on forwarded client IPs in audit logs.
KUBEBYON_TRUSTED_PROXY_CIDRS=127.0.0.1/32,10.0.0.0/8
KUBEBYON_HOST_KUBECONFIG_PATH=/etc/rancher/k3s/k3s.yaml
KUBEBYON_VCLUSTER_CHART_VERSION=0.33.0
KUBEBYON_MANAGED_INGRESS_CHART_NAME=ingress-nginx
KUBEBYON_MANAGED_INGRESS_CHART_REPO=https://kubernetes.github.io/ingress-nginx
KUBEBYON_MANAGED_INGRESS_CHART_VERSION=
KUBEBYON_PLATFORM_API_KEY_SOURCE_NAMESPACE=kubebyon-system
KUBEBYON_PLATFORM_API_KEY_SECRET_NAME=vcluster-platform-api-key
KUBEBYON_PLATFORM_PROJECT=default
KUBEBYON_ADMIN_DISPLAY_NAME=Admin User
KUBEBYON_ADMIN_EMAIL=admin@kubebyon.local
KUBEBYON_ADMIN_PASSWORD=<CHANGE_ME>
KUBEBYON_PLATFORM_API_HOST=
KUBEBYON_PLATFORM_ACCESS_KEY=
KUBEBYON_PLATFORM_MOCK_HOST=https://vcluster.pp.ua:18443
KUBEBYON_PLATFORM_API_INSECURE=true

生产示例至少应改成:

KUBEBYON_ENV=production
KUBEBYON_PRODUCTION=true
KUBEBYON_CORS_ALLOWED_ORIGINS=https://console.example.com
KUBEBYON_SESSION_COOKIE_SECURE=true
KUBEBYON_ADMIN_PASSWORD=<STRONG_UNIQUE_PASSWORD>

KUBEBYON_TRUSTED_PROXY_CIDRS 用逗号分隔可信反向代理网段。后端只会在请求来源 IP 落入这些 CIDR 时采信 X-Forwarded-For / X-Real-IP,因此生产环境应填写负载均衡器、Ingress、HAProxy 或本机代理的真实网段;未部署反向代理时留空,避免客户端伪造审计 IP。

浏览器控制台使用 cookie session 时,KUBEBYON_CORS_ALLOWED_ORIGINS 应显式填写 Console 站点 origin(例如 https://console.example.com,多个值用逗号分隔)。cookie session 通常只支持同站跨 origin(例如 console.example.com -> api.example.com);任意 cross-site 前端仍会被 Sec-Fetch-Site: cross-siteSameSite=Lax cookie 策略阻止,需改用 Bearer/API token 或重新设计 SameSite=None。配置为 * 时后端不会返回 Access-Control-Allow-Credentials,也不会把任意 origin 加入 CSRF 信任列表;这适合纯 Bearer/API 调用,不适合浏览器 cookie 登录。

认证与 join script 请求默认启用 IP 级限流:join script 默认 5 次 burst、每 3 秒恢复 1 次;登录/注册/验证码/重置密码默认 5 次 burst、每 30 秒恢复 1 次。触发后返回 429 并带 Retry-After。如前置反向代理存在,请先正确配置 KUBEBYON_TRUSTED_PROXY_CIDRS,否则限流 key 会退化为代理 IP。

说明:

  • 当前托管业务流量入口内置 controller 只支持 ingress-nginx
  • 因此通常只建议覆盖 KUBEBYON_MANAGED_INGRESS_CHART_VERSION
  • 开关本身在集群创建后通过控制台 / API 按 cluster 维度启用

5.2 runtime/kubebyon-vcluster-values.yaml 至少确认

  • privateNodes.enabled: true
  • controlPlane.service.spec.type: NodePort
  • controlPlane.proxy.extraSANs 包含工作节点访问控制面的公网 IP / 域名

示例:

privateNodes:
  enabled: true
controlPlane:
  distro:
    k8s:
      enabled: true
      image:
        tag: v1.31.2
  coredns:
    embedded: false
  service:
    spec:
      type: NodePort
  proxy:
    extraSANs:
      - "YOUR_PUBLIC_IP"
  statefulSet:
    resources:
      requests:
        cpu: 100m
        memory: 256Mi
        ephemeral-storage: 1Gi
networking:
  podCIDR: 10.64.0.0/16
  serviceCIDR: 10.128.0.0/16

如需了解托管业务流量入口当前实现边界与后续规划,请同时阅读:

  • docs/architecture/managed-workload-ingress-plan.md

6. 如需启用 admission webhook

推荐直接使用目录内脚本生成:

./gen-admission-assets.sh YOUR_PUBLIC_IP 9443 ./runtime/admission
cat runtime/admission/admission.env >> .env

然后检查 .env 中是否已经出现:

  • KUBEBYON_ADMISSION_ADDR=:9443
  • KUBEBYON_ADMISSION_BASE_URL=https://YOUR_PUBLIC_IP:9443
  • KUBEBYON_ADMISSION_TLS_CERT_FILE=/etc/kubebyon/runtime/admission/tls.crt
  • KUBEBYON_ADMISSION_TLS_KEY_FILE=/etc/kubebyon/runtime/admission/tls.key
  • KUBEBYON_ADMISSION_SHARED_SECRET=<RANDOM_HEX>

7. 在远程服务器构建并启动

必须在远程机器执行。

cd /opt/kubebyon/deployments/single-node/docker-compose
docker compose --env-file .env up -d --build

常用检查:

docker compose --env-file .env ps
docker compose --env-file .env logs --tail=120 kubebyon-platform-secret-bootstrap kubebyon-api

预期:

  • postgreshealthy
  • kubebyon-platform-secret-bootstrap 正常退出
  • kubebyon-api 正常启动
  • 如果 admission 已开启,日志会出现:
    • starting kubebyon admission api
    • starting kubebyon api

8. 基础健康检查

8.1 API

curl -fsS http://YOUR_PUBLIC_IP:8080/healthz

预期:

{"status":"ok"}

8.2 admission 端口

如果已开启 admission:

curl -kI https://YOUR_PUBLIC_IP:9443/

预期通常返回 404,重点是不能连接失败

8.3 bootstrap 是否写入了平台 Secret

kubectl get secret -n kubebyon-system vcluster-platform-api-key \
  -o go-template='{{index .data "host" | base64decode}}{{"\n"}}{{index .data "project" | base64decode}}{{"\n"}}'

如果你配置的是 mock host,输出应该是对应的 mock 地址和 project。


9. 创建测试集群并验证节点加入

9.1 登录后台

curl -fsS -c cookie.txt \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@kubebyon.local","password":"<ADMIN_PASSWORD>"}' \
  http://YOUR_PUBLIC_IP:8080/api/auth/login

9.2 创建集群

curl -fsS -b cookie.txt \
  -H 'Content-Type: application/json' \
  -d '{
    "name":"test-compose",
    "control_plane_host":"YOUR_PUBLIC_IP",
    "workload_cpu_limit_milli_cores":1000,
    "workload_memory_limit_mib":512,
    "control_plane_cpu_request_milli_cores":100,
    "control_plane_memory_request_mib":512
  }' \
  http://YOUR_PUBLIC_IP:8080/api/console/clusters

9.3 关于首次创建时的短暂错误态

新集群创建后,控制台有时会短暂出现:

  • status = provisioning
  • connection_status = error
  • last_error_message = secrets "vc-<name>" not found

这是因为 vCluster 的 kubeconfig Secret 还没完全生成。 通常等 vc-<name> Secret 创建完成后,状态会自动变成:

  • status = ready
  • connection_status = reachable

9.4 创建 join token

curl -fsS -b cookie.txt \
  -H 'Content-Type: application/json' \
  -d '{}' \
  http://YOUR_PUBLIC_IP:8080/api/console/clusters/CLUSTER_ID/join-token

返回里会带:

  • token.value
  • token.join_command

9.5 在工作节点执行 join

curl -fsSLk "http://YOUR_PUBLIC_IP:8080/api/join/clusters/CLUSTER_ID/script?token=TOKEN" | sh -

9.6 验证结果

curl -fsS -b cookie.txt http://YOUR_PUBLIC_IP:8080/api/console/clusters/CLUSTER_ID
curl -fsS -b cookie.txt http://YOUR_PUBLIC_IP:8080/api/console/nodes

预期:

  • cluster status = ready
  • connection_status = reachable
  • nodes_count >= 1
  • ready_nodes_count >= 1

10. Console kubectl 代理兼容性说明

POST /api/console/clusters/{clusterID}/kubectl 默认只读,用于控制台安全查询集群状态。

后端会拒绝写操作、交互、隧道、文件输入、原始 API 代理、身份冒充和连接覆盖参数,包括:

  • applydeletepatchexecport-forwardcpdraincordonwait
  • --raw--as--as-group--server--token--kubeconfig-f/-k
  • watch / follow 等持续输出。

这是安全收紧,可能影响旧自动化脚本或运维习惯。Compose 部署完成后,如需执行写操作,请使用专用 API 或在授权环境中直接使用 kubeconfig。


11. 停止与清理

停止服务:

docker compose --env-file .env down

连 PostgreSQL 数据卷一起清理:

docker compose --env-file .env down -v

如果你还创建了测试 vCluster,记得额外从 KubeBYON 控制台或 API 删除测试 cluster。