一、 Nacos 简介
Nacos(Naming and Configuration Service)是阿里巴巴开源的一个集动态服务发现、配置管理、服务元数据及流量管理于一体的平台。它致力于帮助您构建、交付和管理微服务平台,是构建云原生应用的核心基础设施组件。
核心功能:
-
服务发现与服务健康检查 (Service Discovery):
- 服务注册:微服务启动时,可自动或手动向 Nacos 注册自己的服务实例信息(如 IP、端口、健康状态)。
- 服务发现:消费者服务可以通过 Nacos 查询并订阅所需提供者的实时实例列表,实现客户端负载均衡和故障实例的自动剔除。
- 健康检查:支持基于客户端上报心跳和服务器端主动探测两种模式,确保服务列表的可用性。
-
动态配置管理 (Dynamic Configuration Management):
- 统一管理:将应用程序的配置(如数据库连接、开关参数)从代码中分离,集中存储在 Nacos 服务器。
- 动态刷新:配置变更时,Nacos 能实时通知到所有订阅该配置的微服务实例,实现应用配置的热更新,无需重启。
- 多环境隔离:通过
Data ID、Group、Namespace 等维度,轻松管理开发、测试、生产等多套环境的配置。
-
动态 DNS 服务与元数据管理:
- 支持基于 DNS 协议的服务发现,方便非 Java 生态或容器环境集成。
- 可以管理服务的描述、版本等元数据。
Nacos 2.1.0 的重要改进:
该版本在性能、稳定性和安全性上做了显著提升,例如优化了长连接模型,减少了资源消耗,增强了鉴权体系,是生产环境推荐的稳定版本。
二、 在 Kubernetes 中部署 Nacos 2.1.0 集群的优点
在 Kubernetes 中使用您提供的资源清单部署 Nacos 集群,相比传统虚拟机部署或单机部署,具有以下显著优势:
| 优点 |
说明 |
| 1. 高可用与容灾 |
通过 StatefulSet 部署多个副本(如您配置中的 replicas: 3),形成一个分布式集群。当某个 Pod 故障时,K8s 会自动重启它,而其他节点仍可提供服务,保证了注册中心和配置中心本身的高可用性。 |
| 2. 弹性伸缩 |
可以轻松通过修改 StatefulSet 的 replicas 数量来水平扩展或收缩 Nacos 集群规模,以应对不同的负载压力,操作简单且无需人工干预服务器。 |
| 3. 统一的配置与密码管理 |
使用 ConfigMap 和 Secret(建议将密码移至 Secret)来集中管理 Nacos 的启动配置(如数据库连接信息)。配置变更只需更新 ConfigMap/Secret,并滚动更新 Pod 即可生效,安全且高效。 |
| 4. 服务发现与网络集成 |
利用 K8s 的 Service(特别是 Headless Service)为 Nacos Pod 提供稳定的网络标识(pod-name.headless-svc.namespace.svc.cluster.local)。这完美契合了 Nacos 集群节点间相互发现和通信的需求(如您配置中的 NACOS_SERVERS 列表)。 |
| 5. 简化运维 |
K8s 提供了完整的生命周期管理、健康检查、滚动升级、资源监控和日志收集等能力。部署、升级、回滚 Nacos 集群可以通过声明式 YAML 文件完成,极大降低了运维复杂度。 |
| 6. 资源隔离与调度 |
可以为 Nacos Pod 精确设置 CPU 和内存的请求与限制(resources),避免其占用过多主机资源,并让 K8s 调度器将其分配到合适的节点上。 |
| 7. 对接外部服务灵活 |
通过创建 Service 和 Endpoints 指向外部数据库(如您配置中的 MySQL),完美解决了 K8s 集群内应用访问集群外有状态服务的通用问题,架构清晰。 |
总结:在 Kubernetes 中部署 Nacos 集群,是将这两个云原生核心技术栈深度融合的最佳实践。它使得 Nacos 这一微服务核心组件自身也具备了云原生应用应有的弹性、高可用、易运维的特性,能够为整个微服务体系提供更稳定、可靠的基础服务。您提供的 YAML 配置正是这一实践的标准范例。
前提
在部署之前,你需要准备一个可用的 MySQL 数据库,并执行初始化脚本。
# 创建数据库:nacos_config
CREATE DATABASE `nacos_config` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
# 执行初始化脚本方式随意,导进去就可以
脚本官方地址: https://github.com/alibaba/nacos/blob/develop/distribution/conf/nacos-mysql.sql
初始化SQL
以下为完整的 nacos-mysql.sql 脚本内容,用于在你的 nacos_config 数据库中创建必要的表结构并插入默认管理员用户。
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info */
/******************************************/
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘租户字段’,
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
`encrypted_data_key` text NOT NULL COMMENT ‘秘钥’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’config_info’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘id’,
`data_id` varchar(255) NOT NULL COMMENT ‘data_id’,
`group_id` varchar(255) NOT NULL COMMENT ‘group_id’,
`datum_id` varchar(255) NOT NULL COMMENT ‘datum_id’,
`content` longtext NOT NULL COMMENT ‘内容’,
`gmt_modified` datetime NOT NULL COMMENT ‘修改时间’,
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘租户字段’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’增加租户字段’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘id’,
`data_id` varchar(255) NOT NULL COMMENT ‘data_id’,
`group_id` varchar(128) NOT NULL COMMENT ‘group_id’,
`app_name` varchar(128) DEFAULT NULL COMMENT ‘app_name’,
`content` longtext NOT NULL COMMENT ‘content’,
`beta_ips` varchar(1024) DEFAULT NULL COMMENT ‘betaIps’,
`md5` varchar(32) DEFAULT NULL COMMENT ‘md5’,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
`src_user` text COMMENT ‘source user’,
`src_ip` varchar(50) DEFAULT NULL COMMENT ‘source ip’,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘租户字段’,
`encrypted_data_key` text NOT NULL COMMENT ‘秘钥’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’config_info_beta’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘id’,
`data_id` varchar(255) NOT NULL COMMENT ‘data_id’,
`group_id` varchar(128) NOT NULL COMMENT ‘group_id’,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘tenant_id’,
`tag_id` varchar(128) NOT NULL COMMENT ‘tag_id’,
`app_name` varchar(128) DEFAULT NULL COMMENT ‘app_name’,
`content` longtext NOT NULL COMMENT ‘content’,
`md5` varchar(32) DEFAULT NULL COMMENT ‘md5’,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
`src_user` text COMMENT ‘source user’,
`src_ip` varchar(50) DEFAULT NULL COMMENT ‘source ip’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’config_info_tag’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT ‘id’,
`tag_name` varchar(128) NOT NULL COMMENT ‘tag_name’,
`tag_type` varchar(64) DEFAULT NULL COMMENT ‘tag_type’,
`data_id` varchar(255) NOT NULL COMMENT ‘data_id’,
`group_id` varchar(128) NOT NULL COMMENT ‘group_id’,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘tenant_id’,
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’config_tag_relation’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘主键ID’,
`group_id` varchar(128) NOT NULL DEFAULT ’’ COMMENT ‘Group ID,空字符表示整个集群’,
`quota` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘配额,0表示使用默认值’,
`usage` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘使用量’,
`max_size` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘单个配置大小上限,单位为字节,0表示使用默认值’,
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘聚合子配置最大个数,,0表示使用默认值’,
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值’,
`max_history_count` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘最大变更历史数量’,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’集群、各Group容量信息表’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(20) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT ‘app_name’,
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT ’’ COMMENT ‘租户字段’,
`encrypted_data_key` text NOT NULL COMMENT ‘秘钥’,
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’多租户改造’;
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘主键ID’,
`tenant_id` varchar(128) NOT NULL DEFAULT ’’ COMMENT ‘Tenant ID’,
`quota` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘配额,0表示使用默认值’,
`usage` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘使用量’,
`max_size` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘单个配置大小上限,单位为字节,0表示使用默认值’,
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘聚合子配置最大个数’,
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值’,
`max_history_count` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘最大变更历史数量’,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’租户容量信息表’;
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘id’,
`kp` varchar(128) NOT NULL COMMENT ‘kp’,
`tenant_id` varchar(128) default ’’ COMMENT ‘tenant_id’,
`tenant_name` varchar(128) default ’’ COMMENT ‘tenant_name’,
`tenant_desc` varchar(256) DEFAULT NULL COMMENT ‘tenant_desc’,
`create_source` varchar(32) DEFAULT NULL COMMENT ‘create_source’,
`gmt_create` bigint(20) NOT NULL COMMENT ‘创建时间’,
`gmt_modified` bigint(20) NOT NULL COMMENT ‘修改时间’,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=’tenant_info’;
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES (‘nacos’, ‘$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu’, TRUE);
INSERT INTO roles (username, role) VALUES (‘nacos’, ‘ROLE_ADMIN’);
K8s资源清单
这是核心的 Kubernetes 部署清单文件,它将创建一个三节点的 Nacos 集群,并使用外部 MySQL 作为数据源。请将文件保存为 nacos-cluster.yaml。
kind: Service
apiVersion: v1
metadata:
name: mysql-nacos #保持与下面endpoint的metadata.name一致
labels:
name: mysql-nacos #保持与下面endpoint的metadata.labels.name一致
spec:
clusterIP: None
ports:
- port: 3306 # 数据库端口
name: mysql-nacos #这名字理论上随意
targetPort: 3306 # 数据库端口
---
kind: Endpoints
apiVersion: v1
metadata:
name: mysql-nacos
labels:
name: mysql-nacos
subsets:
- addresses:
- ip: 211.159.215.252 # 这里是数据库的ip地址
ports:
- port: 3306 # 数据库端口
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
labels:
app: nacos-headless
spec:
type: ClusterIP
clusterIP: None
ports:
- port: 8848
name: server
targetPort: 8848
- port: 9848
name: client-rpc
targetPort: 9848
- port: 9849
name: raft-rpc
targetPort: 9849
## 兼容1.4.x版本的选举端口
- port: 7848
name: old-raft-rpc
targetPort: 7848
selector:
app: nacos
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-cm #这里下面会用到
data:
mysql.service.name: “mysql-nacos” #增加数据库地址变量,这里填写第二步创建的service名字.
mysql.db.name: “nacos_config” #数据库名字
mysql.port: “3306” #数据库端口
mysql.user: “root” #数据库用户名
mysql.password: “deanit.cn” #数据库密码
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
spec:
serviceName: nacos-headless
replicas: 3
template:
metadata:
labels:
app: nacos
annotations:
pod.alpha.kubernetes.io/initialized: “true”
spec:
# affinity:
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchExpressions:
# - key: "app"
# operator: In
# values:
# - nacos
# topologyKey: “kubernetes.io/hostname”
containers:
- name: k8snacos
image: “nacos/nacos-server:latest”
resources:
requests:
memory: “2Gi”
cpu: “500m”
ports:
- containerPort: 8848
name: client
- containerPort: 9848
name: client-rpc
- containerPort: 9849
name: raft-rpc
- containerPort: 7848
name: old-raft-rpc
env:
- name: NACOS_REPLICAS
value: “3”
- name: MYSQL_SERVICE_HOST #添加的数据库地址环境变量,无需修改.
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.service.name
- name: MYSQL_SERVICE_DB_NAME
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.db.name
- name: MYSQL_SERVICE_PORT
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.port
- name: MYSQL_SERVICE_USER
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.user
- name: MYSQL_SERVICE_PASSWORD
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.password
- name: NACOS_SERVER_PORT
value: “8848”
- name: NACOS_APPLICATION_PORT
value: “8848”
- name: PREFER_HOST_MODE
value: “hostname”
- 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” #这里中间的default,需要根据实际的命名空间修改,默认default命名空间
selector:
matchLabels:
app: nacos
---
apiVersion: v1
kind: Service
metadata:
name: nacos
labels:
app: nacos
spec:
selector:
app: nacos
externalTrafficPolicy: Cluster
ports:
- name: nacos-service-0
targetPort: 8848
nodePort: 30000
port: 8848
protocol: TCP
type: NodePort
部署步骤:
- 修改清单中的关键配置:
- 数据库 IP:在
Endpoints 资源中,将 ip: 211.159.215.252 替换为你实际的 MySQL 服务器 IP。
- 数据库密码:在
ConfigMap 资源中,将 mysql.password: “deanit.cn” 替换为你的数据库密码。
- 命名空间:如果你不在
default 命名空间部署,请将 StatefulSet 中 NACOS_SERVERS 环境变量里的 default 替换为你的命名空间名称。
- 执行部署命令:
kubectl apply -f nacos-cluster.yaml
- 检查部署状态:
kubectl get pods -l app=nacos
kubectl get svc nacos # 查看 NodePort 端口,默认为 30000
Web访问Nacos
部署成功后,即可通过以下地址访问 Nacos 控制台。
http://<你的K8s节点IP>:30000
账号:nacos
密码:nacos
结语
通过以上步骤,你已经成功在 Kubernetes 中部署了一个高可用的 Nacos 2.1.0 集群。这种部署方式充分利用了 Kubernetes 在编排、网络和服务发现方面的优势,使 Nacos 的运维管理变得更加简单和可靠。如果你在实践过程中遇到问题,或者想深入探讨更多关于配置管理和云原生的最佳实践,欢迎在 云栈社区 与大家交流讨论。
