一、配置一览

1、镜像构建相关文件

1.1 Nacos 配置 PostgreSQL 数据源

Nacos 可以使用内置数据源,内置数据源不需要做任何配置,也可以配置外置数据源,默认的使 MySQL。

生产使用建议至少主备模式,或者采用高可用数据库。

因为从学校出来之后一直用的都是 PostgreSQL,所以 Nacos 这里也使用 PostgreSQL 来作为数据源。

Nacos 从 2.2.0 版本开始,可通过 SPI 机制注入多数据源实现插件,并在引入对应数据源实现后,便可在 Nacos 启动时通过读取 application.properties 配置文件中 spring.datasource.platform 配置项选择加载对应多数据源插件。

在原来的 Config 模块中,所有的 SQL 操作的执行是通过直接使用 JdbcTemplate 执行固定 SQL 语句的形式,使得 SQL 语句与业务逻辑高度耦合,并且只支持 Derby 与 MySQL 两种数据源。

Nacos 数据源插件介绍:nacos datasource plugin

官方提供的插件列表如下:nacos-group/nacos-plugin

从 GitHub 获取项目之后,将 nacos-postgresql-datasource-plugin-ext 模组打包为 jar 文件之后在构建 Nacos 镜像时使用。

1.2 Nacos 的 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
94
95
#!/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 -XX:-UseParNewGC"
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}

此 shell 文件中需要注意的地方:

  • print_servers 方法中清空 CLUSTER_CONF 文件之后,将 NACOS_SERVERS 变量的值追加写入到 CLUSTER_CONF 文件中。
  • 添加 Java 启动参数 -Dloader.path,其中有如下片段 ${BASE_DIR}/pluginsplugins 文件夹下即为自定义插件需要添加的位置。

1.3 Nacos 的 application.properties 文件

Nacos 的配置可以通过 properties 文件更改。

此 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
# 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}
### 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

1.4 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
51
52
53
54
55
56
57
58
59
FROM centos:7.9.2009

LABEL maintainer="z2huo9994@163.com"

# set environment
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.0-openjdk" \
NACOS_USER="nacos" \
JAVA="/usr/lib/jvm/java-1.8.0-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.2.3
ARG HOT_FIX_FLAG=""

WORKDIR $BASE_DIR

# 更新仓库配置
RUN set -x \
&& sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \
&& sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

# iputils telnet net-tools
RUN set -x \
&& yum update -y \
&& yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel nc vim libcurl iputils telnet net-tools \
&& yum clean all

RUN curl -SL https://github.com/alibaba/nacos/releases/download/${NACOS_VERSION}${HOT_FIX_FLAG}/nacos-server-${NACOS_VERSION}.tar.gz -o /home/nacos-server.tar.gz \
&& tar -xzvf /home/nacos-server.tar.gz -C /home \
&& rm -rf /home/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

# 添加适配 postgreSQL 插件
ADD plugins/nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar plugins/nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar
ADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/application.properties conf/application.properties

# set startup log dir
RUN mkdir -p logs \
&& touch logs/start.out \
&& ln -sf /dev/stdout start.out \
&& ln -sf /dev/stderr start.out
RUN chmod +x bin/docker-startup.sh

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

Dockerfile 文件中添加如下配置,自定义 yum 镜像源,改善网络下载速度。不知道为啥,我开了 VPN,并且也开了 TUN 模式了,还是会下载超时。

1
2
3
4
# 更新仓库配置
RUN set -x \
&& sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \
&& sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

2、容器编排相关文件

2.1 .env 文件

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

2.2 cluster.conf 文件

1
2
3
nacos-1:8848
nacos-2:8848
nacos-3:8848

2.3 nacos-cluster.env 文件

1
2
3
4
MODE=cluster
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos-1:8848 nacos-2:8848 nacos-3:8848
# NACOS_SERVERS=nacos-1:8848 nacos-2:8849 nacos-3:8850
  • NACOS_SERVERS 属性,定义集群地址,多个地址之间用空格分隔
  • PREFER_HOST_MODE 属性,定义 Nacos 支持 IP 还是域名,取值 hostnameip,默认为 ip
  • MODE 属性,定义系统启动的方式,集群模式还是单机模式,取值 clusterstandalone,默认为 cluster

2.4 compose.yaml 文件

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
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
postgres-master-slave-net:
name: postgres-master-slave-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

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

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

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

Compose 文件中需要注意的配置:

  • 在 networks 中定义 postgres-master-slave-net 网络,该网络是 docker 中部署的 PostgreSQL 主从复制所使用的桥接网络,该网络需要配置 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 application.properties 配置文件

2.5.1 数据库配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
### 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=postgresql

### Connect URL of DB:
db.url.0=jdbc:postgresql://postgres-master:5432/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
db.user.0=*****
db.password.0=*****

### 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=org.postgresql.Driver
db.pool.config.connectionTestQuery=SELECT 1
2.5.2 鉴权配置

二、部署过程

1、打包 Nacos PostgreSQL 数据源插件

从官方提供的插件列表 nacos-group/nacos-plugin 中下载 PostgreSQL 插件。用 IDEA 打开,构建项目并打包。

将打包好的 jar 包添加到 Dockerfile 文件中:

1
ADD plugins/nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar plugins/nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar

2、在 PostgreSQL 中创建数据库

在 PostgreSQL 中创建 Nacos 使用的数据库,并执行 DDL 建表语句。

3、构建 Nacos 镜像

构建 Nacos 镜像。

1
docker build -t z2huo/nacos-dev:2.2.3 .

4、启动服务

1
2
$ docker compose config
$ docker compose up -d

查看容器日志,可以看到日志中的集群地址:The server IP list of Nacos is [nacos-1:8848, nacos-2:8848, nacos-3:8848]

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
2025-01-16 22:33:35 Nacos is starting, you can docker logs your container
2025-01-16 22:33:36
2025-01-16 22:33:36 ,--.
2025-01-16 22:33:36 ,--.'|
2025-01-16 22:33:36 ,--,: : | Nacos 2.2.3
2025-01-16 22:33:36 ,`--.'`| ' : ,---. Running in cluster mode, All function modules
2025-01-16 22:33:36 | : : | | ' ,'\ .--.--. Port: 8848
2025-01-16 22:33:36 : | \ | : ,--.--. ,---. / / | / / ' Pid: 1
2025-01-16 22:33:36 | : ' '; | / \ / \. ; ,. :| : /`./ Console: http://nacos-1:8848/nacos/index.html
2025-01-16 22:33:36 ' ' ;. ;.--. .-. | / / '' | |: :| : ;_
2025-01-16 22:33:36 | | | \ | \__\/: . .. ' / ' | .; : \ \ `. https://nacos.io
2025-01-16 22:33:36 ' : | ; .' ," .--.; |' ; :__| : | `----. \
2025-01-16 22:33:36 | | '`--' / / ,. |' | '.'|\ \ / / /`--' /
2025-01-16 22:33:36 ' : | ; : .' \ : : `----' '--'. /
2025-01-16 22:33:36 ; |.' | , .-./\ \ / `--'---'
2025-01-16 22:33:36 '---' `--`---' `----'
2025-01-16 22:33:36
2025-01-16 22:33:36 2025-01-16 22:33:36,899 INFO The server IP list of Nacos is [nacos-1:8848, nacos-2:8848, nacos-3:8848]
2025-01-16 22:33:36
2025-01-16 22:33:37 2025-01-16 22:33:37,905 INFO Nacos is starting...
2025-01-16 22:33:37
2025-01-16 22:33:38 2025-01-16 22:33:38,907 INFO Nacos is starting...
2025-01-16 22:33:38
2025-01-16 22:33:39 2025-01-16 22:33:39,911 INFO Nacos is starting...
2025-01-16 22:33:39
2025-01-16 22:33:40 2025-01-16 22:33:40,913 INFO Nacos is starting...
2025-01-16 22:33:40
2025-01-16 22:33:41 2025-01-16 22:33:41,916 INFO Nacos is starting...
2025-01-16 22:33:41
2025-01-16 22:33:42 2025-01-16 22:33:42,917 INFO Nacos is starting...
2025-01-16 22:33:42
2025-01-16 22:33:43 2025-01-16 22:33:43,858 INFO Nacos started successfully in cluster mode. use external storage
2025-01-16 22:33:43

浏览器中访问 Nacos 地址,查看集群节点:

三、其他

1、构建 Nacos 镜像时基础镜像的选择

没有使用最新的 Nacos 发行版,使用的 2.2.3 版本。Nacos 默认支持内置数据源和 MySQL 数据源,而我的数据源选择的是 PostgreSQL,需要用到数据源扩展插件 nacos-plugin/nacos-datasource-plugin-ext,该插件暂时只支持 Nacos 2.2.x 版本,防止因为版本不适配问题,Nacos 选择 2.2.3 版本。

在 2.2.3 版本中,参考的 nacos-group/nacos-docker 项目中使用的是 centos 镜像作为基础镜像,而该镜像大小为 300 MB,在最新的 Nacos 发行版中,使用的是 alpine 镜像,该镜像只有 8 MB。

所以最后构建出来的 Nacos 镜像,大小有 800 MB。啊,这个,这个有点太大了。但是,就这样吧。以后再做尝试。

2、Nacos PostgreSQL DDL

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
DROP TABLE IF EXISTS "config_info";  
CREATE TABLE "config_info" (
"id" bigserial NOT NULL,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(255) ,
"content" text NOT NULL,
"md5" varchar(32) ,
"gmt_create" timestamp(6) NOT NULL,
"gmt_modified" timestamp(6) NOT NULL,
"src_user" text ,
"src_ip" varchar(20) ,
"app_name" varchar(128) ,
"tenant_id" varchar(128) ,
"c_desc" varchar(256) ,
"c_use" varchar(64) ,
"effect" varchar(64) ,
"type" varchar(64) ,
"c_schema" text ,
"encrypted_data_key" text NOT NULL
)
;

COMMENT ON COLUMN "config_info"."id" IS 'id';
COMMENT ON COLUMN "config_info"."data_id" IS 'data_id';
COMMENT ON COLUMN "config_info"."content" IS 'content';
COMMENT ON COLUMN "config_info"."md5" IS 'md5';
COMMENT ON COLUMN "config_info"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "config_info"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "config_info"."src_user" IS 'source user';
COMMENT ON COLUMN "config_info"."src_ip" IS 'source ip';
COMMENT ON COLUMN "config_info"."tenant_id" IS '租户字段';
COMMENT ON COLUMN "config_info"."encrypted_data_key" IS '秘钥';
COMMENT ON TABLE "config_info" IS 'config_info';


-- ----------------------------
-- Table structure for config_info_aggr
-- ----------------------------
DROP TABLE IF EXISTS "config_info_aggr";
CREATE TABLE "config_info_aggr" (
"id" bigserial NOT NULL,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(255) NOT NULL,
"datum_id" varchar(255) NOT NULL,
"content" text NOT NULL,
"gmt_modified" timestamp(6) NOT NULL,
"app_name" varchar(128) ,
"tenant_id" varchar(128)
)
;
COMMENT ON COLUMN "config_info_aggr"."id" IS 'id';
COMMENT ON COLUMN "config_info_aggr"."data_id" IS 'data_id';
COMMENT ON COLUMN "config_info_aggr"."group_id" IS 'group_id';
COMMENT ON COLUMN "config_info_aggr"."datum_id" IS 'datum_id';
COMMENT ON COLUMN "config_info_aggr"."content" IS '内容';
COMMENT ON COLUMN "config_info_aggr"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "config_info_aggr"."tenant_id" IS '租户字段';
COMMENT ON TABLE "config_info_aggr" IS '增加租户字段';

-- ----------------------------
-- Records of config_info_aggr
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for config_info_beta
-- ----------------------------
DROP TABLE IF EXISTS "config_info_beta";
CREATE TABLE "config_info_beta" (
"id" bigserial NOT NULL,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(128) NOT NULL,
"app_name" varchar(128) ,
"content" text NOT NULL,
"beta_ips" varchar(1024) ,
"md5" varchar(32) ,
"gmt_create" timestamp(6) NOT NULL,
"gmt_modified" timestamp(6) NOT NULL,
"src_user" text ,
"src_ip" varchar(20) ,
"tenant_id" varchar(128) ,
"encrypted_data_key" text NOT NULL
)
;
COMMENT ON COLUMN "config_info_beta"."id" IS 'id';
COMMENT ON COLUMN "config_info_beta"."data_id" IS 'data_id';
COMMENT ON COLUMN "config_info_beta"."group_id" IS 'group_id';
COMMENT ON COLUMN "config_info_beta"."app_name" IS 'app_name';
COMMENT ON COLUMN "config_info_beta"."content" IS 'content';
COMMENT ON COLUMN "config_info_beta"."beta_ips" IS 'betaIps';
COMMENT ON COLUMN "config_info_beta"."md5" IS 'md5';
COMMENT ON COLUMN "config_info_beta"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "config_info_beta"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "config_info_beta"."src_user" IS 'source user';
COMMENT ON COLUMN "config_info_beta"."src_ip" IS 'source ip';
COMMENT ON COLUMN "config_info_beta"."tenant_id" IS '租户字段';
COMMENT ON COLUMN "config_info_beta"."encrypted_data_key" IS '秘钥';
COMMENT ON TABLE "config_info_beta" IS 'config_info_beta';

-- ----------------------------
-- Records of config_info_beta
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for config_info_tag
-- ----------------------------
DROP TABLE IF EXISTS "config_info_tag";
CREATE TABLE "config_info_tag" (
"id" bigserial NOT NULL,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(128) NOT NULL,
"tenant_id" varchar(128) ,
"tag_id" varchar(128) NOT NULL,
"app_name" varchar(128) ,
"content" text NOT NULL,
"md5" varchar(32) ,
"gmt_create" timestamp(6) NOT NULL,
"gmt_modified" timestamp(6) NOT NULL,
"src_user" text ,
"src_ip" varchar(20)
)
;
COMMENT ON COLUMN "config_info_tag"."id" IS 'id';
COMMENT ON COLUMN "config_info_tag"."data_id" IS 'data_id';
COMMENT ON COLUMN "config_info_tag"."group_id" IS 'group_id';
COMMENT ON COLUMN "config_info_tag"."tenant_id" IS 'tenant_id';
COMMENT ON COLUMN "config_info_tag"."tag_id" IS 'tag_id';
COMMENT ON COLUMN "config_info_tag"."app_name" IS 'app_name';
COMMENT ON COLUMN "config_info_tag"."content" IS 'content';
COMMENT ON COLUMN "config_info_tag"."md5" IS 'md5';
COMMENT ON COLUMN "config_info_tag"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "config_info_tag"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "config_info_tag"."src_user" IS 'source user';
COMMENT ON COLUMN "config_info_tag"."src_ip" IS 'source ip';
COMMENT ON TABLE "config_info_tag" IS 'config_info_tag';

-- ----------------------------
-- Records of config_info_tag
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for config_tags_relation
-- ----------------------------
DROP TABLE IF EXISTS "config_tags_relation";
CREATE TABLE "config_tags_relation" (
"id" bigserial NOT NULL,
"tag_name" varchar(128) NOT NULL,
"tag_type" varchar(64) ,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(128) NOT NULL,
"tenant_id" varchar(128) ,
"nid" bigserial NOT NULL
)
;
COMMENT ON COLUMN "config_tags_relation"."id" IS 'id';
COMMENT ON COLUMN "config_tags_relation"."tag_name" IS 'tag_name';
COMMENT ON COLUMN "config_tags_relation"."tag_type" IS 'tag_type';
COMMENT ON COLUMN "config_tags_relation"."data_id" IS 'data_id';
COMMENT ON COLUMN "config_tags_relation"."group_id" IS 'group_id';
COMMENT ON COLUMN "config_tags_relation"."tenant_id" IS 'tenant_id';
COMMENT ON TABLE "config_tags_relation" IS 'config_tag_relation';

-- ----------------------------
-- Records of config_tags_relation
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for group_capacity
-- ----------------------------
DROP TABLE IF EXISTS "group_capacity";
CREATE TABLE "group_capacity" (
"id" bigserial NOT NULL,
"group_id" varchar(128) NOT NULL,
"quota" int4 NOT NULL,
"usage" int4 NOT NULL,
"max_size" int4 NOT NULL,
"max_aggr_count" int4 NOT NULL,
"max_aggr_size" int4 NOT NULL,
"max_history_count" int4 NOT NULL,
"gmt_create" timestamp(6) NOT NULL,
"gmt_modified" timestamp(6) NOT NULL
)
;
COMMENT ON COLUMN "group_capacity"."id" IS '主键ID';
COMMENT ON COLUMN "group_capacity"."group_id" IS 'Group ID,空字符表示整个集群';
COMMENT ON COLUMN "group_capacity"."quota" IS '配额,0表示使用默认值';
COMMENT ON COLUMN "group_capacity"."usage" IS '使用量';
COMMENT ON COLUMN "group_capacity"."max_size" IS '单个配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "group_capacity"."max_aggr_count" IS '聚合子配置最大个数,,0表示使用默认值';
COMMENT ON COLUMN "group_capacity"."max_aggr_size" IS '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "group_capacity"."max_history_count" IS '最大变更历史数量';
COMMENT ON COLUMN "group_capacity"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "group_capacity"."gmt_modified" IS '修改时间';
COMMENT ON TABLE "group_capacity" IS '集群、各Group容量信息表';

-- ----------------------------
-- Records of group_capacity
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for his_config_info
-- ----------------------------
DROP TABLE IF EXISTS "his_config_info";
CREATE TABLE "his_config_info" (
"id" int8 NOT NULL,
"nid" bigserial NOT NULL,
"data_id" varchar(255) NOT NULL,
"group_id" varchar(128) NOT NULL,
"app_name" varchar(128) ,
"content" text NOT NULL,
"md5" varchar(32) ,
"gmt_create" timestamp(6) NOT NULL DEFAULT '2010-05-05 00:00:00',
"gmt_modified" timestamp(6) NOT NULL,
"src_user" text ,
"src_ip" varchar(20) ,
"op_type" char(10) ,
"tenant_id" varchar(128) ,
"encrypted_data_key" text NOT NULL
)
;
COMMENT ON COLUMN "his_config_info"."app_name" IS 'app_name';
COMMENT ON COLUMN "his_config_info"."tenant_id" IS '租户字段';
COMMENT ON COLUMN "his_config_info"."encrypted_data_key" IS '秘钥';
COMMENT ON TABLE "his_config_info" IS '多租户改造';


-- ----------------------------
-- Table structure for permissions
-- ----------------------------
DROP TABLE IF EXISTS "permissions";
CREATE TABLE "permissions" (
"role" varchar(50) NOT NULL,
"resource" varchar(512) NOT NULL,
"action" varchar(8) NOT NULL
)
;

-- ----------------------------
-- Records of permissions
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for roles
-- ----------------------------
DROP TABLE IF EXISTS "roles";
CREATE TABLE "roles" (
"username" varchar(50) NOT NULL,
"role" varchar(50) NOT NULL
)
;

-- ----------------------------
-- Records of roles
-- ----------------------------
BEGIN;
INSERT INTO "roles" VALUES ('nacos', 'ROLE_ADMIN');
COMMIT;

-- ----------------------------
-- Table structure for tenant_capacity
-- ----------------------------
DROP TABLE IF EXISTS "tenant_capacity";
CREATE TABLE "tenant_capacity" (
"id" bigserial NOT NULL,
"tenant_id" varchar(128) NOT NULL,
"quota" int4 NOT NULL,
"usage" int4 NOT NULL,
"max_size" int4 NOT NULL,
"max_aggr_count" int4 NOT NULL,
"max_aggr_size" int4 NOT NULL,
"max_history_count" int4 NOT NULL,
"gmt_create" timestamp(6) NOT NULL,
"gmt_modified" timestamp(6) NOT NULL
)
;
COMMENT ON COLUMN "tenant_capacity"."id" IS '主键ID';
COMMENT ON COLUMN "tenant_capacity"."tenant_id" IS 'Tenant ID';
COMMENT ON COLUMN "tenant_capacity"."quota" IS '配额,0表示使用默认值';
COMMENT ON COLUMN "tenant_capacity"."usage" IS '使用量';
COMMENT ON COLUMN "tenant_capacity"."max_size" IS '单个配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "tenant_capacity"."max_aggr_count" IS '聚合子配置最大个数';
COMMENT ON COLUMN "tenant_capacity"."max_aggr_size" IS '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "tenant_capacity"."max_history_count" IS '最大变更历史数量';
COMMENT ON COLUMN "tenant_capacity"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "tenant_capacity"."gmt_modified" IS '修改时间';
COMMENT ON TABLE "tenant_capacity" IS '租户容量信息表';

-- ----------------------------
-- Records of tenant_capacity
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for tenant_info
-- ----------------------------
DROP TABLE IF EXISTS "tenant_info";
CREATE TABLE "tenant_info" (
"id" bigserial NOT NULL,
"kp" varchar(128) NOT NULL,
"tenant_id" varchar(128) ,
"tenant_name" varchar(128) ,
"tenant_desc" varchar(256) ,
"create_source" varchar(32) ,
"gmt_create" int8 NOT NULL,
"gmt_modified" int8 NOT NULL
)
;
COMMENT ON COLUMN "tenant_info"."id" IS 'id';
COMMENT ON COLUMN "tenant_info"."kp" IS 'kp';
COMMENT ON COLUMN "tenant_info"."tenant_id" IS 'tenant_id';
COMMENT ON COLUMN "tenant_info"."tenant_name" IS 'tenant_name';
COMMENT ON COLUMN "tenant_info"."tenant_desc" IS 'tenant_desc';
COMMENT ON COLUMN "tenant_info"."create_source" IS 'create_source';
COMMENT ON COLUMN "tenant_info"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "tenant_info"."gmt_modified" IS '修改时间';
COMMENT ON TABLE "tenant_info" IS 'tenant_info';

-- ----------------------------
-- Records of tenant_info
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS "users";
CREATE TABLE "users" (
"username" varchar(50) NOT NULL,
"password" varchar(500) NOT NULL,
"enabled" boolean NOT NULL
)
;

-- ----------------------------
-- Records of users
-- ----------------------------
BEGIN;
INSERT INTO "users" VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
COMMIT;

-- ----------------------------
-- Indexes structure for table config_info
-- ----------------------------
CREATE UNIQUE INDEX "uk_configinfo_datagrouptenant" ON "config_info" ("data_id","group_id","tenant_id");

-- ----------------------------
-- Primary Key structure for table config_info
-- ----------------------------
ALTER TABLE "config_info" ADD CONSTRAINT "config_info_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table config_info_aggr
-- ----------------------------
CREATE UNIQUE INDEX "uk_configinfoaggr_datagrouptenantdatum" ON "config_info_aggr" USING btree ("data_id","group_id","tenant_id","datum_id");

-- ----------------------------
-- Primary Key structure for table config_info_aggr
-- ----------------------------
ALTER TABLE "config_info_aggr" ADD CONSTRAINT "config_info_aggr_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table config_info_beta
-- ----------------------------
CREATE UNIQUE INDEX "uk_configinfobeta_datagrouptenant" ON "config_info_beta" USING btree ("data_id","group_id","tenant_id");

-- ----------------------------
-- Primary Key structure for table config_info_beta
-- ----------------------------
ALTER TABLE "config_info_beta" ADD CONSTRAINT "config_info_beta_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table config_info_tag
-- ----------------------------
CREATE UNIQUE INDEX "uk_configinfotag_datagrouptenanttag" ON "config_info_tag" USING btree ("data_id","group_id","tenant_id","tag_id");

-- ----------------------------
-- Primary Key structure for table config_info_tag
-- ----------------------------
ALTER TABLE "config_info_tag" ADD CONSTRAINT "config_info_tag_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table config_tags_relation
-- ----------------------------
CREATE INDEX "idx_tenant_id" ON "config_tags_relation" USING btree (
"tenant_id"
);
CREATE UNIQUE INDEX "uk_configtagrelation_configidtag" ON "config_tags_relation" USING btree (
"id",
"tag_name",
"tag_type"
);

-- ----------------------------
-- Primary Key structure for table config_tags_relation
-- ----------------------------
ALTER TABLE "config_tags_relation" ADD CONSTRAINT "config_tags_relation_pkey" PRIMARY KEY ("nid");

-- ----------------------------
-- Indexes structure for table group_capacity
-- ----------------------------
CREATE UNIQUE INDEX "uk_group_id" ON "group_capacity" USING btree (
"group_id"
);

-- ----------------------------
-- Primary Key structure for table group_capacity
-- ----------------------------
ALTER TABLE "group_capacity" ADD CONSTRAINT "group_capacity_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table his_config_info
-- ----------------------------
CREATE INDEX "idx_did" ON "his_config_info" USING btree (
"data_id"
);
CREATE INDEX "idx_gmt_create" ON "his_config_info" USING btree (
"gmt_create"
);
CREATE INDEX "idx_gmt_modified" ON "his_config_info" USING btree (
"gmt_modified"
);

-- ----------------------------
-- Primary Key structure for table his_config_info
-- ----------------------------
ALTER TABLE "his_config_info" ADD CONSTRAINT "his_config_info_pkey" PRIMARY KEY ("nid");

-- ----------------------------
-- Indexes structure for table permissions
-- ----------------------------
CREATE UNIQUE INDEX "uk_role_permission" ON "permissions" USING btree (
"role",
"resource",
"action"
);

-- ----------------------------
-- Indexes structure for table roles
-- ----------------------------
CREATE UNIQUE INDEX "uk_username_role" ON "roles" USING btree (
"username",
"role"
);

-- ----------------------------
-- Indexes structure for table tenant_capacity
-- ----------------------------
CREATE UNIQUE INDEX "uk_tenant_id" ON "tenant_capacity" USING btree (
"tenant_id"
);

-- ----------------------------
-- Primary Key structure for table tenant_capacity
-- ----------------------------
ALTER TABLE "tenant_capacity" ADD CONSTRAINT "tenant_capacity_pkey" PRIMARY KEY ("id");

-- ----------------------------
-- Indexes structure for table tenant_info
-- ----------------------------
CREATE UNIQUE INDEX "uk_tenant_info_kptenantid" ON "tenant_info" USING btree (
"kp",
"tenant_id"
);

3、构建 Nacos 2.2.3 版本 alpine 镜像

开始使用的是 Nacos Group 提供的 Dockerfile,里面 2.2.3 版本镜像构建使用的是 centos,这导致了最终的 Nacos 镜像有 800 MB。太大了,而且构建过程很慢,可能也是我网络的问题,是不是还会有的工具包下载失败。

现在替换为 alpine 镜像,只需在 Dockerfile 中做如下修改即可:

1
2
3
4
5
6
7
# 基于 alpine 镜像
FROM alpine:latest

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

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

需要将 Nacos 镜像的基础镜像改为 alpine,并且需要使用 alpine 中的包管理工具 apk 下载需要使用到的软件包。

之后运行构建镜像命令。

1
2
$ docker build -f 2.2.3-alpine.dockerfile -t z2huo/nacos-dev:2.2.3-alpine .
$ docker build -f 2.2.3-centos.dockerfile -t z2huo/nacos-dev:2.2.3-centos .

3.1 注意事项

3.1.1 CRLF 问题

Shell 脚本是跟 markdown 一起存放在 Git 中的,并且 Git 配置了 git config --global core.autocrlf true 用来自动在 LF 和 CRLF 两者之间转换(因为也在 MacOS 上面,MacOS 上面默认为 LF)。docker-startup.sh 文件构建到镜像中,是需要在 Linux 中执行的,Linux 中也是 LF,所以要检查文档的换行是否为 LF。

没有检查,在启动容器时执行 docker-startup.sh 脚本时报错:

1
nacos-1  | bin/docker-startup.sh: line 6: $'\r': command not found

说明 Shell 脚本中有 CR 存在。

3.1.2 ENTRYPOINT 指定容器启动时默认执行的命令

nacos-group/nacos-docker 项目的 2.2.3 分支版本的 Dockerfile 中有如下片段:

1
ENTRYPOINT ["bin/docker-startup.sh"]

之写了需要执行的 Shell 文件,但是没有写需要使用 sh 还是 bash,像这样 ENTRYPOINT ["sh", "bin/docker-startup.sh"]。最开始构建镜像时可以成功启动容器,但是后来尝试使用 alpine 时,重新构建了 centos 镜像,发现原来没有加也不行了,启动容器时报错如下:

1
exec bin/docker-startup.sh: no such file or directory

所以将 Dockerfile 中修改为:

1
ENTRYPOINT ["bash", "bin/docker-startup.sh"]
3.1.3 选择执行 docker-startup.sh 的 Shell

docker-startup.sh 中有 set -x,这个是在 sh 中是不支持的,在 bash 中有支持。

nacos-group/nacos-docker 项目中使用 alpine 的 Dockerfile 中,需要额外安装 bash,centos 应该是自带的吧(猜测)。

1
RUN apk add --no-cache openjdk8-jre-base curl iputils ncurses vim libcurl bash

如果 ENTRYPOINT ["sh", "bin/docker-startup.sh"] 中使用 sh 执行 docker-startup.sh,会报错如下:

1
2
3
2025-01-17 13:34:38 bin/docker-startup.sh: line 6:
: not found
2025-01-17 13:34:38 bin/docker-startup.sh: set: line 14: illegal option -

不支持的命令或语法,另外还会 for 循环什么的也会报错。

所以应该这样 ENTRYPOINT ["bash", "bin/docker-startup.sh"],使用 bash 执行 docker-startup.sh

相关链接

nacos-plugin/nacos-datasource-plugin-ext

nacos-group/nacos-plugin

nacos-group/nacos-docker

nacos postgresql ddl

nacos datasource plugin

Nacos Docker 快速开始 | Nacos 官网

OB tags

#微服务 #SpringCloud #未完待续 #Docker #Nacos