1. 从"一个IP一个路径"到多目录多端口:静态PV的真实生产形态
1.1 静态PV的默认假设,以及我第一次扩容时踩的坑
大部分人第一次在K8S里用NFS静态PV,都是从搜索引擎抄来的一段配置:一个server IP、一个共享路径、一份YAML,新建PV和PVC,Pod直接挂上去。这套流程看似简单,但也正是因为简单,很多人忽略了静态PV背后其实藏着一个很强的隐含假设——你的NFS服务只提供了一个目录给K8S用。
我第一次用NFS静态PV做生产环境的时候,就是栽在这个假设上。当时某存储服务的NFS服务器上同一个路径下堆了三个应用的数据目录,我图省事,只建了一个PV,PVC申请了100Gi,三个应用各自用subPath切分。刚开始一切正常,后来其中一个应用数据量暴涨,把整个挂载点写满,另外两个应用直接开始报磁盘满、日志刷都刷不出来。更麻烦的是,由于所有应用的数据都在同一个NFS导出路径下面,连运维排查都变得很难受,审计那边一问"这批数据到底属于哪个应用",我根本答不上来。
这次教训让我把"多目录多端口"这件事重新认真梳理了一遍。所谓多目录,是指一台NFS服务器上导出了多个目录,你需要给每个目录分别创建静态PV;所谓多端口,是指NFS服务并不一定都在默认的2049端口上,可能因为端口冲突、防火墙限制或者同一台宿主机上跑了多个NFS实例,你必须通过mountOptions告诉K8S去连哪个端口。这两件事单独看都不难,放在一起就容易出问题——而且越到后面越会发现,配置本身只占三成,剩下七成全在梳理服务端真实暴露信息和排查挂载失败上。
1.2 多目录多端口并发出现时的三种常见拓扑
先看清"多目录多端口"到底长什么样,后面配置的时候心里才有底。
第一种拓扑最简单:一台NFS服务器,导出多个目录,全部走标准2049端口。这是最常见的,比如一台存储服务器上分别导出/export/appdata、/export/logs、/export/backup,K8S集群里需要三个PV分别对应三个目录。这种场景的核心工作量和NFS本身关系不大,更多是在K8S侧把PV、PVC、命名规则、容量规划、回收策略这些整理清楚。
第二种拓扑:一台服务器上有多个NFS服务实例,监听不同端口。这种情况多出现在NFS服务和其它服务共享同一台宿主机,2049端口被别的进程占了,或者运维为了隔离多套存储服务,在同一台机器上起了两个nfsd实例,一个监听2049,另一个监听3049。K8S侧要为不同端口的服务分别创建PV,每个PV的mountOptions里都要写清楚端口,不能混用。
第三种拓扑:多台NFS服务器,各自目录不同、端口也不同。这种在实际生产里越来越多,因为一台NFS服务器扛不住所有存储压力。这时你面对的其实是一张"目录-端口-服务IP"的三维对照表,哪一行配错了,哪个PV就挂不上。
我后来在配置静态PV时,第一步永远是先画这张表,把服务器IP、导出路径、端口、容量、给哪个应用用全部列出来。这也算是我从那次翻车里总结出的第一个经验:NFS静态PV的复杂度从来不在YAML写法上,而在对服务端信息的准确梳理上。
2. 多目录静态PV:一台NFS服务拆出N个独立卷的正确姿势
2.1 多目录与subPath的本质区别,别把两者混为一谈
先说一个很多人搞混的概念:多目录和subPath不是一回事。
subPath是K8S里Pod/Deployment在挂载PVC时使用的一个字段,作用是在同一个PV内部,把某个子目录单独挂载进容器的某个路径。比如一个PV下有一个app1目录和一个app2目录,Pod A通过subPath: app1只挂载前者,Pod B通过subPath: app2只挂载后者。这在很多场景下是合理的,尤其是多个服务共享同一份数据、或者只想让某个服务看到部分目录的时候。
但subPath有一个致命弱点:它解决不了容量和数据的隔离问题。所有subPath共享的是同一个PV的存储空间,任何一个子目录写满了,整个PV就满了,其它子目录全部遭殃。而且从PV的维度看,你始终只有一块"大卷",想针对某个应用单独扩容、单独设置回收策略,根本做不到。
多目录静态PV解决的是另一个问题:在NFS服务端把物理目录分开,每个目录独立建PV,每个PV独立管理容量、权限、回收策略。这个时候数据从根上就是隔离的,一个目录写满不会波及其他目录。
我的建议很明确:如果两个应用的数据语义上完全不同(比如一个是业务数据,一个是日志),就别用subPath硬塞进同一个PV;如果只是同一个应用内部不同组件要访问不同子目录,才考虑subPath。这两件事从一开始就要分开,后面少很多坑。
2.2 PV字段逐个拆解:server、path、readOnly的正确关系
多目录静态PV在写法上其实不复杂,但有几个字段值得好好抠一下。
下面是三个标准目录对应三个PV的最小化配置:
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-appdata labels: storage-tier: nfs nfs-path: appdata spec: capacity: storage: 100Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.20 path: /export/appdata readOnly: falseapiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-logs labels: storage-tier: nfs nfs-path: logs spec: capacity: storage: 50Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.20 path: /export/logs readOnly: falseapiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-backup labels: storage-tier: nfs nfs-path: backup spec: capacity: storage: 200Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.20 path: /export/backup readOnly: false这里有三个容易被忽略的地方。
第一,nfs.path写的是服务端的导出路径,不是客户端挂载路径,也不是K8S集群里的任何路径。很多人配置的时候会下意识写/mnt/nfs/appdata这种自己脑子里想象的路径,结果被NFS服务端直接拒绝。要把这个值和你/etc/exports里写的导出条目一一对应。
第二,capacity和accessModes更多是"声明"而不是"检查"。NFS PV没有强制配额机制,你写100Gi只是告诉K8S这个卷有100Gi容量,实际NFS服务端磁盘多大、是否被其它目录占用,K8S并不知情。所以容量规划要在NFS服务端做(比如用逻辑卷划分、做配额),K8S侧的capacity只是给调度器看的参考值。
第三,readOnly字段可以按目录粒度设置。比如日志目录给只读权限,业务数据目录读写都行。多目录的好处就在这里,每个PV可以有不同的权限策略,这在单PV+subPath方案里是做不到的。
2.3 多目录场景的命名、容量与回收策略规划
多目录静态PV一旦建起来,数量会快速膨胀。如果没有统一的命名规范和标签规划,三个月后你回头看,PV列表里全是nfs-pv-1、nfs-pv-2这种名字,想找出某个目录对应的PV得靠猜。
我的做法是在PV的metadata.name里带上目录语义,同时在labels里打上维度标签。比如:
- PV名:
nfs-pv-appdata,直接体现目录用途; - 标签:
storage-tier: nfs表示存储层,nfs-path: appdata表示具体目录,nfs-server: storage-01表示来源服务器。
标签这个东西平时看不出什么价值,等到你要用kubectl get pv -l nfs-server=storage-01一次性列出某台服务器上所有PV的时候,就知道有多香了。
容量规划上,建议按照"目录预期增长量×1.5"来预留。太抠容易提前写满,太富则浪费存储。我见过有人给一个实际只有几GB的目录配置了1TiB的PV,这在NFS服务器上就是纯浪费。
回收策略这块,NFS静态PV我强烈建议统一用Retain。K8S文档里NFS类型卷对Delete回收策略的支持非常有限,实际测试中删除PVC后PV会变成Released状态,但底层的NFS数据并不会被清理,最后还是要人工介入。与其这样,不如一开始就用Retain,把数据生命周期管理的主动权握在自己手里。后面真要删除PV,再按"NFS服务端删目录、K8S删PV、确认无误"的顺序手工处理。
3. 多端口静态PV:mountOptions背后的NFS RPC端口机制
3.1 NFS为什么不止一个端口:rpcbind、nfsd与mountd
多端口这个问题,比多目录要隐蔽得多,因为它牵扯到NFS协议本身的端口发现机制。
很多人以为NFS就和SSH一样,固定一个端口,client连过去就完事。实际上NFSv3时代的端口模型要复杂得多,整个挂载过程至少涉及三类角色:
- rpcbind:默认端口111,类似于"端口索引服务",负责登记和查询各类RPC服务绑定在哪个端口上;
- nfsd:负责文件读写服务,默认端口2049;
- mountd:负责处理挂载请求(就是客户端问"我能挂载哪个目录"),端口默认是随机分配的,需要通过rpcbind查询。
也就是说,一个NFSv3客户端在挂载时,第一步是先和rpcbind通信,查询mountd的端口;第二步向mountd确认要挂载的导出路径是否存在、是否有权限;第三步才真正通过nfsd端口建立文件读写连接。整个过程远不是"连一个2049端口"那么简单。
当NFS服务端跑在非标准端口上时,问题就开始出现了。比如我在某个环境里遇到过2049端口被别的服务占用,运维把NFS的nfsd端口改成了3049。如果K8S里的PV不指定端口,kubelet在节点上执行mount.nfs时会默认去连2049,结果自然是连接超时。
3.2 mountOptions怎么映射到mount.nfs参数
K8S静态PV里的mountOptions字段,本质上就是把参数透传给客户端节点的mount.nfs命令。挂载失败排查时,很多人只盯着PV的YAML看,忘了去节点上手动执行一下mount,这是很大的误区。
在多端口场景下,需要在spec.mountOptions里明确写出的参数至少包括:
mountOptions: - nfsvers=3 - proto=tcp - port=3049 - mountport=40001 - hard - timeo=600 - retrans=2这里每一项都有具体含义,不是随便填的:
nfsvers=3:强制使用NFSv3。如果服务端是v3,客户端默认可能去协商v4,而v4的端口模型完全不同(固定2049),反而会导致非标准端口的配置失效;proto=tcp:指定TCP传输协议。UDP在某些网络环境下也能走,但K8S集群内部网络建议统一TCP,稳定性更好;port=3049:告诉客户端nfsd服务监听的端口。如果在配置里漏了这项,客户端就会默认去连2049;mountport=40001:告诉客户端mountd服务对应的端口。这是最容易漏的一项,因为很多人不知道NFSv3挂载还需要走mountd。默认情况下mount.nfs会去问rpcbind(111端口),如果rpcbind不可达或者防火墙挡了111,挂载同样会失败,这时候显式写上mountport就绕过了rpcbind查询,直接连目标端口。
关键点:这些端口值不是拍脑袋填的,必须从NFS服务端实际查出来。常用的命令是rpcinfo -p <server-ip>,它会列出当前机器上所有RPC服务的注册端口,其中nfs对应的就是nfsd端口,mountd对应的就是mountd端口。先把这两个值查清楚,再写到mountOptions里。
3.3 NFSv3与NFSv4在端口配置上的路线选择
这里还要做一个路线决策:到底用NFSv3还是NFSv4?我的经验是,K8S挂载NFS多端口场景下,优先选NFSv3,并且显式指定nfsvers=3。
原因在于,NFSv4协议进行了端口精简,整个挂载过程基本固定走2049端口,不再依赖rpcbind和mountd(v4.0之后mountd的职责被整合进协议内部)。如果服务端跑在非标准端口,v4的配置反而更麻烦,需要在客户端和服务端同时维护额外的端口映射,出问题的时候排查链路更长。NFSv3虽然端口角色多,但只要把port和mountport这两个值写对,挂载是非常稳定的。
当然,如果服务端本来就是标准的NFSv4(2049端口),那PV里不写端口参数也完全没有问题,让客户端走默认协商就行。多端口场景才需要显式配置,单端口标准场景少即是多。
我的建议是,在和NFS服务端管理员确认协议版本时,就把下面这张表填好,一份给K8S配置用,一份留档给后续排查用:
| 服务端角色 | 默认端口 | 实际端口(以rpcinfo输出为准) |
|---|---|---|
| rpcbind | 111 | 111 |
| nfsd | 2049 | 3049 |
| mountd | 随机 | 40001 |
这张表是排查多端口问题时的"通讯录",每次配置新PV之前先更新它。
4. 多目录×多端口组合案例:一套完整的PV/PVC/Pod配置
4.1 案例背景与两张端口表的梳理
理论讲了这么多,直接上一个我实际配置过的组合案例,完整走一遍。
假设环境如下:
- 同一条内网里的三台存储服务器,分别承担不同职责:
- 服务器A(192.168.10.20):标准NFSv3服务,监听2049,导出
/export/appdata和/export/logs两个目录; - 服务器B(192.168.10.21):NFS服务因为端口冲突跑在3049,mountd端口为40001,导出
/export/backup目录。
- 服务器A(192.168.10.20):标准NFSv3服务,监听2049,导出
先用rpcinfo -p摸清了服务端真实暴露情况:
| 服务器 | 导出目录 | nfsd实际端口 | mountd实际端口 | 协议版本 |
|---|---|---|---|---|
| 192.168.10.20 | /export/appdata | 2049 | 随机 | NFSv3 |
| 192.168.10.20 | /export/logs | 2049 | 随机 | NFSv3 |
| 192.168.10.21 | /export/backup | 3049 | 40001 | NFSv3 |
注意一个细节:服务器A的mountd端口是随机分配的,那为什么PV里不用写mountport?因为标准场景下客户端会自动通过rpcbind查询到mountd端口,不需要K8S显式指定。只要111端口通,挂载就能正常完成。服务器B则不同,它的nfsd不在标准端口,而且运维明确告诉我rpcbind对外不可达,所以我必须把port和mountport都写死,完全跳过rpcbind这个查询环节。
4.2 三个PV的完整YAML与关键差异点
三个PV的完整配置如下。
服务器A的appdata目录,端口用默认值,不用指定:
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-appdata labels: storage-tier: nfs nfs-server: storage-a spec: capacity: storage: 100Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.20 path: /export/appdata mountOptions: - nfsvers=3 - proto=tcp - hard - timeo=600服务器A的logs目录,和appdata共用同一台服务器、同一端口,但path不同:
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-logs labels: storage-tier: nfs nfs-server: storage-a spec: capacity: storage: 50Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.20 path: /export/logs mountOptions: - nfsvers=3 - proto=tcp - hard - timeo=600服务器B的backup目录,这台服务器端口特殊,mountOptions里必须强制指定:
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-backup labels: storage-tier: nfs nfs-server: storage-b spec: capacity: storage: 200Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-static nfs: server: 192.168.10.21 path: /export/backup mountOptions: - nfsvers=3 - proto=tcp - port=3049 - mountport=40001 - hard - timeo=600三个PV放在一起对比,最核心的差异就两点:path的目录不同,以及mountOptions里有没有写上port和mountport。这两个差异如果能一眼看出来并说清楚为什么,多目录多端口配置的基本功就算过关了。
4.3 PVC绑定与Deployment挂载验证
PV建完,接下来是PVC。静态PV和动态供给最大的区别之一,就是PVC要明确绑定到哪个PV。我是通过storageClassName来做绑定的:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-appdata spec: accessModes: - ReadWriteMany resources: requests: storage: 100Gi storageClassName: nfs-static selector: matchLabels: nfs-server: storage-a注意这里的selector,我主动加了一个标签选择器,确保PVC不会绑定到服务器B的PV上。在多目录多端口的环境里,如果不加这个约束,PVC有可能会绑定到你不想绑定的PV上。尤其是当两个PV的storageClassName相同、容量又一样的时候,K8S会认为它们可以互相替代。加了selector之后,绑定关系就明确多了。
Deployment里的挂载配置如下:
apiVersion: apps/v1 kind: Deployment metadata: name: appdata-worker spec: replicas: 1 selector: matchLabels: app: appdata-worker template: metadata: labels: app: appdata-worker spec: containers: - name: app image: nginx:1.27 volumeMounts: - name: appdata-storage mountPath: /data volumes: - name: appdata-storage persistentVolumeClaim: claimName: pvc-appdata创建完这套配置之后,建议用下面的命令做一轮快速巡检:
kubectl get pv kubectl get pvc kubectl get pods -o wide kubectl exec -it appdata-worker-xxxxx -- df -h /datadf -h可以直接看到容器内挂载的文件系统类型和容量。如果能看到NFS相关的挂载信息,说明这条路已经走通了。我当时三个PV全部创建完,逐个验证挂载正常之后,才把业务真实数据迁过去。生产环境里不要省这一步。
5. 挂载失败的完整排查链路:从事件报错反推配置错误
5.1 第一站:kubelet事件里的典型报错翻译
多目录多端口的配置写错,第一反应往往是Pod起不来,一直ContainerCreating。这时候第一件事不是改YAML,而是看事件:
kubectl describe pod <pod-name>事件里的报错信息非常关键,要学会"翻译"。我在实际排查中遇到最多的几类报错和对应原因如下:
mount.nfs: Connection timed out:大概率是端口或者网络不通。优先检查mountOptions里的port是否和服务端实际监听端口一致,再看节点到NFS服务器的网络是否可达、防火墙是否放行。mount.nfs: No such file or directory:服务端导出的路径写错了。这时要去NFS服务端用showmount -e确认到底有哪些导出目录,而不是凭记忆写path。mount.nfs: access denied for <client>...:NFS服务端的/etc/exports里没有放行这个K8S节点的网段或IP,K8S侧再改都没用,必须去服务端加权限。RPC: Port mapper failure - RPC: Unable to receive:rpcbind查询失败。标准端口场景下通常是防火墙挡了111端口;多端口场景下,更直接的办法是在mountOptions里把mountport写死,跳过rpcbind。
事件报错只是入口,真正定位问题还是要往下走。
5.2 第二站:在Node节点手动复现mount命令
K8S的PV挂载动作是由kubelet在工作节点上执行的。所以排查挂载问题的主战场是工作节点,不是控制平面。
我的标准操作是,在报错的事件里找到Pod所在节点,SSH登录上去,先把NFS挂载相关的工具装好:
apt list --installed | grep nfs-common yum list installed | grep nfs-utils如果没装,先装上再继续。然后找一个空目录,手动执行完整的挂载命令:
mkdir -p /mnt/nfs-test mount -t nfs -o nfsvers=3,proto=tcp,port=3049,mountport=40001 192.168.10.21:/export/backup /mnt/nfs-test这一步的妙处在于,它把K8S这层壳完全剥掉了,直接验证NFS服务本身能不能挂。如果这条命令成功,说明NFS服务和K8S配置两端都没问题,问题可能出在PVC绑定或者Pod调度上;如果这条命令就失败,那就不需要去翻K8S文档,老老实实在NFS层面解决。
手动mount成功之后记得umount,别把临时挂载留在节点上。
5.3 第三站:showmount与rpcinfo核对服务端真实暴露
手动mount成功或失败的下一步,是回到服务端,核对"我以为的配置"和"实际的配置"是否一致。
showmount -e用来查看服务端到底导出了哪些目录:
showmount -e 192.168.10.21 Export list for 192.168.10.21: /export/backup 192.168.0.0/16rpcinfo -p用来查看服务端口登记情况:
rpcinfo -p 192.168.10.21 program vers proto port 100003 3 tcp 3049 100003 4 tcp 3049 100005 1 udp 40001 100005 3 tcp 40001100003就是nfsd,100005就是mountd。看到这两个服务的端口之后,再回去检查PV里的mountOptions,基本就能定位是path错误还是port错误。绝大多数多目录多端口配置问题,都会在这一步现出原形。
5.4 那些一次成功之后再挂不上的"玄学"问题
排错排到最后,还会遇到一类让人挠头的场景:明明上一个Pod挂载成功,换了一个Node之后却挂不上;或者同一个Node上,上一次重启前挂得好好的,这次重启后反而不行了。
这类"玄学"问题大多不是玄学,而是环境不一致。几种常见原因:
一是某些Node上没装nfs-common或者nfs-utils。K8S集群的主节点和工作节点可能来自不同的初始化模板,工作节点上缺依赖的情况非常普遍。mount失败的实际原因是"command not found",但kubelet的报错信息并不会直接告诉你这个。建议把NFS客户端工具放进节点的初始化脚本或镜像里,而不是等出问题再装。
二是非标准端口场景下,节点上的防火墙策略不一致。有的节点放行了3049,有的没放行。手动在节点上跑一次mount命令就能复现。
三是mountOptions里写了nfsvers=3但服务端实际只开了v4,或者反过来。这类版本协商问题在标准端口环境不明显,在非标准端口环境下会因为协商失败而挂载不了。
我的应对办法是建立一份"挂载基线文档",把每个PV对应的mountOptions、每个节点的手动挂载验证结果都记录下来。下次再出现"某台Node挂不上"的问题,直接拿基线文档对比,五分钟就能缩小问题范围,而不是在集群里反复describe。
6. 静态PV的适用边界与动态供给的取舍
6.1 静态PV在什么场景下依然是对的
讲到这个程度,有必要说一句公道话:NFS静态PV虽然配置繁琐、扩容要人工介入,但在不少场景下它依然是最合理的选择。
首先是NFS服务由外部存储团队管理的情况。存储权限、目录创建、容量规划、备份策略都在存储团队手里,K8S集群只是"使用者"。这时候动态供给反而难办,因为K8S侧没有权限去任意创建NFS导出目录,或者存储团队不愿意开放自动创建接口给K8S。
其次是数据目录结构和容量诉求非常稳定的场景。比如一个应用从诞生起就明确只需要100Gi的日志空间,半年内没有增长预期,那静态PV一把梭就够了,引入动态供给反而是过度设计。
最后是跨集群共享同一份数据的场景。多个K8S集群要同时读写同一份NFS数据,静态PV天然支持,因为底层的导出目录是固定的、可预期的。
6.2 动态供给接入NFS的关键差异
如果环境允许,动态供给确实省事很多——PVC一申请,底层自动创建目录,不用一个一个去手动建PV。但NFS的动态供给和静态PV在心智模型上是完全不同的:
| 对比项 | 静态PV | 动态供给(以NFS Provisioner为例) |
|---|---|---|
| 目录创建 | 手动在NFS服务端创建 | Provisioner自动创建 |
| 每次分配容量 | 手动规划 | 自动按PVC请求分配 |
| 回收行为 | Retain,手动清理 | 可配置自动删除或保留 |
| 多端口支持 | 每个PV独立mountOptions | 通常依赖服务端标准配置,非标端口适配成本高 |
| 适用场景 | 外部存储团队管理、固定容量 | 存储自助化、弹性扩容需求强 |
这里要特别提醒的是,多端口场景下动态供给通常是给自己找麻烦。动态供给的Provisioner在和NFS服务端交互时,默认假设服务端是标准端口、标准协议,非标端口的适配往往需要改Provisioner的源码或者使用特定的自定义参数,维护成本远高于静态PV里直接写一个mountport。所以我自己的原则是:标准端口环境可以考虑动态供给,非标端口环境老老实实静态PV。
6.3 我的选择逻辑与最终建议
从多次实际项目经验来看,我现在面对"NFS+K8S存储"的需求时,基本会按下面的顺序做决策:
如果外部已经有明确的多目录、多端口要求,优先静态PV,先把目录-端口-容量这张表整理清楚,再逐个建PV。如果存储团队愿意开放自动目录创建的接口,且端口是标准2049,再去评估动态供给。如果两者都不满足,那静态PV这条路虽然繁琐,但至少是可控的。
至于多目录多端口本身,我的核心体会就一句话:这类配置问题的难点从来不是YAML语法,而是你对自己NFS服务端到底暴露了什么、监听在哪个端口、导出哪些目录,有没有一份准确的"档案"。只要这张档案清晰,不管多少目录多少端口,配置起来都只是体力活;档案不清楚,再简单的环境都能挂出各种报错。
我自己后来把这些信息整理成了表格,沉淀在运维文档里。每次新加目录、新加端口、新扩节点,第一件事都是更新这张表,再动K8S配置。事实证明,花在整理信息上的时间,永远不会白费。