简介:这份资源面向需要在 Kubernetes 上部署 Nacos 集群的运维与开发人员,尤其适合刚接触 K8s 编排、希望跳过繁琐配置细节的初学者。它把 Nacos 集群部署拆解为按执行顺序排列的极简 YAML 脚本,覆盖数据库配置、Headless Service、StatefulSet、Service 以及 Ingress 等关键环节,让使用者按编号依次应用即可完成搭建,省去大量手工调试。压缩包共 6 个文件,以 5 个 yaml 清单为主,分别承担数据库连接、无头服务、有状态副本集、服务暴露与外部访问入口等职责,另附 1 个 txt 说明文件,整体仅约 3KB,轻量易读。目前已有 765 人学习下载,说明该方案在同类场景中具备一定参考价值。借助这套脚本,读者可以快速获得一套可复用的 Nacos on K8s 部署模板,理解各资源对象的先后依赖与配置要点,并在此基础上按自身环境调整存储、镜像与域名参数,减少从零编写清单的试错成本。1. 从一份 k8s nacos 集群部署脚本说起:为什么手工搭总翻车如果你正在把 Nacos 往 Kubernetes 上搬,大概率经历过这个场景:照着官方文档一条条kubectl apply,单机模式跑起来了,改成集群模式就各种诡异问题——节点互相发现不了、数据目录权限报错、MySQL 连不上、Pod 一直 CrashLoopBackOff。折腾一下午,最后发现是某个环境变量拼错了,或者 StatefulSet 的 headless service 名字对不上。这份 k8s nacos 集群部署脚本 yaml 就是冲着这个痛点来的:它把 Nacos 集群在 K8s 上跑起来需要的那一堆 Deployment、Service、ConfigMap、PVC 全部打包成可直接套用的 YAML 清单,你改几个参数就能落地。适合两类人:一是刚接触 K8s 但有 Nacos 使用经验的后端或运维,二是想把测试环境 Nacos 从单机迁到集群、又不想从头写编排文件的团队。下面我按实际拆包顺序,把这份资源怎么用、参数怎么调、坑在哪讲透。2. 拆开这份 YAML 包:Nacos 集群在 K8s 上的编排逻辑2.1 为什么 Nacos 集群在 K8s 上要用 StatefulSet 而不是 DeploymentNacos 集群模式的核心是每个节点要有稳定的网络标识和独立的存储。Deployment 起的 Pod 名字是随机后缀,重启后 IP 和主机名都变,Nacos 节点之间靠nacos.member.list或者集群配置文件互相感知,名字一变就掉线。StatefulSet 给每个 Pod 固定序号(nacos-0、nacos-1、nacos-2),配合 headless service 提供稳定的 DNS 记录,节点发现才能稳。这份脚本里 Nacos 用的是 StatefulSet,副本数默认 3。为什么是 3 不是 2?Nacos 集群的 Raft 协议需要奇数节点才能选举,2 个节点在脑裂时无法形成多数派。3 节点是生产最低配,能容忍 1 个节点挂掉。如果你只是测试,1 个节点也能跑,但那就不是集群了,退化成单机模式。存储方面,每个 Nacos Pod 挂一个 PVC,用来存 derby 数据(如果没用外部 MySQL)和日志。脚本里 PVC 的 storageClassName 留了空,你需要根据自己集群的 StorageClass 填。常见做法是用 local-path 或者 nfs-client,云上就用云盘对应的 StorageClass。2.2 集群配置文件与数据库选型:内嵌 derby 还是外接 MySQLNacos 集群模式有两种数据存储方案:内嵌 derby 和外接 MySQL。这份脚本默认走的是外接 MySQL,因为 derby 在集群模式下每个节点各存各的,数据不一致,只适合单机。集群必须用统一的外部数据库。脚本里通过 ConfigMap 挂了一个application.properties,关键几行是:spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://mysql-host:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai db.user.0=nacos db.password.0=nacos这里db.url.0的mysql-host要换成你实际 MySQL 的 service 名或地址。serverTimezone必须设,否则 MySQL 8 会报时区错误。useSSL=false在集群内部通信可以关,省掉证书配置的麻烦。数据库本身需要提前建好nacos_config库,并导入 Nacos 自带的mysql-schema.sql。这个 SQL 文件在 Nacos 发行包的conf目录下,脚本包里一般也会附一份。建表语句大概十几张表,主要是config_info、config_info_beta、his_config_info这些。注意:MySQL 的字符集必须是 utf8mb4,排序规则用 utf8mb4_general_ci。用 utf8 会在存 emoji 或特殊字符时截断,Nacos 配置里如果有这类内容就会丢数据。2.3 环境变量与 JVM 参数:内存怎么分、集群地址怎么写Nacos 容器启动时通过环境变量控制 JVM 和集群行为。脚本里 StatefulSet 的 env 段大概长这样:env: - name: MODE value: "cluster" - name: NACOS_SERVERS value: "nacos-0.nacos-headless.default.svc.cluster.local:8848 nacos-1.nacos-headless.default.svc.cluster.local:8848 nacos-2.nacos-headless.default.svc.cluster.local:8848" - name: JVM_XMS value: "512m" - name: JVM_XMX value: "512m" - name: JVM_XMN value: "256m" - name: MYSQL_SERVICE_HOST value: "mysql-host" - name: MYSQL_SERVICE_PORT value: "3306" - name: MYSQL_SERVICE_DB_NAME value: "nacos_config" - name: MYSQL_SERVICE_USER value: "nacos" - name: MYSQL_SERVICE_PASSWORD value: "nacos"MODE=cluster是必须的,不设就按单机跑。NACOS_SERVERS里每个节点用 headless service 的完整域名,格式是<pod-name>.<service-name>.<namespace>.svc.cluster.local:<port>。namespace 要换成你实际部署的命名空间,脚本里默认是 default。JVM 参数按节点规格调。512m 堆内存适合测试,生产建议 2g 起步。JVM_XMN是新生代大小,一般是 XMX 的 1/2 到 1/4。设太小会导致频繁 Young GC,设太大老年代不够用。我一般按 XMX 的 1/2 设,比如 XMX=2g 就设 XMN=1g。2.4 Service 与 Ingress:客户端怎么访问、控制台怎么暴露脚本里有两个 Service:一个是 headless service(clusterIP: None),给 StatefulSet 内部通信用;另一个是普通 ClusterIP service,给集群内其他服务访问 Nacos 用。如果你要从集群外访问 Nacos 控制台,需要额外配 Ingress 或者 NodePort。headless service 的定义:apiVersion: v1 kind: Service metadata: name: nacos-headless spec: clusterIP: None selector: app: nacos ports: - name: server port: 8848 targetPort: 8848 - name: grpc port: 9848 targetPort: 9848注意 9848 端口。Nacos 2.x 新增了 gRPC 通信端口,是主端口 +1000。如果只开 8848 不开 9848,客户端 2.x 版本连不上,会报Client not connected或者一直重连。这是从 1.x 升 2.x 最容易踩的坑。普通 service 就是把 headless 的 selector 复用,去掉clusterIP: None,给个 ClusterIP。Ingress 部分脚本里可能没带,需要你自己加,指向这个普通 service 的 8848 端口。3. 从零到跑起来:部署步骤与参数调优3.1 前置准备:命名空间、MySQL、StorageClass 三件事在 apply 任何 YAML 之前,先把三样东西准备好。第一,命名空间。脚本里资源都写在 default 下,生产建议单独建一个:kubectl create namespace nacos然后所有 YAML 里的 namespace 字段改成 nacos,或者 apply 时加-n nacos。第二,MySQL。可以用 K8s 里的 MySQL,也可以用外部 RDS。如果用 K8s 里的,先起一个 MySQL StatefulSet 或者用 Helm 装一个。建库和导表:CREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后导入 Nacos 的mysql-schema.sql。导入完检查一下表数量,正常是 12 张左右。第三,StorageClass。查一下集群里有哪些:kubectl get storageclass记下可用的名字,填到 YAML 里 PVC 的storageClassName字段。如果没有 StorageClass,PVC 会一直 Pending,Pod 起不来。3.2 逐条 apply:StatefulSet、Service、ConfigMap 的部署顺序顺序有讲究。先 ConfigMap,再 Service,最后 StatefulSet。因为 StatefulSet 里的 Pod 启动时要挂 ConfigMap,要连 Service 的 DNS,顺序反了会多等几轮重试。# 1. 创建配置 kubectl apply -f nacos-configmap.yaml # 2. 创建 service kubectl apply -f nacos-service.yaml # 3. 创建 statefulset kubectl apply -f nacos-statefulset.yamlapply 完看 Pod 状态:kubectl get pods -l app=nacos -w正常会看到 nacos-0、nacos-1、nacos-2 依次变成 Running。StatefulSet 默认是串行启动,nacos-0 没 Ready 之前不会起 nacos-1。这是为了避免集群初始化时多个节点同时抢主。如果 Pod 一直 Pending,看 Events:kubectl describe pod nacos-0常见原因是 PVC 没绑定,或者资源不够调度。3.3 验证集群状态:日志里看什么、控制台怎么确认Pod 都 Running 之后,先看日志确认集群组建成功:kubectl logs nacos-0 | grep -i "cluster"正常会看到类似Nacos started successfully in cluster mode和Server is STARTED的输出。如果看到java.net.ConnectException或者No route to host,说明节点之间网络不通,检查 headless service 和 NACOS_SERVERS 配置。然后进控制台验证。端口转发一下:kubectl port-forward svc/nacos 8848:8848浏览器打开http://localhost:8848/nacos,默认账号密码都是 nacos。进「集群管理」→「节点列表」,应该看到三个节点,状态都是 UP。如果只看到一个或者有节点是 DOWN,去那个节点的日志里找原因。再验证配置管理功能。新建一个配置,然后在另一个节点上查,能查到说明数据库共享正常。如果查不到,说明数据库配置有问题,或者各节点连的不是同一个库。3.4 资源限制与副本数调整:生产环境怎么配测试环境 512m 堆内存够用,生产要往上调。参考配置:节点规格JVM_XMSJVM_XMXJVM_XMN副本数2C4G1g1g512m34C8G2g2g1g38C16G4g4g2g3 或 5副本数不是越多越好。3 个节点能容忍 1 个挂,5 个能容忍 2 个挂,但节点越多 Raft 选举越慢,配置同步延迟越大。一般 3 个够用,除非有跨机房容灾需求。资源限制在 StatefulSet 的resources段设:resources: requests: memory: "2Gi" cpu: "500m" limits: memory: "4Gi" cpu: "2"requests 是调度依据,limits 是硬上限。JVM 堆内存要小于 limits 的 memory,留出堆外内存和系统开销。比如 limits 设 4Gi,JVM_XMX 最多设 3g,剩下 1g 给 Metaspace、线程栈、Direct Buffer 这些。4. 避坑指南:Nacos on K8s 最常见的五个翻车现场4.1 Pod 一直 CrashLoopBackOff,日志报数据库连接失败现象:Pod 起来几秒就退出,kubectl logs看到Communications link failure或者Access denied for user。原因:MySQL 地址、端口、账号密码配错了,或者 MySQL 还没就绪 Nacos 就启动了。解决:先确认 MySQL 本身能连。在集群里起一个临时 Pod:kubectl run mysql-test --rm -it --image=mysql:8 -- mysql -h mysql-host -u nacos -p能连上再检查 Nacos 的 ConfigMap 里db.url.0的地址是不是写成了localhost。在 K8s 里 localhost 指的是 Pod 自己,不是宿主机,必须写 MySQL 的 service 名或者完整域名。4.2 集群节点列表只显示一个节点现象:控制台集群管理里只有一个节点,其他两个没注册上。原因:NACOS_SERVERS环境变量里的域名解析不了,或者 headless service 没建对。解决:进 Pod 里测 DNS:kubectl exec -it nacos-0 -- nslookup nacos-1.nacos-headless.default.svc.cluster.local如果解析失败,检查 headless service 的 selector 是否匹配 Pod 标签,以及 service 的 namespace 和 Pod 是否一致。另外确认NACOS_SERVERS里的端口是 8848 不是 9848。4.3 客户端 2.x 版本连不上,报 Client not connected现象:应用用 Nacos 2.x 客户端,启动时报Client not connected, current status: STARTING,一直重试。原因:Nacos 2.x 需要 gRPC 端口 9848,Service 或者防火墙没开这个端口。解决:检查 headless service 和普通 service 的 ports 段,确保有 9848 的映射。如果是 NodePort 方式暴露,客户端配置的端口要对应 NodePort,不是 8848。另外 9848 是主端口 +1000,如果你改了主端口,gRPC 端口也要跟着改。4.4 PVC 一直 Pending,Pod 调度不上去现象:kubectl get pvc看到 PVC 状态是 Pending,Pod 也 Pending。原因:没有可用的 StorageClass,或者 StorageClass 的 provisioner 有问题。解决:kubectl get storageclass看有没有默认的。如果没有,装一个 local-path-provisioner 或者 nfs-client-provisioner。如果有但 PVC 还是 Pending,看 provisioner 的 Pod 日志,通常是权限或者网络问题。临时测试可以用hostPath代替 PVC,但不建议生产用。4.5 配置修改后不同节点生效时间不一致现象:在节点 A 改了配置,节点 B 上查还是旧值,等几秒才同步。原因:Nacos 集群间配置同步有延迟,正常现象。但如果延迟超过 10 秒,说明节点间通信有问题。解决:先确认是延迟还是不同步。等 30 秒再查,如果还是旧值,就是真不同步了。检查各节点连的数据库是不是同一个,以及 Raft 状态是否正常。在日志里搜raft关键字,看有没有选举异常。如果某个节点一直选不上主,检查它的系统时间是否和其他节点一致,时间偏差过大会导致 Raft 心跳超时。5. 进阶:用 Helm 管理 Nacos 集群与版本升级的稳妥路径YAML 脚本适合首次部署和理解结构,但长期维护建议上 Helm。Nacos 官方有 Helm chart,社区也有维护版本。用 Helm 的好处是版本升级、参数覆盖、回滚都方便。安装命令大概是这样:helm repo add nacos https://nacos.io/helm helm install nacos nacos/nacos \ --namespace nacos \ --set mode=cluster \ --set replicaCount=3 \ --set database.type=mysql \ --set database.host=mysql-host \ --set database.port=3306 \ --set database.name=nacos_config \ --set database.user=nacos \ --set database.password=nacos升级的时候改 values 再helm upgrade,比手动改 YAML 再 apply 安全。回滚用helm rollback,一条命令回到上个版本。但 Helm 不是银弹。chart 里的模板有时候会覆盖你的自定义配置,尤其是 ConfigMap 部分。我一般会先把 chart 渲染成 YAML 看一眼:helm template nacos nacos/nacos --namespace nacos > rendered.yaml确认渲染结果符合预期再 install。升级前也先helm diff看变更内容,避免意外覆盖。版本升级的稳妥路径:先在小集群验证,确认新版本和你的客户端兼容。Nacos 1.x 升 2.x 要注意 gRPC 端口和客户端版本,2.x 客户端连 1.x 服务端会报错。升级时逐个节点滚动,不要一次性全停。StatefulSet 的podManagementPolicy设成OrderedReady可以保证顺序,但升级会慢一些。设成Parallel快但风险高,生产不建议。从那以后我每次部署 Nacos 集群,都先把 headless service 和 9848 端口检查一遍,再确认 MySQL 字符集是 utf8mb4,最后才 apply StatefulSet。这三步走完,基本不会再遇到 CrashLoop 或者节点注册不上的问题。希望帮到你。本文还有配套的精品资源,点击获取
简介:这份资源面向需要在 Kubernetes 上部署 Nacos 集群的运维与开发人员,尤其适合刚接触 K8s 编排、希望跳过繁琐配置细节的初学者。它把 Nacos 集群部署拆解为按执行顺序排列的极简 YAML 脚本,覆盖数据库配置、Headless Service、StatefulSet、Service 以及 Ingress 等关键环节,让使用者按编号依次应用即可完成搭建,省去大量手工调试。压缩包共 6 个文件,以 5 个 yaml 清单为主,分别承担数据库连接、无头服务、有状态副本集、服务暴露与外部访问入口等职责,另附 1 个 txt 说明文件,整体仅约 3KB,轻量易读。目前已有 765 人学习下载,说明该方案在同类场景中具备一定参考价值。借助这套脚本,读者可以快速获得一套可复用的 Nacos on K8s 部署模板,理解各资源对象的先后依赖与配置要点,并在此基础上按自身环境调整存储、镜像与域名参数,减少从零编写清单的试错成本。1. 从一份 k8s nacos 集群部署脚本说起:为什么手工搭总翻车如果你正在把 Nacos 往 Kubernetes 上搬,大概率经历过这个场景:照着官方文档一条条kubectl apply,单机模式跑起来了,改成集群模式就各种诡异问题——节点互相发现不了、数据目录权限报错、MySQL 连不上、Pod 一直 CrashLoopBackOff。折腾一下午,最后发现是某个环境变量拼错了,或者 StatefulSet 的 headless service 名字对不上。这份 k8s nacos 集群部署脚本 yaml 就是冲着这个痛点来的:它把 Nacos 集群在 K8s 上跑起来需要的那一堆 Deployment、Service、ConfigMap、PVC 全部打包成可直接套用的 YAML 清单,你改几个参数就能落地。适合两类人:一是刚接触 K8s 但有 Nacos 使用经验的后端或运维,二是想把测试环境 Nacos 从单机迁到集群、又不想从头写编排文件的团队。下面我按实际拆包顺序,把这份资源怎么用、参数怎么调、坑在哪讲透。2. 拆开这份 YAML 包:Nacos 集群在 K8s 上的编排逻辑2.1 为什么 Nacos 集群在 K8s 上要用 StatefulSet 而不是 DeploymentNacos 集群模式的核心是每个节点要有稳定的网络标识和独立的存储。Deployment 起的 Pod 名字是随机后缀,重启后 IP 和主机名都变,Nacos 节点之间靠nacos.member.list或者集群配置文件互相感知,名字一变就掉线。StatefulSet 给每个 Pod 固定序号(nacos-0、nacos-1、nacos-2),配合 headless service 提供稳定的 DNS 记录,节点发现才能稳。这份脚本里 Nacos 用的是 StatefulSet,副本数默认 3。为什么是 3 不是 2?Nacos 集群的 Raft 协议需要奇数节点才能选举,2 个节点在脑裂时无法形成多数派。3 节点是生产最低配,能容忍 1 个节点挂掉。如果你只是测试,1 个节点也能跑,但那就不是集群了,退化成单机模式。存储方面,每个 Nacos Pod 挂一个 PVC,用来存 derby 数据(如果没用外部 MySQL)和日志。脚本里 PVC 的 storageClassName 留了空,你需要根据自己集群的 StorageClass 填。常见做法是用 local-path 或者 nfs-client,云上就用云盘对应的 StorageClass。2.2 集群配置文件与数据库选型:内嵌 derby 还是外接 MySQLNacos 集群模式有两种数据存储方案:内嵌 derby 和外接 MySQL。这份脚本默认走的是外接 MySQL,因为 derby 在集群模式下每个节点各存各的,数据不一致,只适合单机。集群必须用统一的外部数据库。脚本里通过 ConfigMap 挂了一个application.properties,关键几行是:spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://mysql-host:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai db.user.0=nacos db.password.0=nacos这里db.url.0的mysql-host要换成你实际 MySQL 的 service 名或地址。serverTimezone必须设,否则 MySQL 8 会报时区错误。useSSL=false在集群内部通信可以关,省掉证书配置的麻烦。数据库本身需要提前建好nacos_config库,并导入 Nacos 自带的mysql-schema.sql。这个 SQL 文件在 Nacos 发行包的conf目录下,脚本包里一般也会附一份。建表语句大概十几张表,主要是config_info、config_info_beta、his_config_info这些。注意:MySQL 的字符集必须是 utf8mb4,排序规则用 utf8mb4_general_ci。用 utf8 会在存 emoji 或特殊字符时截断,Nacos 配置里如果有这类内容就会丢数据。2.3 环境变量与 JVM 参数:内存怎么分、集群地址怎么写Nacos 容器启动时通过环境变量控制 JVM 和集群行为。脚本里 StatefulSet 的 env 段大概长这样:env: - name: MODE value: "cluster" - name: NACOS_SERVERS value: "nacos-0.nacos-headless.default.svc.cluster.local:8848 nacos-1.nacos-headless.default.svc.cluster.local:8848 nacos-2.nacos-headless.default.svc.cluster.local:8848" - name: JVM_XMS value: "512m" - name: JVM_XMX value: "512m" - name: JVM_XMN value: "256m" - name: MYSQL_SERVICE_HOST value: "mysql-host" - name: MYSQL_SERVICE_PORT value: "3306" - name: MYSQL_SERVICE_DB_NAME value: "nacos_config" - name: MYSQL_SERVICE_USER value: "nacos" - name: MYSQL_SERVICE_PASSWORD value: "nacos"MODE=cluster是必须的,不设就按单机跑。NACOS_SERVERS里每个节点用 headless service 的完整域名,格式是<pod-name>.<service-name>.<namespace>.svc.cluster.local:<port>。namespace 要换成你实际部署的命名空间,脚本里默认是 default。JVM 参数按节点规格调。512m 堆内存适合测试,生产建议 2g 起步。JVM_XMN是新生代大小,一般是 XMX 的 1/2 到 1/4。设太小会导致频繁 Young GC,设太大老年代不够用。我一般按 XMX 的 1/2 设,比如 XMX=2g 就设 XMN=1g。2.4 Service 与 Ingress:客户端怎么访问、控制台怎么暴露脚本里有两个 Service:一个是 headless service(clusterIP: None),给 StatefulSet 内部通信用;另一个是普通 ClusterIP service,给集群内其他服务访问 Nacos 用。如果你要从集群外访问 Nacos 控制台,需要额外配 Ingress 或者 NodePort。headless service 的定义:apiVersion: v1 kind: Service metadata: name: nacos-headless spec: clusterIP: None selector: app: nacos ports: - name: server port: 8848 targetPort: 8848 - name: grpc port: 9848 targetPort: 9848注意 9848 端口。Nacos 2.x 新增了 gRPC 通信端口,是主端口 +1000。如果只开 8848 不开 9848,客户端 2.x 版本连不上,会报Client not connected或者一直重连。这是从 1.x 升 2.x 最容易踩的坑。普通 service 就是把 headless 的 selector 复用,去掉clusterIP: None,给个 ClusterIP。Ingress 部分脚本里可能没带,需要你自己加,指向这个普通 service 的 8848 端口。3. 从零到跑起来:部署步骤与参数调优3.1 前置准备:命名空间、MySQL、StorageClass 三件事在 apply 任何 YAML 之前,先把三样东西准备好。第一,命名空间。脚本里资源都写在 default 下,生产建议单独建一个:kubectl create namespace nacos然后所有 YAML 里的 namespace 字段改成 nacos,或者 apply 时加-n nacos。第二,MySQL。可以用 K8s 里的 MySQL,也可以用外部 RDS。如果用 K8s 里的,先起一个 MySQL StatefulSet 或者用 Helm 装一个。建库和导表:CREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后导入 Nacos 的mysql-schema.sql。导入完检查一下表数量,正常是 12 张左右。第三,StorageClass。查一下集群里有哪些:kubectl get storageclass记下可用的名字,填到 YAML 里 PVC 的storageClassName字段。如果没有 StorageClass,PVC 会一直 Pending,Pod 起不来。3.2 逐条 apply:StatefulSet、Service、ConfigMap 的部署顺序顺序有讲究。先 ConfigMap,再 Service,最后 StatefulSet。因为 StatefulSet 里的 Pod 启动时要挂 ConfigMap,要连 Service 的 DNS,顺序反了会多等几轮重试。# 1. 创建配置 kubectl apply -f nacos-configmap.yaml # 2. 创建 service kubectl apply -f nacos-service.yaml # 3. 创建 statefulset kubectl apply -f nacos-statefulset.yamlapply 完看 Pod 状态:kubectl get pods -l app=nacos -w正常会看到 nacos-0、nacos-1、nacos-2 依次变成 Running。StatefulSet 默认是串行启动,nacos-0 没 Ready 之前不会起 nacos-1。这是为了避免集群初始化时多个节点同时抢主。如果 Pod 一直 Pending,看 Events:kubectl describe pod nacos-0常见原因是 PVC 没绑定,或者资源不够调度。3.3 验证集群状态:日志里看什么、控制台怎么确认Pod 都 Running 之后,先看日志确认集群组建成功:kubectl logs nacos-0 | grep -i "cluster"正常会看到类似Nacos started successfully in cluster mode和Server is STARTED的输出。如果看到java.net.ConnectException或者No route to host,说明节点之间网络不通,检查 headless service 和 NACOS_SERVERS 配置。然后进控制台验证。端口转发一下:kubectl port-forward svc/nacos 8848:8848浏览器打开http://localhost:8848/nacos,默认账号密码都是 nacos。进「集群管理」→「节点列表」,应该看到三个节点,状态都是 UP。如果只看到一个或者有节点是 DOWN,去那个节点的日志里找原因。再验证配置管理功能。新建一个配置,然后在另一个节点上查,能查到说明数据库共享正常。如果查不到,说明数据库配置有问题,或者各节点连的不是同一个库。3.4 资源限制与副本数调整:生产环境怎么配测试环境 512m 堆内存够用,生产要往上调。参考配置:节点规格JVM_XMSJVM_XMXJVM_XMN副本数2C4G1g1g512m34C8G2g2g1g38C16G4g4g2g3 或 5副本数不是越多越好。3 个节点能容忍 1 个挂,5 个能容忍 2 个挂,但节点越多 Raft 选举越慢,配置同步延迟越大。一般 3 个够用,除非有跨机房容灾需求。资源限制在 StatefulSet 的resources段设:resources: requests: memory: "2Gi" cpu: "500m" limits: memory: "4Gi" cpu: "2"requests 是调度依据,limits 是硬上限。JVM 堆内存要小于 limits 的 memory,留出堆外内存和系统开销。比如 limits 设 4Gi,JVM_XMX 最多设 3g,剩下 1g 给 Metaspace、线程栈、Direct Buffer 这些。4. 避坑指南:Nacos on K8s 最常见的五个翻车现场4.1 Pod 一直 CrashLoopBackOff,日志报数据库连接失败现象:Pod 起来几秒就退出,kubectl logs看到Communications link failure或者Access denied for user。原因:MySQL 地址、端口、账号密码配错了,或者 MySQL 还没就绪 Nacos 就启动了。解决:先确认 MySQL 本身能连。在集群里起一个临时 Pod:kubectl run mysql-test --rm -it --image=mysql:8 -- mysql -h mysql-host -u nacos -p能连上再检查 Nacos 的 ConfigMap 里db.url.0的地址是不是写成了localhost。在 K8s 里 localhost 指的是 Pod 自己,不是宿主机,必须写 MySQL 的 service 名或者完整域名。4.2 集群节点列表只显示一个节点现象:控制台集群管理里只有一个节点,其他两个没注册上。原因:NACOS_SERVERS环境变量里的域名解析不了,或者 headless service 没建对。解决:进 Pod 里测 DNS:kubectl exec -it nacos-0 -- nslookup nacos-1.nacos-headless.default.svc.cluster.local如果解析失败,检查 headless service 的 selector 是否匹配 Pod 标签,以及 service 的 namespace 和 Pod 是否一致。另外确认NACOS_SERVERS里的端口是 8848 不是 9848。4.3 客户端 2.x 版本连不上,报 Client not connected现象:应用用 Nacos 2.x 客户端,启动时报Client not connected, current status: STARTING,一直重试。原因:Nacos 2.x 需要 gRPC 端口 9848,Service 或者防火墙没开这个端口。解决:检查 headless service 和普通 service 的 ports 段,确保有 9848 的映射。如果是 NodePort 方式暴露,客户端配置的端口要对应 NodePort,不是 8848。另外 9848 是主端口 +1000,如果你改了主端口,gRPC 端口也要跟着改。4.4 PVC 一直 Pending,Pod 调度不上去现象:kubectl get pvc看到 PVC 状态是 Pending,Pod 也 Pending。原因:没有可用的 StorageClass,或者 StorageClass 的 provisioner 有问题。解决:kubectl get storageclass看有没有默认的。如果没有,装一个 local-path-provisioner 或者 nfs-client-provisioner。如果有但 PVC 还是 Pending,看 provisioner 的 Pod 日志,通常是权限或者网络问题。临时测试可以用hostPath代替 PVC,但不建议生产用。4.5 配置修改后不同节点生效时间不一致现象:在节点 A 改了配置,节点 B 上查还是旧值,等几秒才同步。原因:Nacos 集群间配置同步有延迟,正常现象。但如果延迟超过 10 秒,说明节点间通信有问题。解决:先确认是延迟还是不同步。等 30 秒再查,如果还是旧值,就是真不同步了。检查各节点连的数据库是不是同一个,以及 Raft 状态是否正常。在日志里搜raft关键字,看有没有选举异常。如果某个节点一直选不上主,检查它的系统时间是否和其他节点一致,时间偏差过大会导致 Raft 心跳超时。5. 进阶:用 Helm 管理 Nacos 集群与版本升级的稳妥路径YAML 脚本适合首次部署和理解结构,但长期维护建议上 Helm。Nacos 官方有 Helm chart,社区也有维护版本。用 Helm 的好处是版本升级、参数覆盖、回滚都方便。安装命令大概是这样:helm repo add nacos https://nacos.io/helm helm install nacos nacos/nacos \ --namespace nacos \ --set mode=cluster \ --set replicaCount=3 \ --set database.type=mysql \ --set database.host=mysql-host \ --set database.port=3306 \ --set database.name=nacos_config \ --set database.user=nacos \ --set database.password=nacos升级的时候改 values 再helm upgrade,比手动改 YAML 再 apply 安全。回滚用helm rollback,一条命令回到上个版本。但 Helm 不是银弹。chart 里的模板有时候会覆盖你的自定义配置,尤其是 ConfigMap 部分。我一般会先把 chart 渲染成 YAML 看一眼:helm template nacos nacos/nacos --namespace nacos > rendered.yaml确认渲染结果符合预期再 install。升级前也先helm diff看变更内容,避免意外覆盖。版本升级的稳妥路径:先在小集群验证,确认新版本和你的客户端兼容。Nacos 1.x 升 2.x 要注意 gRPC 端口和客户端版本,2.x 客户端连 1.x 服务端会报错。升级时逐个节点滚动,不要一次性全停。StatefulSet 的podManagementPolicy设成OrderedReady可以保证顺序,但升级会慢一些。设成Parallel快但风险高,生产不建议。从那以后我每次部署 Nacos 集群,都先把 headless service 和 9848 端口检查一遍,再确认 MySQL 字符集是 utf8mb4,最后才 apply StatefulSet。这三步走完,基本不会再遇到 CrashLoop 或者节点注册不上的问题。希望帮到你。本文还有配套的精品资源,点击获取