在Kubernetes上构建生产级Nacos集群:从NFS持久化到Ingress暴露的完整实践

张开发
2026/4/16 14:24:49 15 分钟阅读

分享文章

在Kubernetes上构建生产级Nacos集群:从NFS持久化到Ingress暴露的完整实践
1. 为什么要在Kubernetes上部署Nacos集群在微服务架构中服务发现和配置管理是两大核心需求。Nacos作为阿里巴巴开源的服务发现和配置管理平台已经成为云原生时代的重要基础设施。但在生产环境中单节点部署的Nacos存在单点故障风险无法满足高可用要求。这就是为什么我们需要在Kubernetes上构建Nacos集群。我曾在多个生产环境中部署过Nacos集群发现Kubernetes提供了几个关键优势。首先Kubernetes的StatefulSet能够完美支持Nacos这种有状态服务的部署确保每个Pod都有稳定的网络标识和持久化存储。其次Kubernetes的自动恢复机制可以保证Nacos节点在故障时快速重启。最重要的是Kubernetes的横向扩展能力让我们可以根据业务需求轻松调整Nacos集群规模。举个例子去年我们一个电商项目在双11大促期间由于配置变更频繁单节点Nacos完全扛不住压力。后来迁移到Kubernetes集群后不仅性能提升了3倍还实现了零宕机的平滑升级。2. 准备工作与环境配置2.1 基础环境要求在开始部署前我们需要确保Kubernetes集群已经就绪。我建议使用至少3个节点的集群每个节点配置不低于4核8G。以下是具体检查清单# 检查Kubernetes集群状态 kubectl get nodes # 检查存储插件是否安装 kubectl get storageclass # 检查网络插件是否正常 kubectl get pods -n kube-system2.2 NFS服务部署Nacos作为有状态服务数据持久化是必须的。我测试过多种存储方案最终发现NFS是最适合生产环境的方案。下面是NFS服务器的部署步骤# 在NFS服务器上执行 yum install -y nfs-utils rpcbind mkdir -p /data/nfs echo /data/nfs *(insecure,rw,async,no_root_squash) /etc/exports exportfs -r systemctl start rpcbind systemctl start nfs在Kubernetes集群中我们需要部署NFS客户端插件。这个插件会自动帮我们管理PV和PVC的创建# nfs-client-provisioner.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccount: nfs-client-provisioner containers: - name: nfs-client-provisioner image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: your-nfs-server-ip - name: NFS_PATH value: /data/nfs volumes: - name: nfs-client-root nfs: server: your-nfs-server-ip path: /data/nfs3. MySQL数据库部署与配置3.1 部署MySQL集群Nacos支持多种数据库但在生产环境中我强烈推荐使用MySQL。下面是在Kubernetes中部署MySQL的配置# mysql-nfs.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: serviceName: mysql replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: your-strong-password - name: MYSQL_DATABASE value: nacos_config - name: MYSQL_USER value: nacos - name: MYSQL_PASSWORD value: nacos volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ ReadWriteOnce ] storageClassName: managed-nfs-storage resources: requests: storage: 10Gi3.2 初始化Nacos数据库MySQL部署完成后我们需要初始化Nacos所需的表结构。可以从Nacos官方GitHub仓库获取SQL脚本# 获取建表语句 wget https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/nacos-mysql.sql # 导入数据库 kubectl exec -it mysql-0 -- mysql -uroot -p your-strong-password nacos_config nacos-mysql.sql4. Nacos集群部署实战4.1 StatefulSet配置详解Nacos集群的核心是StatefulSet配置。下面是我在生产环境中经过验证的配置# nacos-statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: nacos spec: serviceName: nacos-headless replicas: 3 selector: matchLabels: app: nacos template: metadata: labels: app: nacos spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nacos topologyKey: kubernetes.io/hostname containers: - name: nacos image: nacos/nacos-server:2.0.3 ports: - containerPort: 8848 name: client - containerPort: 7848 name: raft 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.default.svc.cluster.local - name: MYSQL_SERVICE_DB_NAME value: nacos_config - name: MYSQL_SERVICE_USER value: nacos - name: MYSQL_SERVICE_PASSWORD value: nacos volumeMounts: - name: config mountPath: /home/nacos/conf volumeClaimTemplates: - metadata: name: config spec: accessModes: [ ReadWriteMany ] storageClassName: managed-nfs-storage resources: requests: storage: 5Gi4.2 服务暴露与健康检查部署完成后我们需要通过Headless Service和Ingress来暴露Nacos服务# nacos-service.yaml apiVersion: v1 kind: Service metadata: name: nacos-headless labels: app: nacos spec: ports: - port: 8848 name: server clusterIP: None selector: app: nacos # nacos-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nacos-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: nacos.yourdomain.com http: paths: - path: /nacos(/|$)(.*) pathType: Prefix backend: service: name: nacos-headless port: number: 88485. 生产环境优化与运维5.1 监控与告警配置在生产环境中我们需要对Nacos集群进行全方位监控。这是我常用的Prometheus监控配置# nacos-monitor.yaml apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: nacos-monitor spec: selector: matchLabels: app: nacos endpoints: - port: server path: /nacos/actuator/prometheus namespaceSelector: matchNames: - default5.2 备份与恢复策略Nacos配置数据的备份至关重要。我通常会设置定期备份任务# 备份脚本示例 #!/bin/bash DATE$(date %Y%m%d) kubectl exec mysql-0 -- mysqldump -uroot -p$MYSQL_ROOT_PASSWORD nacos_config nacos_backup_$DATE.sql5.3 性能调优经验根据我的实战经验以下参数对Nacos性能影响最大JVM堆内存设置建议不低于4GB数据库连接池配置建议使用HikariCP集群通信超时设置适当延长raft协议超时时间# JVM参数示例 env: - name: JVM_XMS value: 2g - name: JVM_XMX value: 2g - name: NACOS_SERVER_IP valueFrom: fieldRef: fieldPath: status.podIP6. 常见问题排查指南在实际部署过程中我遇到过各种问题。以下是几个典型问题的解决方案问题1Nacos节点无法组成集群检查点确保DNS解析正常检查网络策略是否允许Pod间通信验证NACOS_SERVERS环境变量配置正确问题2配置变更不生效检查点确认MySQL连接正常检查Nacos日志是否有异常验证客户端使用的命名空间和分组是否正确问题3Ingress访问返回404检查点检查Ingress Controller日志验证Service端口映射是否正确检查Nacos Pod是否健康7. 最佳实践与经验分享经过多个项目的实践我总结出以下最佳实践集群规模3节点是最小生产配置5节点适合大型系统存储选择NFS适合大多数场景性能要求高的可以考虑Ceph升级策略采用滚动更新确保至少2个节点始终可用客户端配置建议使用DNS名称而非IP地址访问集群一个真实的案例在某金融项目中我们最初使用默认配置结果在业务高峰期出现了配置同步延迟。通过调整raft协议的选举超时时间和增加JVM堆内存最终将同步时间从秒级降低到毫秒级。

更多文章