Kubernetes 环境下如何部署 Nacos 集群实现高可用服务发现?

文章导读
在 Kubernetes 中部署 Nacos 集群实现高可用,核心在于使用 StatefulSet 保证节点身份稳定,外接 MySQL 持久化配置,并正确配置 K8s 服务发现端口。
📋 目录
  1. 前置准备
  2. 核心资源配置
  3. 验证部署结果
  4. 常见故障排查
  5. 参考来源
A A

在 Kubernetes 中部署 Nacos 集群实现高可用,核心在于使用 StatefulSet 保证节点身份稳定,外接 MySQL 持久化配置,并正确配置 K8s 服务发现端口。

先说结论:生产环境建议使用至少 3 个节点组建集群,必须外接数据库,且需注意 Nacos 2.x 版本的端口变化。

  • 适合:对服务发现可靠性有要求的生产环境
  • 先准备:独立 MySQL 实例、持久化存储类(StorageClass)
  • 验收:检查集群节点状态、注册服务心跳及配置读写

前置准备

1. 数据库初始化:下载 Nacos 官方提供的 MySQL 脚本 nacos-mysql.sql 并在独立 MySQL 实例中执行,创建数据库 nacos_config 及相关表。

2. 存储类检查:确认集群存在可用的 StorageClass,执行 kubectl get sc 查看。若无,需先配置持久化存储。

Kubernetes 环境下如何部署 Nacos 集群实现高可用服务发现?

核心资源配置

以下 YAML 基于 Nacos 2.x 版本设计,包含 ConfigMap、Service 和 StatefulSet。请根据实际环境修改数据库密码及存储类名称。

1. 配置 ConfigMap

虽然支持动态发现,但建议保留基础配置。注意:在 K8s 中更推荐通过环境变量 NACOS_SERVERS 指定节点列表,避免手动维护文件。

Kubernetes 环境下如何部署 Nacos 集群实现高可用服务发现?
apiVersion: v1
kind: ConfigMap
metadata:
  name: nacos-config
data:
  cluster.conf: |
    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
  application.properties: |
    db.num=1
    db.url.0=jdbc:mysql://mysql-host:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=nacos
    db.password=nacos

2. 创建 Service

需要两个 Service:一个 Headless Service 用于 StatefulSet 内部域名解析,一个 ClusterIP 用于外部访问。

apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
spec:
  clusterIP: None
  selector:
    app: nacos
  ports:
    - name: server
      port: 8848
      targetPort: 8848
    - name: client-rpc
      port: 9848
      targetPort: 9848
    - name: raft-rpc
      port: 9849
      targetPort: 9849
---
apiVersion: v1
kind: Service
metadata:
  name: nacos-client
spec:
  type: ClusterIP
  selector:
    app: nacos
  ports:
    - name: server
      port: 8848
      targetPort: 8848
    - name: client-rpc
      port: 9848
      targetPort: 9848

3. 部署 StatefulSet

重点配置环境变量、资源限制及持久化存储。注意 Nacos 2.x 需暴露 9848 和 9849 端口。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
spec:
  serviceName: nacos-headless
  replicas: 3
  selector:
    matchLabels:
      app: nacos
  template:
    metadata:
      labels:
        app: nacos
    spec:
      containers:
        - name: nacos
          image: nacos/nacos-server:2.2.0
          resources:
            requests:
              memory: "1Gi"
              cpu: "500m"
            limits:
              memory: "2Gi"
              cpu: "1000m"
          ports:
            - containerPort: 8848
              name: server
            - containerPort: 9848
              name: client-rpc
            - containerPort: 9849
              name: raft-rpc
          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: MYSQL_SERVICE_HOST
              value: "mysql-host"
            - name: MYSQL_SERVICE_DB_NAME
              value: "nacos_config"
            - name: MYSQL_SERVICE_USER
              value: "nacos"
            - name: MYSQL_SERVICE_PASSWORD
              value: "nacos"
            - name: SPRING_DATASOURCE_PLATFORM
              value: "mysql"
          volumeMounts:
            - name: data
              mountPath: /home/nacos/data
            - name: config
              mountPath: /home/nacos/conf/cluster.conf
              subPath: cluster.conf
      volumes:
        - name: config
          configMap:
            name: nacos-config
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: "your-storage-class"
        resources:
          requests:
            storage: 10Gi

验证部署结果

应用配置后,执行以下命令验证:

# 1. 检查 Pod 状态,确保 3 个节点均为 Running
kubectl get pods -l app=nacos

# 2. 查看日志确认无启动报错
kubectl logs -f nacos-0

# 3. 检查集群健康状态 (替换为实际 Service IP)
curl http://<nacos-service-ip>:8848/nacos/actuator/health

# 4. 查看集群节点列表
curl http://<nacos-service-ip>:8848/nacos/v1/ns/operator/cluster/nodes

常见故障排查

  • 客户端连接失败:Nacos 2.x 使用 gRPC 通信,若防火墙或 SecurityGroup 未开放 9848 和 9849 端口,SDK 会报错。请确保 Service 中映射了这两个端口。
  • 节点状态异常:检查 NACOS_SERVERS 环境变量中的域名是否能在 Pod 内解析。可使用 kubectl exec -it nacos-0 -- ping nacos-1.nacos-headless 测试连通性。
  • 数据库连接错误:确认 MySQL 允许远程连接,且账号密码正确。检查 Pod 日志中是否有 Communications link failure
  • PVC Pending:若 Pod 无法启动,检查 kubectl get pvc。通常是因为 storageClassName 填写错误或不匹配集群现有存储类。

参考来源

  • Nacos 官方文档 - 集群部署指南:https://nacos.io/zh-cn/docs/cluster-setup-1.4.0.html
  • Nacos GitHub - K8s 部署示例:https://github.com/alibaba/nacos/tree/develop/deployment/k8s
  • Nacos 官方文档 - 2.0 兼容性说明:https://nacos.io/zh-cn/docs/2.0.0-compatibility.html