一、项目概述

将智能体应用的底座平台 Dify 1.17.1(含新版 Agent 运行时组件)部署至公司测试环境 Kubernetes 集群(Rancher 管理,K8s 版本 1.21~1.24 区间,使用老式 PodSecurityPolicy)。部署形态为单文件手写 yml,覆盖 43 个 K8s 资源、11 个服务组件,接入公司外部 MySQL RDS、集群内共享 Redis 与共享持久卷。
交付物清单:

  • dify-k8s.yml —— 单文件部署清单(Secret 7 / ConfigMap 14 / Service 10 / Deployment 11 / Ingress 1,全中文注释)
  • sql/init-mysql.sql —— DBA 建库脚本(db_dify 主库 + db_dify_plugin 插件库,职责隔离)
  • 部署变量收集清单.md —— 6 项必填变量的来源、替换方式与前置条件核对表
  • 访问入口 demo.test.com(Ingress → Nginx 统一入口),全部占位符清零
项目信息
访问地址http://demo.test.com:8081/(测试环境入口)
管理员账号admin@qq.com
管理员密码已移除(请向项目负责人获取,首次登录后请立即修改)
数据库MySQL:db_dify(主库)/ db_dify_plugin(插件库)
使用文档Dify 官方使用文档(中文)
指标数值
服务组件全部 Running11
K8s 资源(单文件管理)43
镜像推送至私有镜像仓库9
Redis 明文密码残留0
上线组件清单:
组件职责端口
dify-apiAPI 主服务(启动时自动执行数据库迁移)5001
dify-worker / dify-beat异步任务 Worker 与定时调度(Celery)—
dify-web控制台前端3000
dify-proxyNginx 统一入口(公司健康检查 :80 /keeplive)80
dify-plugin-daemon插件守护进程(独立数据库 db_dify_plugin)5002/5003
dify-sandbox / dify-local-sandbox代码执行沙箱 / Agent 本地沙箱8194 / 5004
dify-ssrf-proxySSRF 防护代理(squid 出网白名单)3128
dify-agent-backend新版 Agent 运行时后端5050
weaviate向量库(复用共享 PVC,单副本 Deployment)8080/50051

三、部署时间线(关键节点)

  1. 部署初期 —— 交付物制作:基于官方 helm chart(dify-helm 0.39.0)渲染后人工整理为单文件手写 yml,对齐公司 Flowise 模板规范:default 命名空间、default-secret 拉取凭证、共享 PVC subPath 隔离、健康检查内嵌脚本风格;同步交付 DBA 建库 SQL 与变量收集清单。
  2. 准备阶段 · 变量填充与镜像核对:填充镜像前缀(示例镜像仓库 registry.example.com/dify-demo,13 处)、访问域名(demo.test.com)、内部通信 Key;与运维推送的 9 个镜像逐一核对(含 nginx 确认为 1.18.0 固定版本);DB / Redis 凭据落位。
  3. 准备阶段 · 注释中文化与健康检查专项:批量翻译 helm 自带英文注释 109 处(保留模板来源标记与示例配置),YAML 结构校验通过;启动健康检查专项:调研公司「探针必须 httpGet :80 /keeplive」规定,逐镜像探测工具链(api 系有 python3、web 有 node、squid 有 perl、weaviate 仅 busybox nc),本地 Docker 实测非 root 绑 80 与四种语言的极简 HTTP 实现。
  4. 准备阶段 · 健康检查方案落地:选定「启动命令内嵌轻量 HTTP 服务」方案(与公司 Flowise 模板同款、零新增容器):新增统一 ConfigMap dify-health-probe(health.py / health.js / health.sh / health.pl 四版本挂载 /k8s-health),11 个 Deployment 探针统一为 httpGet :80 /keeplive,nginx 入口 listen 8080→80 并新增 /keeplive 端点。
  5. 部署中期 —— Redis 接入改造:按运维建议弃用外部地址 redis.syy.com,改用集群内现成 Service(redis.default:6379)+ 现成 Secret(redis/passwd)密钥引用;删除自建 Secret,yml 中 Redis 明文密码清零;Celery broker 与 Agent Redis 连接串改为启动命令动态拼接(密码 URL 编码,特殊字符实测验证)。
  6. 首次集群部署与密集排障:集中定位并解决 6 类问题:镜像拉取凭证缺失、RWO 共享卷跨节点冲突、K8s Service 环境变量注入冲突、非 root 绑 80 的安全策略适配(sysctl 被 PSP 禁止 → root 路线)、local-sandbox 的 runAsNonRoot 特例、老版本 Redis 不支持 RESP3 握手。全部修复经 YAML 校验与本地实测后重部。
  7. 收尾与全量上线 —— 持续排障深化:定位 weaviate 健康探针大面积 refused 的竞态根因(busybox nc 管道 EOF 监听空窗),改用文件重定向后实测 6/6 稳定;SSRF 白名单按官方默认留空(组件互调不受影响)。11 个组件全部 Running,部署成功;随后进入深度排障阶段,先后解决内核 seccomp 兼容、MySQL 方言差异、老版本 Redis 语法依赖、时区统一与 Agent 会话持久化(见难点 9 – 13)。

四、难点与解决方案

以下 13 项为部署与上线排障过程中影响最大的问题,均按「现象 → 根因 → 解决 → 验证」闭环处理。

难点 1 | 健康检查适配公司规范:非特权端口 80 的绑定

  • 现象:公司规定所有工作负载探针必须 httpGet :80 /keeplive。Dify 各镜像默认以非 root 用户(uid 1000/1001)运行,健康服务绑定 80 报 PermissionError;而 root 运行又被 kubelet 以 “breaks non-root policy” 拒绝(仅 local-sandbox 一个组件报错)。
  • 根因:三重约束叠加:① 集群运行时较老,不向非 root 进程保留 NET_BIND_SERVICE 能力(本地新版 runc 可保留,导致本地验证通过、集群失败);② PodSecurityPolicy 禁止 net.ipv4.ip_unprivileged_port_start unsafe sysctl;③ local-sandbox 容器被 helm chart 原生注入 runAsNonRoot: True,kubelet verifyNonRoot 检查直接拒绝 root 启动。
  • 解决:三轮方案演进后收敛为:7 个绑 80 组件统一 runAsUser: 0(与公司 Flowise 模板已验证的实践一致),local-sandbox 显式 runAsNonRoot: False 关闭该特例;健康服务由启动命令内嵌(脚本经 ConfigMap 统一挂载),非 root 组件的能力补充方案(sysctl 白名单 / 镜像 setcap)作为备案留档。
  • 验证:python3 / node / perl / nc 四种健康脚本在对应镜像内全部实测返回 200;启动链完整性确认(tini、entrypoint.sh、MODE 环境变量分叉均未被破坏)。

难点 2 | 老版本 Redis 与 RESP3 协议不兼容

  • 现象:api 启动执行数据库迁移时崩溃:unknown command HELLO,Redis 连接失败,迁移锁获取不到。
  • 根因:公司共享 Redis 版本低于 6.0,不支持 RESP3 协议的 HELLO 握手命令;而 Dify 1.17.1 的配置项 REDIS_SERIALIZATION_PROTOCOL 默认值为 3。镜像内 redis-py 7.4.0 默认协议实为 RESP2,仅 Dify 显式传 3 的连接路径受影响。
  • 解决:源码级分析确认兼容分支存在后,在 dify-api / dify-worker 两个 ConfigMap(覆盖 api/worker/beat 三组)增加 REDIS_SERIALIZATION_PROTOCOL: "2" 切回 RESP2,无需升级 Redis 或修改镜像。
  • 验证:重新部署后迁移正常执行、迁移锁正常获取;Celery(kombu,默认 RESP2)经确认不受影响。

难点 3 | Redis 接入改造:密钥引用与连接串动态拼接

  • 现象:初版方案在自建 Secret 中明文存放 Redis 密码,且连接地址指向外部实例,密钥轮换与安全审计不便。
  • 根因:K8s 环境变量不支持字符串模板拼接——Dify 的 CELERY_BROKER_URL / DIFY_AGENT_REDIS_URL 必须是内嵌密码的完整 URL,无法直接用 secretKeyRef 引用单键密码。
  • 解决:地址改为集群内 Service(redis.default:6379);密码经 secretKeyRef 注入环境变量;完整 URL 在启动命令前缀动态拼接(python urllib 强制 URL 编码,特殊字符密码实测通过);api 缓存与 plugin-daemon 使用分离变量(REDIS_HOST/PORT/PASSWORD)无需拼接;自建 Secret 删除,明文密码彻底退出 yml。
  • 验证:特殊字符密码编码实测正确(p@ss → p%40ss);4 个拼接组件启动脚本全部通过 bash -n 语法检查。

难点 4 | K8s Service 环境变量注入撞配置项

  • 现象:beat 组件启动即崩:配置校验报 PGVECTOR_PORT 应为整数,实际收到 tcp://10.247.160.114:5432。
  • 根因:K8s 会把同命名空间所有 Service 自动注入 Pod 环境变量;集群 default 命名空间已存在其他应用的 pgvector Service,注入的 PGVECTOR_PORT 恰好与 Dify 整型配置项同名冲突(自有 weaviate Service 同理存在 WEAVIATE_PORT 隐患)。
  • 解决:11 个 Deployment 的 Pod 模板统一补齐 enableServiceLinks: false(初版仅 api/web 有),一次性消除此类注入冲突。
  • 验证:重部后 beat 正常进入启动流程,配置校验错误消失。

难点 5 | 镜像拉取失败(ImagePullBackOff)

  • 现象:滚动更新后新 Pod 全部 ImagePullBackOff,旧 Pod 借滚动保护机制继续运行。
  • 根因:初版整理时 10 个 Deployment 遗漏 imagePullSecrets(仅 weaviate 由 chart 自带);部分节点此前手动预拉过镜像,IfNotPresent 策略掩盖了缺失,新 Pod 调度到无缓存节点后问题暴露。
  • 解决:11/11 全部补齐 imagePullSecrets: [{name: default-secret}],复用公司现成 SWR 拉取凭证。
  • 验证:重部后各节点拉取成功,日志出现 “already present on machine” 与正常 Pulled 记录。

难点 6 | RWO 共享卷跨节点调度冲突

  • 现象:dify-local-sandbox 卡在卷挂载:Unable to attach or mount volumes: home-data ... timed out。

  • 根因:共享持久卷 demo-test-pvc 为 RWO(单节点读写)模式,已挂载节点与新 Pod 调度节点不同时无法二次挂载,kubelet 挂载等待超时。

  • 解决:分级处理:local-sandbox 两个沙箱执行目录(/home/dify、/workspace)数据无需持久化,改为 emptyDir 解除节点绑定(PVC 引用 6→4);真正需要持久化的 api / worker / plugin-daemon / weaviate 增加互相亲和性(podAffinity,topologyKey 为节点名),强制聚到同一节点。

  • 验证:重部后卷挂载正常;Pod 集中单节点运行。备案方案(向运维要节点名改 nodeSelector 钉定)已写入文档。### 难点 7 | weaviate 健康探针竞态(监听空窗)

  • 现象:weaviate 容器进程存活,但 /keeplive 探针 30 分钟内 124+ 次 connection refused / reset,Pod 反复被标记 Unhealthy。

  • 根因:健康脚本用 printf 响应 | nc -l -p 80 管道喂响应——printf 写完立即关闭写端,nc 的标准输入马上 EOF,busybox nc 频繁退出,80 端口出现毫秒级监听空窗;本地手动验证间隔大恰好躲过,集群探针(liveness + readiness 平均 5 秒一次)高频命中。属测试盲区型问题。

  • 解决:响应改为文件重定向(printf 一次性写盘,循环内 nc -l -p 80 < 响应文件),消除 stdin EOF 竞态;根因与修法注释写入脚本,防止后人复踩。

  • 验证:weaviate 镜像内连续 6 次请求 + 并发双连接全部 200;重部后探针事件恢复 Healthy。

  • 根治升级:文件重定向版仅缓解——kubelet 双探针(liveness + readiness 交错)仍会打出间歇空窗。最终改为 nginx sidecar 方案:weaviate Pod 内加 keepalive-nginx 容器(nginx:1.18.0)常驻监听 80 多连接响应 /keeplive,主容器回归原生启动,探针竞态彻底根治。

难点 8 | nginx 入口版本收敛与安全硬化

  • 现象:初版入口镜像使用 latest 浮动 tag,与运维实际推送版本不一致,存在不可复现风险。
  • 根因:镜像推送清单与 yml 未锁定同一版本号。
  • 解决:收敛为 nginx:1.18.0 固定 tag(配置指令兼容性逐条核对通过),并在 http 块补充 server_tokens off 隐藏版本号;同时明确运维注意事项:删除重建 Service 后需滚动重启 dify-proxy 以刷新 DNS 解析。
  • 验证:YAML 合法性、探针、密钥一致性终检通过。

难点 9 | dify-sandbox 代码执行崩溃(内核 3.10 的 seccomp 兼容)

  • 现象:dify-sandbox Pod CrashLoopBackOff,日志 panic: could not create filter;业务编排里的代码执行节点完全不可用。特权模式(privileged)与 seccompProfile: Unconfined 均无效。
  • 根因:集群 7 节点均为 CentOS7 内核 3.10.0-1160:镜像内 libseccomp 2.6.0 初始化时用 seccomp(GET_ACTION_AVAIL) ioctl 探测内核是否支持 KILL_PROCESS,老内核无该 ioctl(ENOSYS)→ libseccomp 拒绝初始化。实测该内核(RHEL backport)实际能加载 KILL_PROCESS 过滤器(触发后 SIGSYS、退出码 159)——只是预探测被挡。曾假设"伪造 actions_avail 文件"可绕过,经本地忠实模拟(拦截 ioctl + bind mount 伪造文件)实测 2.5.3/2.6.0 均不回退读该文件,方案否决,避免了一次无效部署。
  • 解决:不换镜像、不打镜像:/etc/ld.so.preload 注入自编译兼容钩子 hook.so(ConfigMap binaryData 携带),仅拦截 GET_ACTION_AVAIL(KILL_PROCESS) 探测返回"支持",其余全部透传;真正的过滤器加载由 runner 的 Go 代码原生 syscall 直达内核(部署前已在容器内预检 TSYNC 标志支持)。
  • 验证:本地真实镜像端到端:python3/nodejs 代码执行成功、50+ 次压测与无钩子对照零异常、拦截力完好(ptrace 被 SIGSYS 击杀、正常代码放行);集群部署后代码执行节点恢复,业务验证通过。

难点 10 | 探索页 500:MySQL 方言 NULLS LAST(含补丁勘误)

  • 现象:探索页 GET /console/api/installed-apps 返回 500,MySQL 报 1064 语法错误,SQL 中出现 ORDER BY ... DESC NULLS LAST。
  • 根因:services/installed_app_service.py 的排序函数使用 PG 专属语法 NULLS LAST(MySQL 含 8.0 不支持)。第一版补丁覆盖 repositories/installed_app_repository.py——该文件在 dify-api:1.17.1 镜像内根本不存在:当时基于本地源码副本扫描与验证,而本地副本与镜像版本不一致,挂载的文件从未被 import,等于没修。
  • 解决:从镜像内导出真实文件核对后改写为两键跨方言等价((last_used_at IS NULL) ASC + last_used_at DESC,语义与 NULLS LAST 完全一致,生产换 PostgreSQL 也无碍),ConfigMap 单文件覆盖 site 内对应文件;同步在文档中记录勘误。
  • 验证:SQLAlchemy MySQL/PG 双方言编译验证(补丁版两方言产物一致且无 NULLS 关键字);镜像内全量 grep 仅剩 vastbase 向量库驱动(本环境不加载);集群部署后探索页恢复正常。

难点 11 | Agent 应用对话全空 + SSE 断流(Redis 6.2+ 语法依赖)

  • 现象:Agent 应用(构建模式/对话)发消息后全部无回复,前端红条 SSE stream reconnect attempts exhausted;Chatflow 编排直接用 LLM 节点正常。api 日志特征:每秒一次 GET /runs/{id}/events/sse?after=0-0 200 OK 且游标始终停在 0-0。
  • 根因:agent-backend 容器日志实锤:redis.exceptions.ResponseError: Invalid stream ID——事件读取用 XRANGE ... min="(游标)",“(id” 排他范围语法是 Redis 6.2 新增特性,公司 Redis 版本低于 6.2,执行即报错 → SSE 事件流每次建立立即断开 → 重连耗尽。本地 compose 环境正常(redis 6/7 支持)造成了环境差异假象。
  • 解决:单文件补丁等价改写:包含下界读取 + 应用层剔除游标自身条目(Stream ID 按 ms-seq 数值比较而非字典序),兼容 Redis 5.0+;镜像内全量 grep 确认仅此一处 6.2+ 特性用法,ConfigMap 覆盖 site-packages 内对应文件。
  • 验证:本地真实容器 5 用例(全量/中游游标/分页/空流/模拟老 Redis):原版与补丁版结果完全一致;模拟老 Redis 下原版精确复现集群故障、补丁版正常。集群部署后 Agent 对话恢复,业务验证通过。

难点 12 | 日志与业务时间早 8 小时(容器 UTC 时区)

  • 现象:应用日志与数据库业务时间(created_at 等)均比北京时间早 8 小时(日志里的 06:11 实际为 14:11)。
  • 根因:容器默认 UTC(官方镜像与 compose 默认即 UTC,本地容器实测确认):应用日志、datetime.now()、数据库写入全部 UTC。另 Dify 有独立 LOG_TZ 配置(默认 UTC)单独控制日志时间戳——只设 TZ 不设 LOG_TZ 日志仍是 UTC。
  • 解决:不改镜像:8 个 ConfigMap 加 TZ: Asia/Shanghai(经 envFrom 传播);api/worker 额外加 LOG_TZ(源码确认同时控制日志与 Celery 调度时区);ssrf-proxy/weaviate 在 Deployment env 直接加。ConfigMap 变更需手动重启 Pod。
  • 验证:容器内实测 TZ 生效后 datetime.now 输出北京时间;部署后日志与业务时间恢复同步。历史 UTC 数据不自动修正(测试环境接受,订正需另行评估)。

难点 13 | Agent 会话工作区丢失(emptyDir 盲区 + 卷写法死锁)

  • 现象:重启组件后 Agent 对话全部失败:invalid_cwd (400): cwd is not a directory: /workspace/<uuid>;且修复部署时 local-sandbox 又遇挂载死锁(ContainerCreating 超时)。

  • 根因:三层叠加:① Agent 运行时 binding 持久引用工作目录(会话快照记录 /workspace/<uuid>、/home/dify/<uuid>);② local-sandbox 两卷是 emptyDir(难点 6 RWO 改造时判断"沙箱执行目录无需持久化"——对代码执行成立,对 Agent 会话是盲区;官方 compose 用持久卷无此问题);③ Dify 1.17.1 local 后端无自愈:acquire 的目录校验脚本在丢失的 cwd 里执行 → 直接 400,包装为 BindingAcquireError,而全链路只捕获 BindingLostError → 重建路径永不触发(e2b/enterprise 后端有自愈分支,唯独 local 没有)。

  • 解决:两步演进:① 持久化——复用 demo-test-pvc 独立 subPath(独立专用 PVC 草案因集群默认 StorageClass 未知被推翻),并将 local-sandbox 并入 podAffinity 同节点组——RWO 真实语义是同节点多 Pod 共挂合法、跨节点才冲突,之前改 emptyDir 的真正障碍只是无亲和约束;② 部署卡点——首版"两个 volume 条目引用同一 claim"在同 Pod 下挂载死锁,对照实验坐实(同节点 4 个单卷 Pod 正常 + 对照测试 Pod 单卷秒起),改标准写法:单 volume 双 volumeMount(kubelet 一次挂载、两次 subPath bind)。

  • 验证:部署后 Agent 新建会话正常回复,退出重进再发消息正常(会话目录持久化),local-sandbox 重启不再影响会话;写法坑已写入 yml 注释防止复踩。## 五、方法论与过程亮点

  • 问题先本地复现,再上集群:镜像工具链探测、非 root 绑 80 实测、URL 编码验证、nc 竞态复现等均先在本地 Docker 验证闭环,减少集群试错成本;唯一漏网的是「运行时能力保留差异」与「探针高频竞态」两个环境相关项,随后也以同法闭环。

是

否

否

是

现象出现

是否环境相关
内核 / 中间件版本

容器内探测真实能力

导出镜像内真实文件核对

本地真实容器复现

设计最小改动方案
优先 ConfigMap 单文件覆盖,不打镜像

行为对照验证等价性

集群部署验证

问题闭环

沉淀为可复用排障范式

  • 源码级定位,不靠猜测:Redis 协议问题定位到 Dify 配置默认值(REDIS_SERIALIZATION_PROTOCOL=3)与 redis-py 7.4 实际默认(RESP2)的差集;local-sandbox 拒绝问题精确定位到 kubelet verifyNonRoot 的报错原文与 chart 原生 runAsNonRoot 字段。
  • 全程可回滚:每次改动前快照备份(.temp/ 保留 12+ 个版本锚点),所有批量修改经结构化 YAML 校验(资源数、探针数、密钥一致性、占位符计数)。
  • 安全基线内建:Redis 密码经 Secret 引用零明文残留;Redis 明文密码曾出现在早期报错日志,已向运维提出轮换建议(引用式接入换密码无需改 yml)。
  • 文档驱动协作:变量收集清单(6 项变量的来源/替换命令/前置条件)、健康检查改造说明、存储调度策略说明随交付物同步沉淀,运维对接口径统一。
  • 源码核对以镜像内文件为准:MySQL 补丁第一版因本地源码副本与镜像版本不一致而完全落空(覆盖的文件在镜像内根本不存在、从未被 import)——此后所有源码级排查均先 docker 导出镜像内真实文件核对,本地副本只作参考;这是两次 500/断流问题定位的关键转折。
  • 老基础设施的隐含依赖系统排雷:公司环境内核 3.10、Redis <6.2 属"老底座",官方镜像隐含依赖新内核/新中间件特性(seccomp KILL_PROCESS 探测、XRANGE 排他语法、RESP3)——统一按"先在容器内探测实际能力,再定方案"处理,三个问题共用一套"ConfigMap 单文件补丁、不打镜像"的落地模式。
  • 补丁等价性实证,不只语法校验:每个补丁都在真实容器/真实中间件上做行为对照(原版与补丁版同输入比输出;模拟老环境复现故障、补丁版通过),确保"修了"且"没修坏"——如 seccomp 钩子验证拦截力(ptrace 被击杀)而非只验证"能跑"。
  • 与公司规范对齐:健康检查内嵌脚本风格、单文件手写 yml、default-secret 拉取凭证、共享 PVC subPath 隔离,均与既有 Flowise 部署实践保持一致,降低运维接手成本。

六、遗留事项与后续建议

SSRF 白名单留空(有意为之):SSRF_PROXY_ALLOW_PRIVATE_IPS 当前为空,公网调用(如第三方智能体平台)不受影响;将来 HTTP 请求节点需要访问公司内网地址时,按运行时报错提示将集群网段(Pod 网段 + Service 网段,如 10.247.0.0/16)填入即可,yml 内已附操作注释。

  • 业务回归(核心链路已通过):探索页(MySQL 补丁后)、Agent 应用对话(Redis 补丁后)、代码执行节点(seccomp 钩子后)均验证通过;积分兑换智能体迁移重构持续进行中。
  • 三个兼容补丁的维护提示:dify-api-mysql-patch / dify-sandbox-seccomp-hook / dify-agent-backend-redis-patch 与镜像版本绑定——升级 Dify 镜像前需评估补丁是否仍适用(新镜像可能已修复或改路径);公司 Redis 升级至 6.2+、内核升级后,Redis/内核两类补丁可移除;生产换 PostgreSQL 后 MySQL 补丁可移除(决策已写入清单文档)。
  • Redis 密码轮换(建议运维执行):密码曾出现在早期报错日志中;因已改为 Secret 引用,轮换后仅需重启 Pod,无需改动任何部署文件。
  • plugin-daemon 持续观察:其 golang 客户端(go-redis)与老版本 Redis 的兼容性如后续出现 HELLO 类报错,需单独处理(与 Python 侧路径不同)。
  • 集群维护提示:ReplicaSet rev:1/2/3 历史属滚动更新正常记录(副本数 0,不占资源);若需精简可调低 revisionHistoryLimit。删除重建 Service 后需 kubectl rollout restart deploy/dify-proxy 刷新 nginx 的静态 DNS 解析。
  • 容量巡检:共享 PVC telefen-test-pvc 各 subPath(dify / plugin-daemon / weaviate)建议纳入容量监控。

七、小结

从交付物制作、镜像推送、安全策略适配,到 11 个组件全部 Running,再到上线后 13 个问题的逐个闭环,这次部署最大的收获不是"跑起来了",而是形成了一套可复用的排障范式:先在容器内探测真实能力,再决定方案;补丁以镜像内文件为准,用行为对照证明等价;能不打镜像就不打镜像,用 ConfigMap 单文件覆盖落地。对于同样跑在老内核、老 Redis 上的团队,希望这份记录能帮你少踩几个坑。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐