一、配置一览

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/bin/bash

set -x
export CUSTOM_SEARCH_NAMES="application"
export CUSTOM_SEARCH_LOCATIONS=file:${BASE_DIR}/conf/
export MEMBER_LIST=""
PLUGINS_DIR="/home/nacos/plugins/peer-finder"
function print_servers() {
if [[ ! -d "${PLUGINS_DIR}" ]]; then
echo "" >"$CLUSTER_CONF"
for server in ${NACOS_SERVERS}; do
echo "$server" >>"$CLUSTER_CONF"
done
else
bash $PLUGINS_DIR/plugin.sh
sleep 30
fi
}
#===========================================================================================
# JVM Configuration
#===========================================================================================
JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 "
if [[ "${MODE}" == "standalone" ]]; then
JAVA_OPT="${JAVA_OPT} -Xms${JVM_XMS} -Xmx${JVM_XMX} -Xmn${JVM_XMN}"
JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
else
if [[ "${EMBEDDED_STORAGE}" == "embedded" ]]; then
JAVA_OPT="${JAVA_OPT} -DembeddedStorage=true"
fi
JAVA_OPT="${JAVA_OPT} -server -Xms${JVM_XMS} -Xmx${JVM_XMX} -Xmn${JVM_XMN} -XX:MetaspaceSize=${JVM_MS} -XX:MaxMetaspaceSize=${JVM_MMS}"
if [[ "${NACOS_DEBUG}" == "y" ]]; then
JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
fi
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
print_servers
fi

#===========================================================================================
# Setting system properties
#===========================================================================================
# set mode that Nacos Server function of split
if [[ "${FUNCTION_MODE}" == "config" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.functionMode=config"
elif [[ "${FUNCTION_MODE}" == "naming" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.functionMode=naming"
fi
# set nacos server ip
if [[ ! -z "${NACOS_SERVER_IP}" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.server.ip=${NACOS_SERVER_IP}"
fi

if [[ ! -z "${USE_ONLY_SITE_INTERFACES}" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.inetutils.use-only-site-local-interfaces=${USE_ONLY_SITE_INTERFACES}"
fi

if [[ ! -z "${PREFERRED_NETWORKS}" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.inetutils.preferred-networks=${PREFERRED_NETWORKS}"
fi

if [[ ! -z "${IGNORED_INTERFACES}" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.inetutils.ignored-interfaces=${IGNORED_INTERFACES}"
fi

### If turn on auth system:
if [[ ! -z "${NACOS_AUTH_ENABLE}" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.core.auth.enabled=${NACOS_AUTH_ENABLE}"
fi

if [[ "${PREFER_HOST_MODE}" == "hostname" ]]; then
JAVA_OPT="${JAVA_OPT} -Dnacos.preferHostnameOverIp=true"
fi
JAVA_OPT="${JAVA_OPT} -Dnacos.member.list=${MEMBER_LIST}"

JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([0-9]*).*$/\1/p')
if [[ "$JAVA_MAJOR_VERSION" -ge "9" ]]; then
JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${BASE_DIR}/logs/nacos_gc.log:time,tags:filecount=10,filesize=102400"
else
JAVA_OPT_EXT_FIX="-Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext"
JAVA_OPT="${JAVA_OPT} -Xloggc:${BASE_DIR}/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
fi

JAVA_OPT="${JAVA_OPT} -Dloader.path=${BASE_DIR}/plugins,${BASE_DIR}/plugins/health,${BASE_DIR}/plugins/cmdb,${BASE_DIR}/plugins/selector"
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/nacos-server.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.additional-location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --spring.config.name=${CUSTOM_SEARCH_NAMES}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/nacos-logback.xml"
JAVA_OPT="${JAVA_OPT} --server.max-http-header-size=524288"

echo "Nacos is starting, you can docker logs your container"
exec $JAVA ${JAVA_OPT}

1.3 application.properties

application.properties 配置文件示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# spring
server.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos}
server.contextPath=/nacos
server.port=${NACOS_APPLICATION_PORT:8848}
server.tomcat.accesslog.max-days=30
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false}
server.error.include-message=ALWAYS
# default current work dir
server.tomcat.basedir=file:.
#*************** Config Module Related Configurations ***************#
### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
#spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:}
spring.sql.init.platform=${SPRING_DATASOURCE_PLATFORM:}
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
db.num=${MYSQL_DATABASE_NUM:1}
db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false}
db.user.0=${MYSQL_SERVICE_USER}
db.password.0=${MYSQL_SERVICE_PASSWORD}
## DB connection pool settings
db.pool.config.connectionTimeout=${DB_POOL_CONNECTION_TIMEOUT:30000}
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2
### The auth system to use, currently only 'nacos' and 'ldap' is supported:
nacos.core.auth.system.type=${NACOS_AUTH_SYSTEM_TYPE:nacos}
### worked when nacos.core.auth.system.type=nacos
### The token expiration in seconds:
nacos.core.auth.plugin.nacos.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}
### The default token:
nacos.core.auth.plugin.nacos.token.secret.key=${NACOS_AUTH_TOKEN:}
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}
nacos.core.auth.enable.userAgentAuthWhite=${NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE:false}
nacos.core.auth.server.identity.key=${NACOS_AUTH_IDENTITY_KEY:}
nacos.core.auth.server.identity.value=${NACOS_AUTH_IDENTITY_VALUE:}
## spring security config
### turn off security
nacos.security.ignore.urls=${NACOS_SECURITY_IGNORE_URLS:/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**}
# metrics for elastic search
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
nacos.console.ui.enabled=true
nacos.core.param.check.enabled=true

配置文件中有许多环境变量,可以在启动容器时指定。

1.4 Dockerfile

远程下载 Nacos 安装包版本的 dockerfile 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
FROM alpine:latest

LABEL maintainer="z2huo9994@163.com"

# 安装依赖
RUN apk add --no-cache openjdk8-jre-base curl iputils ncurses vim libcurl bash

# 设置环境变量
ENV MODE="cluster" \
PREFER_HOST_MODE="ip"\
BASE_DIR="/home/nacos" \
CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
CLUSTER_CONF="/home/nacos/conf/cluster.conf" \
FUNCTION_MODE="all" \
JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk" \
NACOS_USER="nacos" \
JAVA="/usr/lib/jvm/java-1.8-openjdk/bin/java" \
JVM_XMS="1g" \
JVM_XMX="1g" \
JVM_XMN="512m" \
JVM_MS="128m" \
JVM_MMS="320m" \
NACOS_DEBUG="n" \
TOMCAT_ACCESSLOG_ENABLED="false" \
TIME_ZONE="Asia/Shanghai"

ARG NACOS_VERSION=2.4.2
ARG HOT_FIX_FLAG=""

WORKDIR $BASE_DIR

# 下载并安装 Nacos
RUN set -x \
&& curl -SL "https://github.com/alibaba/nacos/releases/download/${NACOS_VERSION}${HOT_FIX_FLAG}/nacos-server-${NACOS_VERSION}.tar.gz" -o nacos-server.tar.gz \
&& tar -xzvf nacos-server.tar.gz -C /home \
&& rm -rf nacos-server.tar.gz /home/nacos/bin/* /home/nacos/conf/*.properties /home/nacos/conf/*.example /home/nacos/conf/nacos-mysql.sql \
&& ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone

ADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/application.properties conf/application.properties

# 设置启动日志目录
RUN mkdir -p logs \
&& touch logs/start.out \
&& ln -sf /dev/stdout logs/start.out \
&& ln -sf /dev/stderr logs/start.out \
&& chmod +x bin/docker-startup.sh

EXPOSE 8848
ENTRYPOINT ["sh","bin/docker-startup.sh"]

远程下载为从 GitHub 上面下载,可能在一些网络环境中下载速度过慢,可以用本地的 Nacos 安装包来构建镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
FROM alpine:latest

LABEL maintainer="z2huo9994@163.com"

# 安装依赖
RUN apk add --no-cache openjdk8-jre-base curl iputils ncurses vim libcurl bash

# 设置环境变量
ENV MODE="cluster" \
PREFER_HOST_MODE="ip"\
BASE_DIR="/home/nacos" \
CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
CLUSTER_CONF="/home/nacos/conf/cluster.conf" \
FUNCTION_MODE="all" \
JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk" \
NACOS_USER="nacos" \
JAVA="/usr/lib/jvm/java-1.8-openjdk/bin/java" \
JVM_XMS="1g" \
JVM_XMX="1g" \
JVM_XMN="512m" \
JVM_MS="128m" \
JVM_MMS="320m" \
NACOS_DEBUG="n" \
TOMCAT_ACCESSLOG_ENABLED="false" \
TIME_ZONE="Asia/Shanghai"

ARG NACOS_VERSION=2.4.2
ARG HOT_FIX_FLAG=""

WORKDIR $BASE_DIR

# 将本地 nacos 安装包复制到镜像并解压到 /home 目录中
ADD packages/nacos-server-2.4.2.tar.gz /home

# 下载并安装 Nacos
RUN set -x \
&& rm -rf nacos-server.tar.gz /home/nacos/bin/* /home/nacos/conf/*.properties /home/nacos/conf/*.example /home/nacos/conf/nacos-mysql.sql \
&& ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone

ADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/application.properties conf/application.properties

# 设置启动日志目录
RUN mkdir -p logs \
&& touch logs/start.out \
&& ln -sf /dev/stdout logs/start.out \
&& ln -sf /dev/stderr logs/start.out \
&& chmod +x bin/docker-startup.sh

EXPOSE 8848
ENTRYPOINT ["sh","bin/docker-startup.sh"]

使用如下命令来构建 Docker 镜像:

1
2
docker build -t z2huo/nacos-dev:2.4.2-alpine -f local-nacos-package.dockerfile .
docker build -t z2huo/nacos-dev:2.4.2.1-alpine -f local-nacos-package.dockerfile .

2、容器相关文件

2.1 .env

1
2
image=z2huo/nacos-dev:2.4.2-alpine
restart=unless-stopped

可以使用官方提供的镜像:

1
2
image=nacos/nacos-server:v2.4.2.1
restart=unless-stopped

2.2 nacos-cluster.env

支持的环境变量,可以查看:nacos-docker README | github

1
2
3
4
5
6
7
8
9
MODE=cluster
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos-1:8848 nacos-2:8858 nacos-3:8868

# NACOS_SERVERS=nacos-1:8848 nacos-2:8848 nacos-3:8848
# NACOS_SERVERS=nacos-1:8848 nacos-2:8849 nacos-3:8850

JVM_XMS=2g
JVM_XMX=2g

2.3 cluster.conf

此配置文件需要直接挂载到容器中,或者直接使用环境变量 NACOS_SERVERS

1
2
3
4
5
6
7
nacos-1:8848
nacos-2:8858
nacos-3:8868

# nacos-1:8848
# nacos-2:8849
# nacos-3:8850

2.4 application.properties

如果有很多自定义配置的需求,建议直接对 application.properties 文件进行挂卷,取代使用环境变量。

2.4.1 通用配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#*************** Spring Boot Related Configurations ***************#
### Default web context path:
server.servlet.contextPath=/nacos
### Include message field
server.error.include-message=ALWAYS
### Default web server port:
server.port=8848

#*************** Network Related Configurations ***************#
### If prefer hostname over ip for Nacos server addresses in cluster.conf:
# nacos.inetutils.prefer-hostname-over-ip=false

### Specify local server's IP:
# nacos.inetutils.ip-address=


#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
spring.datasource.platform=mysql
spring.sql.init.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://mysql-master:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false
db.user.0=nacos
db.password.0=z2huo@2024

### Connection pool configuration: hikariCP
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2

# db.pool.config.driverClassName=com.mysql.cj.jdbc.Driver
# db.pool.config.connectionTestQuery=SELECT 1

### the maximum retry times for push
nacos.config.push.maxRetryTime=50

#*************** Naming Module Related Configurations ***************#

### If enable data warmup. If set to false, the server would accept request without local data preparation:
# nacos.naming.data.warmup=true

### If enable the instance auto expiration, kind like of health check of instance:
# nacos.naming.expireInstance=true

### Add in 2.0.0
### The interval to clean empty service, unit: milliseconds.
# nacos.naming.clean.empty-service.interval=60000

### The expired time to clean empty service, unit: milliseconds.
# nacos.naming.clean.empty-service.expired-time=60000

### The interval to clean expired metadata, unit: milliseconds.
# nacos.naming.clean.expired-metadata.interval=5000

### The expired time to clean metadata, unit: milliseconds.
# nacos.naming.clean.expired-metadata.expired-time=60000

### The delay time before push task to execute from service changed, unit: milliseconds.
# nacos.naming.push.pushTaskDelay=500

### The timeout for push task execute, unit: milliseconds.
# nacos.naming.push.pushTaskTimeout=5000

### The delay time for retrying failed push task, unit: milliseconds.
# nacos.naming.push.pushTaskRetryDelay=1000

### Since 2.0.3
### The expired time for inactive client, unit: milliseconds.
# nacos.naming.client.expired.time=180000

#*************** CMDB Module Related Configurations ***************#
### The interval to dump external CMDB in seconds:
# nacos.cmdb.dumpTaskInterval=3600

### The interval of polling data change event in seconds:
# nacos.cmdb.eventTaskInterval=10

### The interval of loading labels in seconds:
# nacos.cmdb.labelTaskInterval=300

### If turn on data loading task:
# nacos.cmdb.loadDataAtStart=false

#***********Metrics for tomcat **************************#
server.tomcat.mbeanregistry.enabled=true

#***********Expose prometheus and health **************************#
#management.endpoints.web.exposure.include=prometheus,health

### Metrics for elastic search
management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200

### Metrics for influx
management.metrics.export.influx.enabled=false
#management.metrics.export.influx.db=springboot
#management.metrics.export.influx.uri=http://localhost:8086
#management.metrics.export.influx.auto-create-db=true
#management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true

#*************** Access Log Related Configurations ***************#
### If turn on the access log:
server.tomcat.accesslog.enabled=true

### file name pattern, one file per hour
server.tomcat.accesslog.rotate=true
server.tomcat.accesslog.file-date-format=.yyyy-MM-dd-HH
### The access log pattern:
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i

### The directory of access log:
server.tomcat.basedir=file:.

#*************** Access Control Related Configurations ***************#
### If enable spring security, this option is deprecated in 1.2.0:
#spring.security.enabled=false

### The ignore urls of auth
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**

### The auth system to use, currently only 'nacos' and 'ldap' is supported:
nacos.core.auth.system.type=nacos

### If turn on auth system:
nacos.core.auth.enabled=false

### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=true

### Since 1.4.1, Turn on/off white auth for user-agent: nacos-server, only for upgrade from old version.
nacos.core.auth.enable.userAgentAuthWhite=false

### Since 1.4.1, worked when nacos.core.auth.enabled=true and nacos.core.auth.enable.userAgentAuthWhite=false.
### The two properties is the white list for auth and used by identity the request from other server.
nacos.core.auth.server.identity.key=
nacos.core.auth.server.identity.value=

### worked when nacos.core.auth.system.type=nacos
### The token expiration in seconds:
nacos.core.auth.plugin.nacos.token.cache.enable=false
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
### The default token (Base64 String):
nacos.core.auth.plugin.nacos.token.secret.key=

### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
#nacos.core.auth.ldap.url=ldap://localhost:389
#nacos.core.auth.ldap.basedc=dc=example,dc=org
#nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc}
#nacos.core.auth.ldap.password=admin
#nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org
#nacos.core.auth.ldap.filter.prefix=uid
#nacos.core.auth.ldap.case.sensitive=true
#nacos.core.auth.ldap.ignore.partial.result.exception=false

#*************** Control Plugin Related Configurations ***************#
# plugin type
#nacos.plugin.control.manager.type=nacos

# local control rule storage dir, default ${nacos.home}/data/connection and ${nacos.home}/data/tps
#nacos.plugin.control.rule.local.basedir=${nacos.home}

# external control rule storage type, if exist
#nacos.plugin.control.rule.external.storage=

#*************** Config Change Plugin Related Configurations ***************#
# webhook
#nacos.core.config.plugin.webhook.enabled=false
# It is recommended to use EB https://help.aliyun.com/document_detail/413974.html
#nacos.core.config.plugin.webhook.url=http://localhost:8080/webhook/send?token=***
# The content push max capacity ,byte
#nacos.core.config.plugin.webhook.contentMaxCapacity=102400

# whitelist
#nacos.core.config.plugin.whitelist.enabled=false
# The import file suffixs
#nacos.core.config.plugin.whitelist.suffixs=xml,text,properties,yaml,html
# fileformatcheck,which validate the import file of type and content
#nacos.core.config.plugin.fileformatcheck.enabled=false

#*************** Istio Related Configurations ***************#
### If turn on the MCP server:
nacos.istio.mcp.server.enabled=false

上面的配置文件中需要修改数据库配置:

1
2
3
4
5
6
7
8
9
10
spring.datasource.platform=mysql
spring.sql.init.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://mysql-master:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false
db.user.0=nacos
db.password.0=yourpassword
2.4.2 各个容器的配置
1
2
spring.profiles.include=common
server.port=8848
1
2
spring.profiles.include=common
server.port=8858
1
2
spring.profiles.include=common
server.port=8868

2.5 compose.yaml

2.5.1 挂载 application.properties 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 使用 application.properties 来配置容器

name: nacos-cluster-demo

networks:
nacos_cluster_net:
name: nacos_cluster_net
driver: bridge
ipam:
driver: default
config:
- subnet: 172.88.0.0/16
ip_range: 172.88.0.0/16
gateway: 172.88.0.1
mysql-master-slave-net:
name: mysql-master-slave-net
external: true
mysql-single-net:
name: mysql-single-net
external: true

volumes:
nacos-1-volume:
name: nacos-cluster-demo-nacos-1-logs-volume
nacos-2-volume:
name: nacos-cluster-demo-nacos-2-logs-volume
nacos-3-volume:
name: nacos-cluster-demo-nacos-3-logs-volume

# nacos 依赖 mysql 主从的两个 IP 如下
# 172.33.1.11
# 172.33.1.21
# 172.33.1.31

# nacos 依赖 mysql 单节点的 IP 如下
# 172.33.0.11

# Nacos 集群配置,如果需要自定义的配置较多,不建议使用 env_file 指定 env 文件,而是改为 volume 挂载 application.properties

services:
nacos-1:
image: ${image}
container_name: nacos-1
hostname: nacos-1
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.1
volumes:
- nacos-1-volume:/home/nacos/logs
- ./application-1.properties:/home/nacos/conf/application.properties
- ./application-common.properties:/home/nacos/conf/application-common.properties
# - ./cluster.conf:/home/nacos/conf/cluster.conf
ports:
# - "7848:7848"
# - "8848:8848"
# - "9868:9848"
# - "9850:9849"
- "7848:7848"
- "8848:8848"
- "9848:9848"
- "9849:9849"
env_file:
- ./nacos-cluster.env
restart: ${restart}

nacos-2:
image: ${image}
container_name: nacos-2
hostname: nacos-2
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.2
volumes:
- nacos-2-volume:/home/nacos/logs
- ./application-2.properties:/home/nacos/conf/application.properties
- ./application-common.properties:/home/nacos/conf/application-common.properties
# - ./cluster.conf:/home/nacos/conf/cluster.conf
ports:
# - "7849:7848"
# - "8849:8848"
# - "9869:9848"
# - "9851:9849"
- "7858:7858"
- "8858:8858"
- "9858:9858"
- "9859:9859"
env_file:
- ./nacos-cluster.env
restart: ${restart}

nacos-3:
image: ${image}
container_name: nacos-3
hostname: nacos-3
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.3
volumes:
- nacos-3-volume:/home/nacos/logs
- ./application-3.properties:/home/nacos/conf/application.properties
- ./application-common.properties:/home/nacos/conf/application-common.properties
# - ./cluster.conf:/home/nacos/conf/cluster.conf
ports:
# - "7850:7848"
# - "8850:8848"
# - "9870:9848"
# - "9852:9849"
- "7868:7868"
- "8868:8868"
- "9868:9868"
- "9869:9869"
env_file:
- ./nacos-cluster.env
restart: ${restart}

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 使用环境变量配置

name: nacos-cluster-demo

networks:
nacos_cluster_net:
name: nacos_cluster_net
driver: bridge
ipam:
driver: default
config:
- subnet: 172.88.0.0/16
ip_range: 172.88.0.0/16
gateway: 172.88.0.1
mysql-master-slave-net:
name: mysql-master-slave-net
external: true
mysql-single-net:
name: mysql-single-net
external: true

volumes:
nacos-1-volume:
name: nacos-cluster-demo-nacos-1-logs-volume
nacos-2-volume:
name: nacos-cluster-demo-nacos-2-logs-volume
nacos-3-volume:
name: nacos-cluster-demo-nacos-3-logs-volume

# nacos 依赖 mysql 主从的两个 IP 如下
# 172.33.1.11
# 172.33.1.21
# 172.33.1.31

# nacos 依赖 mysql 单节点的 IP 如下
# 172.33.0.11

# Nacos 集群配置,如果需要自定义的配置较多,不建议使用 env_file 指定 env 文件,而是改为 volume 挂载 application.properties

services:
nacos-1:
image: ${image}
container_name: nacos-1
hostname: nacos-1
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.1
volumes:
- nacos-1-volume:/home/nacos/logs
ports:
- "7848:7848"
- "8848:8848"
- "9848:9848"
- "9849:9849"
env_file:
- ./nacos-cluster.env
restart: ${restart}
environment:
- NACOS_APPLICATION_PORT=8848

nacos-2:
image: ${image}
container_name: nacos-2
hostname: nacos-2
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.2
volumes:
- nacos-2-volume:/home/nacos/logs
ports:
- "7858:7858"
- "8858:8858"
- "9858:9858"
- "9859:9859"
env_file:
- ./nacos-cluster.env
restart: ${restart}
environment:
- NACOS_APPLICATION_PORT=8858

nacos-3:
image: ${image}
container_name: nacos-3
hostname: nacos-3
networks:
# mysql-master-slave-net:
mysql-single-net:
nacos_cluster_net:
ipv4_address: 172.88.1.3
volumes:
- nacos-3-volume:/home/nacos/logs
ports:
- "7868:7868"
- "8868:8868"
- "9868:9868"
- "9869:9869"
env_file:
- ./nacos-cluster.env
restart: ${restart}
environment:
- NACOS_APPLICATION_PORT=8868

nacos-cluster.env 文件配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MODE=cluster
PREFER_HOST_MODE=hostname

SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=mysql-1
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=yourpassword
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false

NACOS_SERVERS=nacos-1:8848 nacos-2:8858 nacos-3:8868

JVM_XMS=2g
JVM_XMX=2g

2.6 MySQL Nacos DDL

建库语句如下:

1
2
3
4
create database if not exists nacos
character set utf8mb4
collate utf8mb4_0900_ai_ci
;

建表语句如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/******************************************/
/* 表名称 = 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(128) DEFAULT NULL COMMENT 'group_id',
`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 COMMENT 'app_name',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description',
`c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage',
`effect` varchar(64) DEFAULT NULL COMMENT '配置生效的描述',
`type` varchar(64) DEFAULT NULL COMMENT '配置的类型',
`c_schema` text COMMENT '配置的模式',
`encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' 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';

/******************************************/
/* 表名称 = 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(128) 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 COMMENT 'app_name',
`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='增加租户字段';


/******************************************/
/* 表名称 = 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` varchar(1024) NOT NULL DEFAULT '' 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';

/******************************************/
/* 表名称 = 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';

/******************************************/
/* 表名称 = 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 COMMENT 'nid, 自增长标识',
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';

/******************************************/
/* 表名称 = 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容量信息表';

/******************************************/
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(20) unsigned NOT NULL COMMENT 'id',
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增标识',
`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',
`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',
`op_type` char(10) DEFAULT NULL COMMENT 'operation type',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' 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='多租户改造';


/******************************************/
/* 表名称 = 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 COMMENT 'username',
`password` varchar(500) NOT NULL COMMENT 'password',
`enabled` boolean NOT NULL COMMENT 'enabled'
);

CREATE TABLE `roles` (
`username` varchar(50) NOT NULL COMMENT 'username',
`role` varchar(50) NOT NULL COMMENT 'role',
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);

CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL COMMENT 'role',
`resource` varchar(128) NOT NULL COMMENT 'resource',
`action` varchar(8) NOT NULL COMMENT 'action',
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

二、部署过程

通过上面提供的 Dockerfile 构建 Nacos 镜像。

在 MySQL 中创建 Nacos 数据库,并执行建表语句。

执行 docker compose up -d 启动 Nacos 容器。

容器启动后,可以在容器中看到如下日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2025-05-03 04:49:30          ,--.
2025-05-03 04:49:30 ,--.'|
2025-05-03 04:49:30 ,--,: : | Nacos 2.4.2
2025-05-03 04:49:30 ,`--.'`| ' : ,---. Running in cluster mode, All function modules
2025-05-03 04:49:30 | : : | | ' ,'\ .--.--. Port: 8848
2025-05-03 04:49:30 : | \ | : ,--.--. ,---. / / | / / ' Pid: 1
2025-05-03 04:49:30 | : ' '; | / \ / \. ; ,. :| : /`./ Console: http://nacos-1:8848/nacos/index.html
2025-05-03 04:49:30 ' ' ;. ;.--. .-. | / / '' | |: :| : ;_
2025-05-03 04:49:30 | | | \ | \__\/: . .. ' / ' | .; : \ \ `. https://nacos.io
2025-05-03 04:49:30 ' : | ; .' ," .--.; |' ; :__| : | `----. \
2025-05-03 04:49:30 | | '`--' / / ,. |' | '.'|\ \ / / /`--' /
2025-05-03 04:49:30 ' : | ; : .' \ : : `----' '--'. /
2025-05-03 04:49:30 ; |.' | , .-./\ \ / `--'---'
2025-05-03 04:49:30 '---' `--`---' `----'
2025-05-03 04:49:30
2025-05-03 04:49:30 2025-05-03 04:49:30,536 INFO The server IP list of Nacos is [nacos-1:8848, nacos-2:8848, nacos-3:8848]
2025-05-03 04:49:30
2025-05-03 04:49:31 2025-05-03 04:49:31,537 INFO Nacos is starting...
2025-05-03 04:49:31
2025-05-03 04:49:32 2025-05-03 04:49:32,538 INFO Nacos is starting...
2025-05-03 04:49:32
2025-05-03 04:49:33 2025-05-03 04:49:33,539 INFO Nacos is starting...
2025-05-03 04:49:33
2025-05-03 04:49:34 2025-05-03 04:49:34,541 INFO Nacos is starting...
2025-05-03 04:49:34
2025-05-03 04:49:35 2025-05-03 04:49:35,542 INFO Nacos is starting...
2025-05-03 04:49:35
2025-05-03 04:49:36 2025-05-03 04:49:36,546 INFO Nacos is starting...
2025-05-03 04:49:36
2025-05-03 04:49:37 2025-05-03 04:49:37,476 INFO Nacos started successfully in cluster mode. use external storage

浏览器中访问 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
2
: not foundbin/docker-startup.sh: line 6:
nacos-1 | bin/docker-startup.sh: set: line 14: illegal option -

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
2
3
4
5
6
7
8
9
package com.alibaba.nacos.api.common;

public class Constants {

public static final Integer SDK_GRPC_PORT_DEFAULT_OFFSET = 1000;

public static final Integer CLUSTER_GRPC_PORT_DEFAULT_OFFSET = 1001;

}
1
2
3
4
5
6
7
8
9
10
package com.alibaba.nacos.common.remote.client.grpc;

public class GrpcSdkClient extends GrpcClient {

@Override
public int rpcPortOffset() {
return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY,
String.valueOf(Constants.SDK_GRPC_PORT_DEFAULT_OFFSET)));
}
}
1
2
3
4
5
6
7
8
9
10
package com.alibaba.nacos.common.remote.client.grpc;

public class GrpcClusterClient extends GrpcClient {

@Override
public int rpcPortOffset() {
return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY,
String.valueOf(Constants.CLUSTER_GRPC_PORT_DEFAULT_OFFSET)));
}
}
1
2
3
4
5
6
7
8
9
10
11
package com.alibaba.nacos.common.remote.client.grpc;

public abstract class GrpcClient extends RpcClient {

// ......

int port = serverInfo.getServerPort() + rpcPortOffset();

// ......

}

所以在单机模式下部署 Nacos 集群,不能简单地为每个实例配置连续的主端口,比如选择的主端口号为:8848、8849、8850,因为这样会导致其他端口冲突。

在 Docker 容器中部署又有所不同,每个容器内部端口配置相同是不存在冲突的,但是需要将容器中的端口暴露给宿主机,此时如果暴露的端口和 Nacos 容器使用的端口不一致时,gRPC 客户端会连接不上服务端(不知道为啥,并且在 Dubbo 配置中暂时还没有找到指定与 Nacos 通信端口的配置),比如在 Dubbo 中使用 Nacos 作为配置中心、注册中心和元数据中心时。

例如容器端口映射如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- "7848:7848"
- "8848:8848"
- "9868:9848"
- "9850:9849"

- "7849:7848"
- "8849:8848"
- "9869:9848"
- "9851:9849"

- "7850:7848"
- "8850:8848"
- "9870:9848"
- "9852:9849"

客户端与服务端之间 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.

相关链接

Docker 中部署 Nacos 集群 | z2huo

nacos-server image | hub.docker.com

nacos-docker README | github

[[Docker 中部署 Nacos 集群]]

[[CR、LF、CRLF]]

OB tags

#微服务 #SpringCloud #Docker #Nacos