构建自定义的Nacos镜像支持MySQL数据源与LDAP认证
文章目录
Nacos
官方的docker
镜像不支持LDAP
1同时在连接mysql
方面在某些版本中会出现No Datasource Set 的异常,而其官方的release版本则很很稳定,同时又支持LDAP
。目前部门很多项目都是基于docker
部署的,处于简化使用,基于部署维护等原因,我决定通过Dockerfile来构建符合自己要求的nacos
镜像,在确保性能稳定的同时也能支持ldap
登录。
构建过程
初始构建
一开始自己基于Nacos2.2.1下载的tar.gz文件进行构建,主要有如下几个步骤:
- 通过
FROM
拉取openjdk-8
基础镜像 - 拷贝并解压
nacos
压缩文件 - 通过sed命令来替换
application.properties
中的相关配置 - 通过
startup.sh -m standalone
启动nacos
初步的Dockerfile
如下
FROM openjdk:8-jdk
MAINTAINER 卢运强 "yunqiang.lu@hirain.com"
# 在联网环境下可以通过wget直接下载压缩文件
COPY nacos-server-2.2.1.tar.gz /home/nacos-server-2.2.1.tar.gz
WORKDIR /home
RUN echo "解压nacos文件"
RUN tar -zxvf nacos-server-2.2.1.tar.gz
RUN rm -rf nacos-server-2.2.1.tar.gz nacos/conf/*.sql nacos/conf/*.example nacos/bin/*
COPY startup.sh /home/nacos/bin/startup.sh
RUN mkdir -p /home/nacos/logs
#开始修改配置文件
ARG conf=nacos/conf/application.properties
RUN sed -i "s/server.servlet.contextPath=\/nacos/server.servlet.contextPath=\${SERVER_SERVLET_CONTEXTPATH:\/nacos}/g" $conf
RUN sed -i "s/server.port=8848/server.port=\${NACOS_SERVER_PORT:8848}/g" $conf
#RUN sed -i "s/\#.*spring.datasource.platform=mysql/spring.datasource.platform=\${SPRING_DATASOURCE_PLATFORM:\"mysql\"}/g" $conf
RUN sed -i "s/\#.*spring.sql.init.platform=mysql/spring.sql.init.platform=\${SPRING_DATASOURCE_PLATFORM:mysql}/g" $conf
RUN sed -i "s/\#.*db.num=1/db.num=1/g" $conf
RUN sed -i "s/\#.*db.url.0.*/db.url.0=jdbc:mysql:\/\/\${MYSQL_SERVICE_HOST}:\${MYSQL_SERVICE_PORT:3306}\/\${MYSQL_SERVICE_DB_NAME}\?characterEncoding=utf8\&connectTimeout=1000\&socketTimeout=3000\&autoReconnect=true/g" $conf
RUN sed -i "s/\#.*db.user.0=nacos/db.user=\${MYSQL_SERVICE_USER:root}/g" $conf
RUN sed -i "s/\#.*db.password.0=nacos/db.password=\${MYSQL_SERVICE_PASSWORD}/g" $conf
RUN sed -i "s/.*server.tomcat.accesslog.enabled.*/server.tomcat.accesslog.enabled=\${TOMCAT_ACCESSLOG_ENABLED:false}/g" $conf
RUN sed -i "s/.*nacos.core.auth.plugin.nacos.token.secret.key=.*/nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789/g" $conf; fi
RUN chmod +x /home/nacos/bin/startup.sh
ENTRYPOINT ["/bin/bash","/home/nacos/bin/startup.sh","-m","standalone"]
基于上述文件构建的镜像通过docker run
指令执行时一直启动不成功,而在Linux
终端中通过bash startup.sh -m standlone
的方式则可以顺利启动nacos
,初次尝试失败!
改进版本
对startup.sh
进行检查之后,发现其主要是通过如下的nohup
指令启动的
if [[ "$JAVA_OPT_EXT_FIX" == "" ]]; then
nohup "$JAVA" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
else
nohup "$JAVA" "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
fi
而docker
默认支不支持nohup
2,无奈之下只能去nacos
官网寻找帮助,在其官方GtiHub中找到了一个文档Dockerfile,其中的启动脚本为docker-startup.sh
,对比startup.sh
发现主要的差异是前者是采用exec
而非 nohup
,于是将Dockerfile
仿照官方说明修改如下,之后能正常启动
FROM openjdk:8-jdk
MAINTAINER 卢运强 "lucumt@gmail.com"
RUN echo $JAVA_HOME
#ENV BASE_DIR="/home/nacos"
ENV MODE="standalone" \
PREFER_HOST_MODE="ip"\
BASE_DIR="/home/nacos" \
CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
FUNCTION_MODE="all" \
JAVA_HOME="/usr/local/openjdk-8" \
NACOS_USER="nacos" \
JAVA="/usr/local/openjdk-8/bin/java" \
JVM_XMS="1g" \
JVM_XMX="1g" \
JVM_XMN="512m" \
JVM_MS="128m" \
JVM_MMS="320m" \
NACOS_DEBUG="y" \
TOMCAT_ACCESSLOG_ENABLED="false" \
TIME_ZONE="Asia/Shanghai"
# 在联网环境下可以通过wget直接下载压缩文件
COPY nacos-server-2.2.1.tar.gz /home/nacos-server-2.2.1.tar.gz
WORKDIR /home
RUN echo "解压nacos文件"
RUN tar -zxvf nacos-server-2.2.1.tar.gz
RUN rm -rf nacos-server-2.2.1.tar.gz nacos/conf/*.sql nacos/conf/*.example nacos/bin/*
COPY docker-startup.sh /home/nacos/bin/docker-startup.sh
RUN mkdir -p /home/nacos/logs
#开始修改配置文件
ARG conf=nacos/conf/application.properties
RUN sed -i "s/server.servlet.contextPath=\/nacos/server.servlet.contextPath=\${SERVER_SERVLET_CONTEXTPATH:\/nacos}/g" $conf
RUN sed -i "s/server.port=8848/server.port=\${NACOS_SERVER_PORT:8848}/g" $conf
#RUN sed -i "s/\#.*spring.datasource.platform=mysql/spring.datasource.platform=\${SPRING_DATASOURCE_PLATFORM:\"mysql\"}/g" $conf
RUN sed -i "s/\#.*spring.sql.init.platform=mysql/spring.sql.init.platform=\${SPRING_DATASOURCE_PLATFORM:mysql}/g" $conf
RUN sed -i "s/\#.*db.num=1/db.num=1/g" $conf
RUN sed -i "s/\#.*db.url.0.*/db.url.0=jdbc:mysql:\/\/\${MYSQL_SERVICE_HOST}:\${MYSQL_SERVICE_PORT:3306}\/\${MYSQL_SERVICE_DB_NAME}\?characterEncoding=utf8\&connectTimeout=1000\&socketTimeout=3000\&autoReconnect=true/g" $conf
RUN sed -i "s/\#.*db.user.0=nacos/db.user=\${MYSQL_SERVICE_USER:root}/g" $conf
RUN sed -i "s/\#.*db.password.0=nacos/db.password=\${MYSQL_SERVICE_PASSWORD}/g" $conf
RUN sed -i "s/.*server.tomcat.accesslog.enabled.*/server.tomcat.accesslog.enabled=\${TOMCAT_ACCESSLOG_ENABLED:false}/g" $conf
RUN sed -i "s/.*nacos.core.auth.plugin.nacos.token.secret.key=.*/nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789/g" $conf
RUN chmod +x /home/nacos/bin/docker-startup.sh
ENTRYPOINT ["/bin/bash","/home/nacos/bin/docker-startup.sh","-m","standalone"]
支持LDAP
结合公司的实际情况,在部门内部使用时一般采用LDAP
登录,而交付给客户时更多的采用普通账号登录,为此需要2份Dockerfile
来构建2个不同的镜像,处于简化维护的考虑,自己决定采用1份Dockerfile
文件根据构建参数来动态的生成不同的镜像。
在网络上搜索后发现可以在Dockerfile
中执行类似if else的指令3,于是在原有的Dockerfile
基础上添加如下指令即可动态的支持LDAP
登录
ARG LOGIN_TYPE=nacos
RUN sed -i "s/nacos.core.auth.system.type=.*/nacos.core.auth.system.type=${LOGIN_TYPE}/g" $conf
RUN if [ $LOGIN_TYPE = "nacos" ];then echo "基于普通登录方式构建";else echo "基于ldap登录方式构建"; fi
# ldap登录认证方式的额外处理
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.url=.*/nacos.core.auth.ldap.url=\${LDAP_URL}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.basedc=.*/nacos.core.auth.ldap.basedc=\${LDAP_BASE_DC}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.userDn=.*/nacos.core.auth.ldap.userDn=\${LDAP_USER_DN}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.password=.*/nacos.core.auth.ldap.password=\${LDAP_USER_PASSWORD}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.filter.prefix=.*/nacos.core.auth.ldap.filter.prefix=\${LDAP_UID}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.case.sensitive=.*/nacos.core.auth.ldap.case.sensitive\${LDAP_CASE_SENSITIVE}/g" $conf; fi
最终文件
Dockerfile
FROM openjdk:8-jdk
MAINTAINER 卢运强 "lucumt@gmail.com"
RUN echo $JAVA_HOME
#ENV BASE_DIR="/home/nacos"
ENV MODE="standalone" \
PREFER_HOST_MODE="ip"\
BASE_DIR="/home/nacos" \
CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
FUNCTION_MODE="all" \
JAVA_HOME="/usr/local/openjdk-8" \
NACOS_USER="nacos" \
JAVA="/usr/local/openjdk-8/bin/java" \
JVM_XMS="1g" \
JVM_XMX="1g" \
JVM_XMN="512m" \
JVM_MS="128m" \
JVM_MMS="320m" \
NACOS_DEBUG="y" \
TOMCAT_ACCESSLOG_ENABLED="false" \
TIME_ZONE="Asia/Shanghai"
# 在联网环境下可以通过wget直接下载压缩文件
COPY nacos-server-2.2.1.tar.gz /home/nacos-server-2.2.1.tar.gz
WORKDIR /home
RUN echo "解压nacos文件"
RUN tar -zxvf nacos-server-2.2.1.tar.gz
RUN rm -rf nacos-server-2.2.1.tar.gz nacos/conf/*.sql nacos/conf/*.example nacos/bin/*
COPY docker-startup.sh /home/nacos/bin/docker-startup.sh
RUN mkdir -p /home/nacos/logs
#开始修改配置文件
ARG conf=nacos/conf/application.properties
RUN sed -i "s/server.servlet.contextPath=\/nacos/server.servlet.contextPath=\${SERVER_SERVLET_CONTEXTPATH:\/nacos}/g" $conf
RUN sed -i "s/server.port=8848/server.port=\${NACOS_SERVER_PORT:8848}/g" $conf
#RUN sed -i "s/\#.*spring.datasource.platform=mysql/spring.datasource.platform=\${SPRING_DATASOURCE_PLATFORM:\"mysql\"}/g" $conf
RUN sed -i "s/\#.*spring.sql.init.platform=mysql/spring.sql.init.platform=\${SPRING_DATASOURCE_PLATFORM:mysql}/g" $conf
RUN sed -i "s/\#.*db.num=1/db.num=1/g" $conf
RUN sed -i "s/\#.*db.url.0.*/db.url.0=jdbc:mysql:\/\/\${MYSQL_SERVICE_HOST}:\${MYSQL_SERVICE_PORT:3306}\/\${MYSQL_SERVICE_DB_NAME}\?characterEncoding=utf8\&connectTimeout=1000\&socketTimeout=3000\&autoReconnect=true/g" $conf
RUN sed -i "s/\#.*db.user.0=nacos/db.user=\${MYSQL_SERVICE_USER:root}/g" $conf
RUN sed -i "s/\#.*db.password.0=nacos/db.password=\${MYSQL_SERVICE_PASSWORD}/g" $conf
RUN sed -i "s/.*server.tomcat.accesslog.enabled.*/server.tomcat.accesslog.enabled=\${TOMCAT_ACCESSLOG_ENABLED:false}/g" $conf
RUN sed -i "s/.*nacos.core.auth.plugin.nacos.token.secret.key=.*/nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789/g" $conf
ARG LOGIN_TYPE=nacos
RUN sed -i "s/nacos.core.auth.system.type=.*/nacos.core.auth.system.type=${LOGIN_TYPE}/g" $conf
RUN if [ $LOGIN_TYPE = "nacos" ];then echo "基于普通登录方式构建";else echo "基于ldap登录方式构建"; fi
# ldap登录认证方式的额外处理
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.url=.*/nacos.core.auth.ldap.url=\${LDAP_URL}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.basedc=.*/nacos.core.auth.ldap.basedc=\${LDAP_BASE_DC}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.userDn=.*/nacos.core.auth.ldap.userDn=\${LDAP_USER_DN}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.password=.*/nacos.core.auth.ldap.password=\${LDAP_USER_PASSWORD}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.filter.prefix=.*/nacos.core.auth.ldap.filter.prefix=\${LDAP_UID}/g" $conf; fi
RUN if [ $LOGIN_TYPE = "ldap" ];then sed -i "s/\#nacos.core.auth.ldap.case.sensitive=.*/nacos.core.auth.ldap.case.sensitive\${LDAP_CASE_SENSITIVE}/g" $conf; fi
RUN chmod +x /home/nacos/bin/docker-startup.sh
ENTRYPOINT ["/bin/bash","/home/nacos/bin/docker-startup.sh","-m","standalone"]
构建方式
在构建时需要将Dockerfile
、docker-startup.sh
以及对应的nacos
压缩文件放到同一个目录下
-
普通登录方式构建
# 不传递登录参数 docker build -t nacos_custom:v1.0 . # 显示指定登录参数 docker build -t nacos_custom:v1.0 --build-arg LOGIN_TYPE=nacos .
-
LDAP
登录方式构建docker build -t nacos_custom:v1.0 --build-arg LOGIN_TYPE=ldap .
使用方式
假设存储数据库为mysql
采用docker-compose方式登录,相关的docker-compose.yml
文件如下:
-
普通方式登录
version: "3" services: nacos: image: nacos_custom:v1.0 restart: always container_name: nacos_custom ports: - 8858:8858 environment: - TZ=Asia/Shanghai - NACOS_SERVER_PORT=8858 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=xxxx - MYSQL_SERVICE_PORT=xxxx - MYSQL_SERVICE_DB_NAME=nacos_test - MYSQL_SERVICE_USER=root - MYSQL_SERVICE_PASSWORD=654321 volumes: - $PWD/logs:/home/nacos/logs/
-
LDAP
登录version: "3" services: nacos: image: nacos_custom:v1.0 restart: always container_name: nacos_custom ports: - 8858:8858 environment: - TZ=Asia/Shanghai - NACOS_SERVER_PORT=8858 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=xxxx - MYSQL_SERVICE_PORT=3316 - MYSQL_SERVICE_DB_NAME=nacos_test - MYSQL_SERVICE_USER=root - MYSQL_SERVICE_PASSWORD=xxxx - LDAP_URL=ldap://xxxx:389 - LDAP_BASE_DC=dc=xxx,dc=xxx - LDAP_USER_DN=cn=xxx,dc=xxx,dc=com - LDAP_USER_PASSWORD=xxxx - LDAP_UID=uid - LDAP_CASE_SENSITIVE=false volumes: - $PWD/logs:/home/nacos/logs/
镜像参数说明
属性 | 作用 | 默认值 | 可选值 |
---|---|---|---|
NACOS_SERVER_PORT | nacos服务器端口 | 8848 | |
SPRING_DATASOURCE_PLATFORM | 指定nacos的数据源 | mysql | mysql 或空 |
MYSQL_SERVICE_HOST | mysql服务器地址 | ||
MYSQL_SERVICE_PORT | mysql服务器端口 | 3306 | |
MYSQL_SERVICE_DB_NAME | mysql数据库名称 | ||
MYSQL_SERVICE_USER | mysql数据库用户名 | root | |
MYSQL_SERVICE_PASSWORD | mysql数据据密码 | ||
LDAP_URL | ldap服务的地址和端口号 | ||
LDAP_BASE_DC | ldap搜索范围 | ||
LDAP_USER_DN | ldap绑定账号4 | ||
LDAP_USER_PASSWORD | ldap绑定账号的密码 | ||
LDAP_UID | 用户账号字段 | ||
LDAP_CASE_SENSITIVE | ldap认证时是否大小写敏感 |