
简介这份资源面向需要在 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 不是 2Nacos 集群的 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.platformmysql db.num1 db.url.0jdbc:mysql://mysql-host:3306/nacos_config?characterEncodingutf8connectTimeout1000socketTimeout3000autoReconnecttrueuseUnicodetrueuseSSLfalseserverTimezoneAsia/Shanghai db.user.0nacos db.password.0nacos这里db.url.0的mysql-host要换成你实际 MySQL 的 service 名或地址。serverTimezone必须设否则 MySQL 8 会报时区错误。useSSLfalse在集群内部通信可以关省掉证书配置的麻烦。数据库本身需要提前建好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: nacosMODEcluster是必须的不设就按单机跑。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 设比如 XMX2g 就设 XMN1g。2.4 Service 与 Ingress客户端怎么访问、控制台怎么暴露脚本里有两个 Service一个是 headless serviceclusterIP: 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字段。如果没有 StorageClassPVC 会一直 PendingPod 起不来。3.2 逐条 applyStatefulSet、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 appnacos -w正常会看到 nacos-0、nacos-1、nacos-2 依次变成 Running。StatefulSet 默认是串行启动nacos-0 没 Ready 之前不会起 nacos-1。这是为了避免集群初始化时多个节点同时抢主。如果 Pod 一直 Pending看 Eventskubectl 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: 2requests 是调度依据limits 是硬上限。JVM 堆内存要小于 limits 的 memory留出堆外内存和系统开销。比如 limits 设 4GiJVM_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 本身能连。在集群里起一个临时 Podkubectl run mysql-test --rm -it --imagemysql: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 里测 DNSkubectl 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 端口 9848Service 或者防火墙没开这个端口。解决检查 headless service 和普通 service 的 ports 段确保有 9848 的映射。如果是 NodePort 方式暴露客户端配置的端口要对应 NodePort不是 8848。另外 9848 是主端口 1000如果你改了主端口gRPC 端口也要跟着改。4.4 PVC 一直 PendingPod 调度不上去现象kubectl get pvc看到 PVC 状态是 PendingPod 也 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 modecluster \ --set replicaCount3 \ --set database.typemysql \ --set database.hostmysql-host \ --set database.port3306 \ --set database.namenacos_config \ --set database.usernacos \ --set database.passwordnacos升级的时候改 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 或者节点注册不上的问题。希望帮到你。本文还有配套的精品资源点击获取