Files
pikasTech-HWLAB/docs/reference/g14-gitops-cicd.md
T

13 KiB
Raw Blame History

G14 GitOps CI/CD

G14 是 HWLAB 当前 DEV/PROD 原生 k8s 与 GitOps 运行面目标。G14 CI/CD 必须只作用于 G14 k3s,不接管 D601 legacy 运行面,不使用 UniDesk Code Queue 作为调度器,也不把 UniDesk backend、provider-gateway 或 microservice proxy 当作 HWLAB runtime。

目标模型

  • Source of truth:业务版本以 Git source commit 为唯一身份;镜像 tag、OCI labels、runtime annotation 和 Argo CD desired state 都必须记录同一个 source commit。
  • CITekton 在 G14 k3s 内运行 hwlab-g14-ci-image-publish Pipeline,读取 CI.json 命令,按 source commit 构建镜像并推送到 G14 registry。
  • Artifact:镜像使用 commit tag,例如 127.0.0.1:5000/hwlab/hwlab-cloud-api:<shortCommit>digest 由 registry 返回,CI report 只作为审计证据,不作为 CD 真相。
  • Branch splitG14 是源码监控分支;G14-gitops 是 Tekton promotion 写入的生成分支,保存 deploy/gitops/g14/** desired state。
  • CDArgo CD 只消费 G14-gitops:deploy/gitops/g14/runtime-devdeploy/gitops/g14/runtime-prod 的 Git desired state,不重新构建镜像,不读取 D601 状态,不获取 legacy DEV CD Lease。
  • FRPG14 DEV 通过 hwlab-dev/hwlab-g14-frpc 暴露 17666/17667G14 PROD 通过 hwlab-prod/hwlab-g14-prod-frpc 暴露 18666/18667master frps 的 deploy/frp/frps.dev.toml 与实际 /etc/frp/frps.toml 必须同时放行这四个 G14 端口。
  • 并行性:不同 source commit 的 CI build 不共享发布锁;并行安全由 immutable commit tag/digest 和 Git desired state 保证。最终运行版本由 Argo CD 当前同步的 Git revision 决定。

生成入口

scripts/g14-gitops-render.mjs 是 G14 专用转换器:

  • 读取 CI.json,生成 Tekton Pipeline 和 PipelineRun 样板。
  • 读取 deploy/deploy.jsondeploy/k8s/*,生成 Argo CD 可消费的 G14 runtime Kustomize path。
  • G14 Tekton 的镜像构建发布入口必须是 scripts/g14-artifact-publish.mjs;它只是集群内 Task 的 build/push helper,不做 rollout、不写 D601、不获取 legacy DEV CD Lease。旧 scripts/dev-artifact-publish.mjs 入口已删除;dev-cd-applyci-publish 和旧 main JS CD 入口禁止出现在 G14 Pipeline 生成脚本和 G14 验收证据中。
  • 生成 hwlab-g14-branch-poller CronJob:它使用 G14 集群内的 Git SSH Secret 轮询 G14 分支,按 source commit 创建确定命名的 Tekton PipelineRun。
  • 生成 hwlab-g14-control-plane-reconciler CronJob:它使用同一个 Git SSH Secret 轮询 G14,运行 repo 内 scripts/g14-gitops-render.mjs,并 server-side apply 生成的 Tekton RBAC、Pipeline、Poller 和 Reconciler manifests;因此 CI 控制面变化应自动进入 G14 k3s,不需要人工长期执行 render/apply。
  • 默认输出到 deploy/gitops/g14/
  • 默认 GitOps 生成分支是 G14-gitopsPipeline 成功后把本次 source commit 对应的 deploy/gitops/g14/** 推送到该分支,避免把生成提交继续写回 G14
  • 默认 registry prefix 是 127.0.0.1:5000/hwlab,用于 G14 单节点 k3s 的 node-local registry。
  • 默认 CI/CD proxy 是 G14 本机 http://127.0.0.1:10808 / socks5h://127.0.0.1:10808。Tekton CI step、Docker-in-Docker sidecar 和 publish step 都注入 proxy/no_proxypublish step 必须先在 DIND 内 docker pull $HWLAB_DEV_BASE_IMAGE,再进入 DEV base-image preflight、build 和 registry push,保证 npm、base image 拉取和 registry push 走 G14 本机代理边界。
  • ci-json 不允许每次运行时重新 apt-get installnpx playwright install --with-deps。它必须使用已经预热的 CI 基础镜像,当前默认由 scripts/g14-gitops-render.mjs 固定为 mcr.microsoft.com/playwright@sha256:b0ab6f3cb99aa7803adbc14d9027ec1785fc6e433b97e134e0f8fe61683b6b53;该镜像在 G14 k3s/containerd 中已缓存,包含 Node、npm、Git、Python3、OpenSSH、curl、Playwright 系统依赖和 /ms-playwright/chromium-1217。脚本启动时必须输出 ci-base-imageplaywright-cache-check 结构化日志;缺少工具或 Chromium cache 时直接失败并修基础镜像,不能回退到 runtime apt 下载。若以后需要 Node 22 固定版本,先构建并推送 G14 registry 内的 Node22+Playwright runner 镜像,再修改 HWLAB_G14_CI_JSON_IMAGE/render 默认值。
  • G14 host 只用于 source workspace、GitOps render、k3s 控制和轻量语法/静态合同检查;不要把 host 当成浏览器执行面。当前 G14 host OS 可能比 Playwright 官方 browser 包支持矩阵更新,npx playwright install chromium 会失败或 browser executable 不存在。web:check 默认允许这类明确的 Playwright/browser runtime 环境限制作为 environment_blocker/skip 通过源码合同;真正的布局、移动端和交互 browser smoke 必须在 G14 k3s/Tekton 的 Playwright 基础镜像内运行,不能用 host 上强装 browser 作为长期方案。
  • Poller、control-plane reconciler 和 image publish step 也不允许每次运行时 apk add。当前 G14 registry 固定工具镜像是 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-v1,包含 Node 22、npm、Git、OpenSSH、curl、Python3 和 Docker CLI;生成的脚本只做 proxy preflight 与工具存在性检查。若需要升级工具,先在 G14 构建/推送新的工具镜像,再修改 HWLAB_G14_CI_TOOLS_IMAGE/render 默认值并由 reconciler apply。
  • 服务镜像构建的默认 parent/base image 不得从 Docker Hub 反复拉取。当前 node:20-bookworm-slim 已镜像到 G14 registry 的 allowlist 名称:127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slimrender 默认 base-image 和 poller BASE_IMAGE 都指向这个本地镜像。需要升级 parent image 时,先通过 G14 proxy 拉取并推送到 G14 registry,再修改 HWLAB_G14_DEV_BASE_IMAGE/render 默认值;image publish step 只允许从本地 registry pull base image,且 tag 必须符合 publish gate 的 hwlab-node20-base/hwlab-dev-base/hwlab-node-runtime-base allowlist。
  • 任何依赖下载阶段都必须有可观测诊断。生成的 Tekton 脚本在 apt/apk、npm、Playwright browser、Docker base image pull 和 GitOps promote 之前输出结构化 dependency-proxy-probedependency-curl-probedependency-download-* 日志,至少包含 phase、目标 URL/镜像、脱敏 proxy、首包耗时、总耗时、下载字节数和速度。CI/CD 卡在下载时,先用这些日志判断是 proxy 不可达、目标源慢、DNS/首包慢还是下载吞吐低,再决定是否切换 G14 代理节点或预热镜像;不能只凭 PipelineRun Running 时长判断业务测试失败。

常用命令:

npm run g14:gitops:render -- --source-revision <sourceCommit>
npm run g14:gitops:check

Code Agent Provider Profiles

G14 Code Agent 通过同一个 repo-owned Codex app-server stdio runner 承载多个 OpenAI-compatible Responses profile。Cloud Web 每次请求都发送 providerProfile,后端按 profile 生成本次请求的 env overlay;不得把某一个模型通道硬写死到全局运行态而删除另一个通道。

Profile 默认 Model Base URL 说明
deepseek HWLAB_CODE_AGENT_DEEPSEEK_MODEL,默认 deepseek-chat HWLAB_CODE_AGENT_DEEPSEEK_BASE_URL,默认 http://hwlab-deepseek-proxy.<namespace>.svc.cluster.local:4000/v1/responses G14 集群内 LiteLLM DeepSeek bridge。
codex-api HWLAB_CODE_AGENT_CODEX_API_MODEL,默认 gpt-5.5 HWLAB_CODE_AGENT_CODEX_API_BASE_URL,默认 http://172.26.26.227:17680/v1/responses 保留旧 Codex/OpenAI-compatible Responses API 通道。

hwlab-cloud-api 仍以 HWLAB_CODE_AGENT_PROVIDER=codex-stdio 运行。HWLAB_CODE_AGENT_MODELHWLAB_CODE_AGENT_OPENAI_BASE_URL 可作为 runtime-default 兜底,但前端默认 profile 是 deepseek,用户可以切到 codex-api。Codex app-server 启动参数必须同时设置 provider base URL、modelreview_model,否则 LiteLLM /v1/responses 会收到 model=None。旧 codex-api profile 指向 172.26.26.227cloud-api 的 NO_PROXY/no_proxy 必须包含该 host 或私网段,避免旧通道被 G14 外网代理误拦截。

DeepSeek proxy manifest 是 GitOps desired state 的一部分,DEV/PROD 分别生成在 runtime-dev/deepseek-proxy.yamlruntime-prod/deepseek-proxy.yaml。DeepSeek key 仍通过 hwlab-code-agent-provider/openai-api-key Secret 注入到 proxy 容器;文档、trace、health、issue 和日志不得打印 Secret 值。

Polling 触发

G14 不要求 GitHub webhook 或 GitHub Actions 配置。hwlab-ci/hwlab-g14-branch-poller CronJob 每 5 分钟通过 Git SSH 拉取 G14 HEAD,并用 source commit 的前 12 位生成 PipelineRun 名称 hwlab-g14-ci-poll-<short12>

如果同名 PipelineRun 已存在,poller 直接跳过;如果不存在,则创建新的 PipelineRun。这样可以用 Kubernetes 原生 CronJob、ServiceAccount、RBAC 和 Tekton API 实现无 GitHub webhook 的分支监控,同时避免同一个 commit 被反复派单。历史上的 chore: promote G14 GitOps source ... 生成提交会被 poller 跳过。

Pipeline 的标准路径是:G14 source commit -> CI.json Tekton 测试 -> commit-tagged image push 到 G14 registry -> render deploy/gitops/g14/** -> push G14-gitops -> Argo CD 同步 runtime。CD 只消费已经构建好的镜像和 Git desired state,不在 Argo CD 内构建镜像。

GitOps promotion 成功只证明 G14-gitops 分支已经写入新 desired state;如果 render 改变了 Argo Application、AppProject、runtime path 或 DEV/PROD 拆分目录,必须同步检查并应用 deploy/gitops/g14/argocd/project.yamlapplication-dev.yamlapplication-prod.yamlhwlab-g14-dev 必须指向 deploy/gitops/g14/runtime-devhwlab-g14-prod 必须指向 deploy/gitops/g14/runtime-prod;如果集群里 Application 仍指向旧 deploy/gitops/g14/runtimeArgo 会停在旧 revision,即使 CI/publish/promote 全部成功也不会滚动新镜像。

观察 PipelineRun、Argo 和 rollout 时使用短连接轮询:一次 kubectl get 或有限 logs --tail 后返回,由指挥侧间隔重试。不要用长时间 kubectl wait --timeout=900s 占住 tran G14:k3s 透传锁;如果误用长 wait,只能杀掉本地等待客户端并清理 stale tran lock,不能把这个等待过程当成 CD 失败。

下载阶段排障命令:

KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci logs pod/<pipelinerun-task-pod> --all-containers --tail=400 \
  | grep -E 'dependency-(proxy|curl|download)'

如果 probe 显示 proxy-env-missingproxy-connect-failedtimeout 或速度长期接近 0,应先按 /root/docs/vpn-proxy-ops.md 检查 v2rayN/Hysteria,再重跑 polling。若 probe 正常但后续测试失败,按对应 CI.json 命令和业务检查排障。

手动 render/apply 只允许作为 bootstrap 或 reconciler 故障抢修;正常路径必须由 hwlab-g14-control-plane-reconciler 自动完成 CI 控制面 manifest 更新。

集群资源

  • hwlab-ciregistry、Tekton runner RBAC、Polling CronJob、Pipeline/PipelineRun 所在 namespace。
  • hwlab-ci/hwlab-g14-control-plane-reconciler:自动 render/apply G14 CI 控制面 manifest 的 CronJob。
  • argocdArgo CD 控制面和 hwlab-g14-dev / hwlab-g14-prod Application 所在 namespace。
  • hwlab-devHWLAB DEV runtime namespace,由 Argo CD 应用 deploy/gitops/g14/runtime-dev
  • hwlab-prodHWLAB PROD runtime namespace,由 Argo CD 应用 deploy/gitops/g14/runtime-prod;通过 hwlab-g14-prod-frpc 映射到 18666/18667,正式验收必须同时检查 Argo sync、Deployment ready、FRP public health 与 source commit。

G14 registry 由 Kubernetes Deployment hwlab-ci/hwlab-registry 承载,使用 host network 暴露 127.0.0.1:5000 给 k3s/containerd 和 host-network Tekton build pod。旧 host Docker registry 不能与该 Deployment 同时占用 5000 端口。

G14 k3s/containerd 的 Pod 镜像拉取也必须长期使用 G14 本机代理。主机配置记录在 /root/docs/kubernetes-ops.md,当前 systemd env 文件是 /etc/systemd/system/k3s.service.env。修改代理后需要 systemctl daemon-reload && systemctl restart k3s,并确认 k3s-server 进程环境中存在 HTTP_PROXY / NO_PROXY

凭证边界

HWLAB repo 是私有仓库时,Tekton 和 Argo CD 需要各自的 Git SSH Secret。Secret 只能从 G14 本机已有 SSH key 创建,不能写入 Git,不能打印 key 内容。

Tekton 约定 Secret 名称:hwlab-ci/hwlab-git-ssh

Argo CD 约定 repository Secretargocd/hwlab-git-ssh,并带 label argocd.argoproj.io/secret-type=repository

D601 边界

G14 GitOps manifests 不包含 D601 kubeconfig、D601 node guard、D601 FRP 公网入口或 UniDesk Code Queue 调度入口。D601 仍由既有生产路径维护;G14 GitOps 的安装、PipelineRun、Argo sync 和 registry 操作都不能对 D601 执行 kubectl、docker 或流量切换动作。