Nacos 注册中心开发随笔

更改密码

Nacos 开启认证功能后,登录的默认用户名和密码是 nacos / nacos,为了系统安全,建议更改登录密码。

  • 引入依赖
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • 通过 BCryptPasswordEncoder 类生成新的密码,注意盐值是随机的,所以生成的密码每次都可能不一样,请不要担心
1
2
3
4
5
6
7
8
9
10
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordEncoderUtil {

public static void main(String[] args) {
// 每次生成的密码都可能不一样
System.out.println(new BCryptPasswordEncoder().encode("newPassword"));
}

}
  • 更改 Nacos 的 users 表,指定新的密码

  • 若需要更改用户名称(比如 admin),则更改完用户名称之后,还需要往 roles 表中添加用户角色关联记录,如下图所示:

  • 若需要添加新的 Nacos 用户,可以参考以下 SQL 语句
1
2
INSERT INTO users (username, password, enabled) VALUES ('administrator', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('administrator', 'ROLE_ADMIN');

配置 JVM

配置参数

JVM 参数说明
JVM_XMS=512m-Xms - JVM 启动时分配的堆内存大小
JVM_XMX=512m-Xmx - JVM 运行过程中分配的最大堆内存大小
JVM_XMN=256m-Xmn - JVM 堆内存中新生代的大小

配置方式

  • 第一种方式,启动 Docker 容器时指定 JVM 参数
1
docker run --name nacos-standalone -e MODE=standalone -e JVM_XMS=512m -e JVM_XMX=512m -e JVM_XMN=256m -p 8848:8848 -d nacos/nacos-server:latest
  • 第二种方式,在 Nacos Server 的 Env 配置文件中添加 JVM 参数
1
2
3
4
5
6
PREFER_HOST_MODE=hostname
MODE=standalone
SPRING_DATASOURCE_PLATFORM=mysql
JVM_XMS=512m
JVM_XMX=512m
JVM_XMN=256m

常见使用问题

使用指定的 IP 地址注册服务

问题描述

在 Docker 中部署微服务时,每个容器通常都会有一个独立的 IP 地址。当将这些服务注册到 Nacos 时,Nacos 会记录这些内网地址。但是,当其他微服务尝试调用这些服务时,它们实际上是在寻找这些内网地址。这就导致了无法找到对方的问题,因为它们都是在不同的容器和网络中运行的。特别注意,考虑的系统安全,Nacos 通常会和微服务应用部署在同一个内网,而不会暴露到公网。

  • (1) 场景一:当微服务应用部署在 Docker 容器时,默认会使用容器内的 IP(私有 IP)将服务注册到 Nacos 中,从而导致容器外部可能无法正常调用微服务应用。
  • (2) 场景二:当多个微服务应用和 Nacos 分别部署在多个内网时,由于默认会使用内网 IP 将服务注册到 Nacos 中,从而导致微服务应用之间无法正常调用。

问题解决

  • 使用 spring.cloud.nacos.discovery.ip 指定微服务应用注册所使用的 IP
1
2
# 使用固定 IP 注册服务
spring.cloud.nacos.discovery.ip=13.2.51.11
  • 还可以指定微服务应用注册所使用的网卡
1
2
3
4
5
6
7
8
9
10
11
# 设置固定网卡
spring.cloud.nacos.discovery.networkInterface=eth0

# 如果想拥有更丰富的选择,可以使用 Spring Cloud 的工具 InetUtils 进行配置,详细使用说明: https://github.com/spring-cloud/spring-cloud-commons/blob/master/docs/src/main/asciidoc/
spring.cloud.inetutils.default-hostname # 指定默认的主机名。当应用程序无法自动解析主机名时,将使用此配置作为默认值。
spring.cloud.inetutils.default-ip-address # 指定默认的 IP 地址。当应用程序无法自动解析 IP 地址时,将使用此配置作为默认值。
spring.cloud.inetutils.ignored-interfaces[0]=eth0 # 忽略名为 eth0 的网络接口。此配置用于排除特定的网卡,使其不被考虑为服务注册的候选接口。
spring.cloud.inetutils.ignored-interfaces=eth.* # 使用正则表达式忽略匹配 eth.* 的所有网络接口。例如,eth0、eth1 等接口都将被忽略。
spring.cloud.inetutils.preferred-networks=13.2.51 # 选择符合前缀(如 13.2.51)的 IP 地址作为服务注册的 IP。此配置项接受一个正则表达式数组,用于匹配期望使用的 IP 地址或 IP 前缀。
spring.cloud.inetutils.timeout-seconds # 设置计算主机 IP 信息的超时时间,单位为秒。默认值为 1 秒。
spring.cloud.inetutils.use-only-site-local-interfaces # 指示是否仅使用内网 IP(私有 IP)进行服务注册。如果设置为 true,则只考虑内网 IP 地址。
  • Nacos 的其他可选配置
1
2
3
4
5
6
7
8
9
10
11
12
13
spring.cloud.nacos.discovery.server-addr         # Nacos Server 的地址,比如 127.0.0.1:8848
spring.cloud.nacos.discovery.service # 当前服务的名称
spring.cloud.nacos.discovery.weight # 取值范围 1 到 100,数值越大,权重越大
spring.cloud.nacos.discovery.network-interface # 当 IP 未配置时,注册的 IP 为此网卡所对应的 IP 地址,如果此项也未配置,则默认取第一块网卡的地址
spring.cloud.nacos.discovery.ip # 当前服务注册所使用的 IP,优先级最高
spring.cloud.nacos.discovery.port # 默认情况下不用配置,会自动探测
spring.cloud.nacos.discovery.namespace # 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等

spring.cloud.nacos.discovery.access-key # 当要上阿里云时,阿里云上面的一个云账号名
spring.cloud.nacos.discovery.secret-key # 当要上阿里云时,阿里云上面的一个云账号密码
spring.cloud.nacos.discovery.metadata # 使用 Map 格式配置元数据,用户可以根据自己的需要自定义一些和服务相关的元数据信息
spring.cloud.nacos.discovery.log-name # 日志文件名
spring.cloud.nacos.discovery.enpoint # 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
  • 针对 Docker 容器的其他解决方案
    • (1) 调整 Docker 使用 host 网络模式启动容器,让容器直接复用宿主机网络栈。这样容器内应用的 IP 与宿主机一致,注册到 Nacos 的地址可直接被其他服务器访问‌。
      1
      2
      3
      4
      5
      6
      # docker-compose.yml
      services:

      your-service:
      network_mode: host
      image: your-service-image
    • (2) ‌使用 DNS 解析,通过内网 DNS 或 /etc/hosts 文件为宿主机配置域名,微服务应用注册时使用域名代替 IP。
      1
      2
      3
      4
      5
      6
      spring:
      cloud:
      nacos:
      discovery:
      server-addr: nacos.your-domain:8848 # 域名指向 Nacos
      ip: service-node1.your-domain # 微服务应用注册时使用宿主机域名

将 Nacos 控制台暴露到公网

问题描述

为了避免恶意网络攻击,Nacos 通常会和微服务应用部署在同一个内网,而不会暴露到公网。但是,若 Nacos 与其他微服务应用不是部署在同一个内网,可能就不得不将 Nacos 暴露到公网(更建议使用 VPN 实现内网互通来解决),这会导致 Nacos 控制台容易受到网络攻击。

问题解决

  • (1) 启用 Nacos 的安全认证功能,详细使用说明请看官方文档
1
2
3
4
5
6
7
8
9
10
# 是否启用 Nacos 认证功能,true 表示启用
nacos.core.auth.enabled=true
# 认证系统的类型,默认为 nacos
nacos.core.auth.system.type=nacos
# 服务器身份标识的键(不可为空),用于 Nacos 集群内多个节点之间的身份认证
nacos.core.auth.server.identity.key=自定义密钥
# 服务器身份标识的值(不可为空),用于 Nacos 集群内多个节点之间的身份认证
nacos.core.auth.server.identity.value=自定义值
# JWT 令牌的密钥,用于生成和验证 JWT 令牌的签名
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
1
2
# 自定义 JWT 令牌的密钥时,推荐将配置项设置为 Base64 编码的字符串,且原始密钥长度不得低于 32 字符
nacos.core.auth.default.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=
  • (2) 更改 Nacos 登录的用户名和密码

    • Nacos 登录的用户名和密码默认是 nacos / nacos,详细的更改教程请看这里
  • (3) 更改服务端口

    • 更改 Nacos 的默认端口,将 Nacos 服务端的默认端口从 8848 改为非标准端口(如 18848),降低被自动化工具扫描的风险‌。
  • (4) VPN 隧道加密

    • 若服务器支持,可通过 IPSec VPN 或 WireGuard 建立加密隧道,使微服务与 Nacos 间的通信在虚拟内网中完成,无需暴露 Nacos 端口到公网‌。
  • (5) 控制台安全加固

    • 使用 Nginx 反向代理 Nacos 控制台,实现路径隔离。比如,对 Nacos 控制台访问路径(如 /nacos)的端口(如 8848)做‌公网 IP 白名单限制‌,仅允许管理员 IP 访问。Nginx 的配置如下所示:
    • 在 Nginx 层增加 Basic Auth 或 OAuth2.0 认证,为控制台访问添加额外安全层‌。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      # 服务注册接口开放公网
      location /nacos/v1/ns {
      proxy_pass http://nacos-server:8848;
      allow 微服务IP1;
      allow 微服务IP2;
      allow 微服务IP3;
      deny all;
      }

      # 控制台访问限制内网
      location /nacos/ {
      proxy_pass http://nacos-server:8848;
      allow 管理员IP;
      deny all;
      }