侧边栏壁纸
  • 累计撰写 49 篇文章
  • 累计创建 33 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Nacos 3.2.1 生产级高可用集群部署指南 (Kubernetes)

Angus
2026-07-13 / 0 评论 / 0 点赞 / 2 阅读 / 6810 字

本文档描述了在 Kubernetes 环境下部署 Nacos 3.2.1 高可用集群的最佳实践。集群采用 StatefulSet + Headless Service 架构,并已解决 JVM OOM、端口冲突及跨节点调度等常见问题。

一、 部署前置准备

1. 数据库初始化

Nacos 3.x 在集群模式下不支持自动建表。在部署应用前,必须手动初始化 MySQL 数据库。

  1. 在你的 MySQL 服务器上创建数据库:
   CREATE DATABASE nacos DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  1. 获取 Nacos 3.2.1 官方 SQL 脚本,并在上述库中完整执行。
kubectl exec -it nacos-0 -n atai-ops -- cat /home/nacos/conf/mysql-schema.sql > nacos-3.2.1-init.sql
  1. 确保配置给 Nacos 容器的数据库账号拥有读写权限。

2. K8s 节点要求

为了保证真正的 Raft 高可用,当前 YAML 配置了硬性 Pod 反亲和性(Anti-Affinity)

  • 要求: Kubernetes 集群中必须至少有 3 个 可用的 Worker 节点,否则 Pod 会因为无法满足分散调度条件而处于 Pending 状态。
  • (如果测试环境节点不足,请将下方 YAML 中的 requiredDuringSchedulingIgnoredDuringExecution 修改为 preferredDuringSchedulingIgnoredDuringExecution)。

二、 核心部署脚本

将以下内容保存为 nacos-cluster.yaml

注意: 部署前,请将 ConfigMap 中的 <your-mysql-host><your-db-user><your-db-password> 替换为真实的数据库连接信息。

# 1. 命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: atai-ops

---
# 2. ConfigMap (Nacos 核心配置)
apiVersion: v1
kind: ConfigMap
metadata:
  name: nacos-cm
  namespace: atai-ops
data:
  application.properties: |
    # UI 控制台上下文路径 (注意: Nacos 3.x 千万不要在这里配置 server.port,会引发内部 Tomcat 端口冲突)
    server.servlet.contextPath=/nacos
    
    # 鉴权配置
    nacos.core.auth.enabled=true
    nacos.core.auth.server.identity.key=serverIdKey
    nacos.core.auth.server.identity.value=inner-server-node-2024-secure-cluster-id
    nacos.core.auth.plugin.nacos.token.secret.key=R2s3I21QOXhMMiR2TjVxVzhqUjQhVDZ5QjNjRTBmSDEza1M5dU8yJA==
    
    # 外部 MySQL 数据源配置
    spring.sql.init.platform=mysql
    db.num=1
    db.url.0=jdbc:mysql://<your-mysql-host>:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=<your-db-user>
    db.password.0=<your-db-password>
    
    # 开启 Prometheus 监控指标
    management.endpoints.web.exposure.include=*

---
# 3. Headless Service (集群节点内部通信与自动发现)
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  namespace: atai-ops
  labels:
    app: nacos
spec:
  type: ClusterIP
  clusterIP: None
  ports:
    - port: 8848
      name: client
    - port: 9848
      name: client-rpc
    - port: 9849
      name: raft-rpc
  selector:
    app: nacos

---
# 4. NodePort Service (对外暴露 API 与 UI 控制台)
apiVersion: v1
kind: Service
metadata:
  name: nacos-service
  namespace: atai-ops
  labels:
    app: nacos
spec:
  type: NodePort
  selector:
    app: nacos
  ports:
    - name: client
      port: 8848
      targetPort: 8848
    - name: client-rpc
      port: 9848
      targetPort: 9848
    - name: console
      port: 8080
      targetPort: 8080

---
# 5. StatefulSet (Nacos 3 节点集群控制器)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
  namespace: atai-ops
spec:
  serviceName: nacos-headless
  replicas: 3
  selector:
    matchLabels:
      app: nacos
  template:
    metadata:
      labels:
        app: nacos
    spec:
      # Pod 反亲和性:强制 3 个节点调度到不同的宿主机,保证物理高可用
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nacos
            topologyKey: "kubernetes.io/hostname"
      containers:
        - name: nacos
          image: nacos/nacos-server:v3.2.1
          imagePullPolicy: IfNotPresent
          
          # 资源限制:Limits 内存必须大于 JVM 的 Xmx 至少 50%,防止被 K8s OOMKill
          resources:
            requests:
              cpu: "500m"
              memory: "1Gi"
            limits:
              cpu: "2"
              memory: "2Gi"
              
          ports:
            - containerPort: 8848
              name: client
            - containerPort: 9848
              name: client-rpc
            - containerPort: 9849
              name: raft-rpc
            - containerPort: 8080
              name: console
              
          env:
            - name: MODE
              value: "cluster"
            # 利用 K8s DNS 域名配置集群节点,镜像启动时自动渲染到 cluster.conf
            - name: NACOS_SERVERS
              value: "nacos-0.nacos-headless.atai-ops.svc.cluster.local:8848 nacos-1.nacos-headless.atai-ops.svc.cluster.local:8848 nacos-2.nacos-headless.atai-ops.svc.cluster.local:8848"
            
            # 安全鉴权环境变量 (必须在此处注入,否则 Docker 启动脚本会校验失败(exit 255))
            - name: NACOS_AUTH_TOKEN
              value: "R2s3I21QOXhMMiR2TjVxVzhqUjQhVDZ5QjNjRTBmSDEza1M5dU8yJA=="
            - name: NACOS_AUTH_IDENTITY_KEY
              value: "serverIdKey"
            - name: NACOS_AUTH_IDENTITY_VALUE
              value: "inner-server-node-2024-secure-cluster-id"
              
            # JVM 内存参数配置 (保守配置,为容器堆外内存留出空间)
            - name: JVM_XMS
              value: "512m"
            - name: JVM_XMX
              value: "512m"
            - name: JVM_XMN
              value: "256m"
              
          volumeMounts:
            - name: config-volume
              mountPath: /home/nacos/conf/application.properties
              subPath: application.properties
      volumes:
        - name: config-volume
          configMap:
            name: nacos-cm

三、 部署与验证

  1. 执行部署命令:
kubectl apply -f nacos-cluster.yaml

  1. 观察 Pod 启动状态:
kubectl get pods -n atai-ops -w

等待 nacos-0nacos-1nacos-2 的状态全部变为 Running。 3. 获取对外暴露的端口:

kubectl get svc nacos-service -n atai-ops

找到 8080 对应的 NodePort 端口(例如 32055)。 4. 访问控制台 在浏览器中输入:

http://<任意K8s节点IP>:<映射的8080_NodePort>/nacos

登录成功后,进入 集群管理 -> 节点列表,确认 3 个节点均处于 UP 状态,即代表集群部署成功!

0

评论区