Nacos + MySQL + Docker
一、配置一览
1、镜像构建相关文件
之前使用 PostgreSQL 作为数据源需要自己构建镜像,并添加 PostgreSQL 数据源插件,因为 MySQL 是官方默认支持的数据源,所以可以直接使用官方镜像,取代手动构建:nacos-server image | hub.docker.com
1.1 选择使用 MySQL 作为数据源
Nacos 可以使用内置数据源,内置数据源不需要做任何配置,也可以配置外置数据源,默认的是 MySQL。
生产使用建议至少主备模式,或者采用高可用数据库。
选择使用 MySQL 作为数据源不需要做额外的配置,也不需要使用额外的插件。
之前在 Docker 中配置了 MySQL 主从环境,使用的是 MySQL 的 9.2.0 版本。
1.2 docker-startup.sh
1 | !/bin/bash |
1.3 application.properties
application.properties
配置文件示例如下:
1 | # spring |
配置文件中有许多环境变量,可以在启动容器时指定。
1.4 Dockerfile
远程下载 Nacos 安装包版本的 dockerfile 文件如下:
1 | FROM alpine:latest |
远程下载为从 GitHub 上面下载,可能在一些网络环境中下载速度过慢,可以用本地的 Nacos 安装包来构建镜像:
1 | FROM alpine:latest |
使用如下命令来构建 Docker 镜像:
1 | docker build -t z2huo/nacos-dev:2.4.2-alpine -f local-nacos-package.dockerfile . |
2、容器相关文件
2.1 .env
1 | image=z2huo/nacos-dev:2.4.2-alpine |
可以使用官方提供的镜像:
1 | image=nacos/nacos-server:v2.4.2.1 |
2.2 nacos-cluster.env
支持的环境变量,可以查看:nacos-docker README | github
1 | MODE=cluster |
2.3 cluster.conf
此配置文件需要直接挂载到容器中,或者直接使用环境变量 NACOS_SERVERS
1 | nacos-1:8848 |
2.4 application.properties
如果有很多自定义配置的需求,建议直接对 application.properties
文件进行挂卷,取代使用环境变量。
2.4.1 通用配置
1 | #*************** Spring Boot Related Configurations ***************# |
上面的配置文件中需要修改数据库配置:
1 | spring.datasource.platform=mysql |
2.4.2 各个容器的配置
1 | spring.profiles.include=common |
1 | spring.profiles.include=common |
1 | spring.profiles.include=common |
2.5 compose.yaml
2.5.1 挂载 application.properties
配置
1 | # 使用 application.properties 来配置容器 |
Docker Compose 中的配置:
- 在
networks
中定义的mysql-master-slave-net
网络,该网络是之前在 Docker 中部署的 MySQL 主从复制容器所使用的桥接网络,该网络需要配置external: true
表示使用的是当前 Compose 之外的网络。 - 挂载
application.properties
配置文件,用来替代构建的镜像中的配置文件 - 不用挂载
cluster.conf
文件,因为在docker-startup.sh
文件中,print_servers
方法中会向cluster.conf
文件中写入内容。 - 需要暴露 4 个端口
7848
,Raft 集群通信端口,用于 Nacos 集群节点之间的 Raft 协议通信。Raft 是 Nacos 默认的集群选举和数据一致性协议,集群节点通过此端口进行 Leader 选举和日志复制。8848
,HTTP API 端口。提供主要的 HTTP API 服务接口,用于客户端与 Nacos 服务端之间的交互。涵盖服务注册、服务发现、配置管理等功能。9848
,服务健康检查端口。提供服务端的健康检查和监控接口。用于获取 Nacos 服务端的运行状态信息(如 CPU 使用率、负载、集群状态等)。9849
,Grpc 通信端口。用于 Nacos 内部服务和客户端之间基于 gRPC 协议的通信。支持更高效的长连接通信,特别是在 Nacos 2.x 中,gRPC 替代了部分 HTTP 通信,成为主要的注册与心跳通信协议。
如果你有很多自定义配置的需求,强烈建议在生产环境对
application.properties
文件进行挂卷定义.
2.5.2 使用环境变量配置
1 | # 使用环境变量配置 |
nacos-cluster.env
文件配置如下:
1 | MODE=cluster |
2.6 MySQL Nacos DDL
建库语句如下:
1 | create database if not exists nacos |
建表语句如下:
1 | /******************************************/ |
二、部署过程
通过上面提供的 Dockerfile 构建 Nacos 镜像。
在 MySQL 中创建 Nacos 数据库,并执行建表语句。
执行 docker compose up -d
启动 Nacos 容器。
容器启动后,可以在容器中看到如下日志:
1 | 2025-05-03 04:49:30 ,--. |
浏览器中访问 Nacos 地址 localhost: 8848/nacos
,查看集群节点:
三、其他
1、MySQL 密码认证问题
启动容器后,容器日志中有异常如下:
1 | Caused by: com.mysql.cj.exceptions.UnableToConnectException: Public Key Retrieval is not allowed |
是由于 MySQL 的安全认证机制与客户端配置不兼容导致的,在 Nacos 的 application.properties
配置文件中使用了明文密码。
MySQL 8+ 默认使用 caching_sha2_password
插件,该插件要求客户端在身份验证时通过 SSL/TLS 加密传输密码。若未启用 SSL 或未允许公钥检索,客户端无法获取服务器的公钥进行加密,从而触发此错误。
使用如下的数据库连接 URL:
1 | jdbc:mysql://mysql-master:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false |
连接中添加额外的参数:
allowPublicKeyRetrieval=true
,允许客户端从服务器检索公钥。useSSL=false
,禁用 SSL。
但是使用如上配置会降低安全性。
2、shell 脚本回车换行符问题
办公室的电脑是 Windows 的,默认使用的是 CRLF,Docker 容器中使用的 Linux,只支持 \n
,不支持 \r\n
,在 Windows 中构建镜像时,需要确认并修改一下 Shell 脚本的换行符类型为 LF 之后再构建镜像。否则在容器启动时执行 Shell 脚本时会有如下错误:
1 | : not foundbin/docker-startup.sh: line 6: |
3、Nacos 服务接口占用问题
Nacos 服务端运行时,默认会占用多个端口,每个端口都有其特定用途。以 Nacos 默认的端口举例
- 8848,主端口号,通过
server.port
配置属性指定,默认的管理控制台端口,用于服务注册、发现、配置管理的 RESTful API - 9848,客户端 gRPC 请求,用于 Nacos 2.0+ 版本客户端与服务端之间的 gRPC 通信,由客户端主动发起连接
- 9849,服务端 gRPC 请求,用于 Nacos 2.0+ 版本集群模式下不同服务端节点之间的数据同步和通信
- 7848,Jraft 请求,用于 Nacos 集群模式下服务端节点间的 Raft 一致性算法通信(如选主、日志复制)
上面的端口号是根据 server.port
来计算的。
1 | package com.alibaba.nacos.api.common; |
1 | package com.alibaba.nacos.common.remote.client.grpc; |
1 | package com.alibaba.nacos.common.remote.client.grpc; |
1 | package com.alibaba.nacos.common.remote.client.grpc; |
所以在单机模式下部署 Nacos 集群,不能简单地为每个实例配置连续的主端口,比如选择的主端口号为:8848、8849、8850,因为这样会导致其他端口冲突。
在 Docker 容器中部署又有所不同,每个容器内部端口配置相同是不存在冲突的,但是需要将容器中的端口暴露给宿主机,此时如果暴露的端口和 Nacos 容器使用的端口不一致时,gRPC 客户端会连接不上服务端(不知道为啥,并且在 Dubbo 配置中暂时还没有找到指定与 Nacos 通信端口的配置),比如在 Dubbo 中使用 Nacos 作为配置中心、注册中心和元数据中心时。
例如容器端口映射如下:
1 | - "7848:7848" |
客户端与服务端之间 gRPC 通信端口映射宿主机和容器中端口不匹配,比如 9868:9848
导致 Dubbo 客户端连接不到 Nacos,报错如下:
1 | o.a.d.c.s.n.NacosDynamicConfiguration : [DUBBO] Failed to create nacos config service client. Reason: server status check failed., dubbo version: 3.3.5, current host: 198.18.0.1, error code: 5-34. This may be caused by , go to https://dubbo.apache.org/faq/5/34 to find instructions. |
相关链接
nacos-server image | hub.docker.com
OB links
[[Docker 中部署 Nacos 集群]]
[[CR、LF、CRLF]]
OB tags
#微服务 #SpringCloud #Docker #Nacos