前言,参考知乎的一篇文章在 Rancher 上部署了 Nacos 集群,但前段时间升级到2.4.1时发现集群可以启动成功,客户端服务也并未出现报错,但 Nacos 的服务列表为空,事后发现 Nacos 发布了2.4.2版本,这个版本的描述中刚好说了是2.4.1版本更改了检查服务状态的逻辑。

“Additionally, the logic for checking ServerStatus has been optimized to prevent issues from affecting the availability of non-Raft-dependent functionalities due to Raft election failures.”

以上是版本描述,而我通过升级 2.4.2 也确实解决了上述问题,但除次之外因为上述的不当部署方案导致 Raft 选举失败也要解决下,避免下次再次遇到该问题。

准备环境

  • Rancher(2.5/2.7我用过,其他未用过)
  • Nacos@2.4.1
  • 集群命名空间,本文以example为示例命名空间
  • MySQL 数据库,以及 Nacos 需要的表(目前版本已不再提供默认的用户和角色,需要自己创建)

以下是之前版本提供的默认用户和角色

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

2.4.1也是要测试下是否正确部署成功。

配置文件

准备Nacos要用的配置映射 (Config-Map) ,本文以nacos-config为名。

MODE=cluster
#必须 hostname
PREFER_HOST_MODE=hostname
# 必须用外置数据库,目前仅支持mysql
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=your-mysql-host
MYSQL_SERVICE_PORT=your-mysql-port
MYSQL_SERVICE_DB_NAME=your-database-name
MYSQL_SERVICE_USER=your-database-username
MYSQL_SERVICE_PASSWORD=your-db-password
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
NACOS_AUTH_ENABLE=true
NACOS_AUTH_IDENTITY_KEY=random-string
NACOS_AUTH_IDENTITY_VALUE=base64(random-string)
NACOS_AUTH_TOKEN=base64(random-string)
# 可选,如果初始化数据库时间长可以加上该参数
DB_POOL_CONNECTION_TIMEOUT=60000

去掉注释后全选可以直接复制粘贴这些参数到配置映射的键中,会自动添加新的键值并填充。

开始部署

在 Rancher 集群新增一个工作负载,需要是 Statefulset 类型 (Rancher@2.7需要在 Service 新增一个 Headless 服务,并用选择器指向这个负载) 。

  1. 填写工作负载的名称,此处以nacos-cluster为示例
  2. 部署 3 个 Statefulset Pods。
  3. 填写 Docker 镜像地址
  4. 选择命名空间
  5. 在环境变量中引用准备的 Config-Map nacos-config
  6. 新增环境变量 NACOS_SERVERS
NACOS_SERVERS=nacos-cluster-0.nacos-cluster.example.svc.cluster.local:8848 nacos-cluster-1.nacos-cluster.example.svc.cluster.local:8848 nacos-cluster-2.nacos-cluster.example.svc.cluster.local:8848

值的规则是Pod名.工作负载名.命名空间名.svc.cluster.local:服务端口,我们部署 3 个Pods,则从 0 开始计数,服务地址以空格隔开

NACOS_SERVERS 单独设置是考虑到配置需要根据负载名和Pod名去填写,单独设置会更方便一些。

至于健康检查、数据卷则按需设置。

到此 Nacos 集群也就配置好了,可以准备启动服务了,之后在服务日志中等到输出启动成功的日志就好了(如果没有其他问题的话)。

检查集群

访问 Nacos 的网页控制台,并使用自己创建的账号/密码登录控制台。

集群管理

查看集群管理–>节点列表,查看是否只有三个节点,并且节点都是 UP 状态。如果按照知乎那篇帖子的方案使用指向 Pods 的Headless Services 虽然也可以部署成功,此处也会都是 UP 状态,但会多出一个节点,也就是 Pods 的完整域名,并且每次刷新都会变动,大概就是这个原因会让 Raft 的选举失败。而PREFER_HOST_MODE设置为ip 同样会导致此处多一个节点,节点为三个 Pod 的 IP ,并不断变动。

服务管理

注册几个客户端服务,然后在服务管理–>服务列表查看是否有对应的那几个客户端服务,如果没有则说明部署有误,可以看下F12里的接口返回信息,大概会说明错误信息,然后再去 Nacos 的日志目录下查看日志,进而分析问题。

最后

如果一切符合本文的预期描述,那么恭喜你,你已成功正确的部署了 Nacos 集群。最后就可以把 Nacos 的版本升级到最新版本了(截至本文发布的时间 Nacos 发布到了 2.4.2.1)。

如果你之前在 Rancher 部署过 Nacos 集群,并且有出现问题,那么我建议把原本的负载删掉,原本服务发现里的服务删掉,以及产生的空白服务也删掉(如果删不掉可以通过 API 查看的方式删掉),这主要是解决 Rancher 的缓存问题。经过我的发现解析指向 Pod 的 Headless Service 甚至会用到曾经的工作负载名称,很明显是有缓存的(v2.5是有个这个问题的,v2.7没遇到这个问题)。