docker中搭建nacos并将springboot项目的配置文件转移到nacos中

前言

网上搜索docker中搭建nacos发现文章不是很好理解,正好最近在搭建nacos练手。记录一下整个搭建过程。


docker中搭建nacos并将springboot项目的配置文件转移到nacos中

1 docker中下拉nacos镜像

下拉镜像(这里不下拉也ok,后面执行run的时候没有就自己去下拉了)

docker pull nacos/nacos-server:v2.4.2

我本来下拉的时候没有加版本号也就是默认下拉了最新的,但是启动报错说java版本不适配。所以这里指定了版本。

拉下来之后可以通过以下命令查询docker中的镜像

docker images

2 配置nacos信息

1. 创建docker的挂载目录,实现数据的持久化

创建挂载目录 新建logs目录

mkdir -p /mydata/nacos/logs/

新建conf目录

mkdir -p /mydata/nacos/conf/

2. 复制nacos默认配置文件到宿主机的挂载目录中

因为需要使用到nacos中的默认配置文件,如果直接将宿主机的目录挂载到docker容器中,会导致宿主机的空目录覆盖容器原本的默认配置文件。因此 我们需要先不挂载目录启动一下容器,将配置文件拷贝出来。然后再挂在启动容器。

否则会报如下错误:找不到nacos-logback.xml文件。

启动容器

docker run -p 28848:8848 --name nacos -d nacos/nacos-server

复制文件

cp nacos:/home/nacos/logs/ /mydata/nacos/

cp nacos:/home/nacos/conf/ /mydata/nacos/

复制完可以在宿主机中查看目录中的东西,如下,已经存在上面报错找不到的nacos-logbask.xml文件

删除容器

刚刚创建的容器只是为了拷贝出默认的配置文件,这里就需要把容器停止,删除,然后重新创建。

可以使用-f参数,强制删除。如果不添加-f 则只能删除停止运行的容器

docker rm -f nacos

3 启动nacos

  1. 创建容器(复制一下命令执行即可)

docker run -d --name nacos -p 28848:8848 --privileged=true -e MODE=standalone -v /mydata/nacos/logs/:/home/nacos/logs -v /mydata/nacos/conf/:/home/nacos/conf/ --restart=always nacos/nacos-server:v2.4.2

参数解释:
-d:表示容器后台运行,启动之后会返回一个容器id
-p注意我这里使用了宿主机的28848端口 是将容器的8848端口映射到28848端口,为什么不用宿主机的8848端口这样做主要是防止网络上的恶意攻击。
--privileged:true表示容器以特权模式运行,表示容器可以执行一些通常受限的操作。
-e MODE=standalone:表示nacos为单机模式运行,默认是集群方式运行 参数为:cluster。
-v: 就是将容器里面两个重要的文件夹映射到我们宿主机上刚刚创建的两个文件夹中。方便我们操作管理。
--restart always: 表示容器如果意外关闭,docker会自动重启该容器。
nacos/nacos-server:是指镜像名称,就是我们第一步下拉下来的镜像名字。

启动完成之后可以查看一下docker容器的情况,如下

4 配置nginx映射nacos配置后台

查找宿主机上的nginx.conf文件位置

find / -name nginx.conf

找到配置文件路径之后使用vim打开编辑

vim /你找到的路径/nginx.conf

在配置文件中添加以下配置信息

sell 复制代码
                location ~ (^/nacos).* {
                        proxy_pass http://127.0.0.1:28848;
                        #proxy_set_header Host                $host:$server_port;
                }

配置之后保存

检查配置文件格式是否正确

nginx -t

然后重启nginx

sudo nginx -s reload

注意添加sudo 和-s 防止nginx重启的时候没有完全重启,导致配置一直不生效
sudo 以root权限执行此命令。因为nginx涉及到重要资源的配置如果端口443 8080。这些资源一般只有root用户或者设置的其它具备管理权限的用户才可以操作。因此防止启动不生效最好添加上。笔者之前因为不添加这个排查过很多次nginx启动了还不生效的问题(很多时候是关闭没有关闭掉,有启动了多个nginx。相互之间影响导致不生效)

外网访问 输入你的域名或者ip加 /nacos 即可看到

5 配置nacos开启登录验证

此时已经可以正常启动了

但是正常项目中一定是需要鉴权的。所以下面通过配置application.properties文件开启登录验证

我在这一步遇到很多问题,
启动之后如果大家也遇到问题可以进入到我们配置的log目录中查看具体的报错信息

tail -f /mydata/nacos/logs/nacos.log

配置大部分是操作application.properties 文件,我这里附上一份我已经亲测调试好的。里面#中文提示的需要改成你的环境配置,具体修改方法看下面操作步骤

java 复制代码
# 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=mysql 
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://你的ip地址:23306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
# 数据库的账号************************************************************************
db.user.0=heibaike
# 数据库的密码************************************************************************
db.password.0=password

# 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:
# 你生成的的base64密钥************************************************************************
nacos.core.auth.plugin.nacos.token.secret.key=${NACOS_AUTH_TOKEN:PQdq6s7A13******zJKcok1yyvBnSuELY=} 
### 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}
# 服务端认证需要的key************************************************************************
nacos.core.auth.server.identity.key=${NACOS_AUTH_IDENTITY_KEY:liulu}
# 服务端认证需要的value************************************************************************
nacos.core.auth.server.identity.value=${NACOS_AUTH_IDENTITY_VALUE:liulu}
# 开启鉴权************************************************************************
nacos.core.auth.enabled=true
# 你自定义的用户名************************************************************************
cos.core.auth.username=username
# 你自定义的密码************************************************************************
nacos.core.auth.password=liulu


## 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. 我在配置文件application.properties 中开启鉴权

nacos.core.auth.enabled=true

之后重启镜像报错说没有生成合适的token

  1. 然后我又在配置文件中修改了

nacos.core.auth.plugin.nacos.token.secret.key=yoUNZzcOU/x/0T**********He3tJgq1oVobClEvdUg=

这个值需要大家自己生成一个合适的Base64编码密钥,可以通过一下方法生成

java 复制代码
import java.util.Base64;

public class Main {
    public static void main(String[] args) {
        String secret = "your-32-byte-long-secret-key";
        String base64Encoded = Base64.getEncoder().encodeToString(secret.getBytes());
        System.out.println(base64Encoded);
    }
}

运行上述代码并将输出的 Base64 编码密钥放入配置文件中。

然后重启镜像说没有nacos.core.auth.server.identity.key

  1. 配置nacos.core.auth.server.identity.key

默认的如下:

nacos.core.auth.server.identity.key={NACOS_AUTH_IDENTITY_KEY:} nacos.core.auth.server.identity.value={NACOS_AUTH_IDENTITY_VALUE:}

这里只需要在参数中:后面自定义值就可以,如下

nacos.core.auth.server.identity.key={NACOS_AUTH_IDENTITY_KEY:heibaike} nacos.core.auth.server.identity.value={NACOS_AUTH_IDENTITY_VALUE:wanghaixin}

然后保存文件 重启docker容器

docker restart nacos

搞定!

6 配置数据库

之前已经正常运行起来,但是数据库使用的是nacos内置的数据库,可能会有数据丢失的风险,这里演示如何使用外部数据库

我使用的是mysql数据库,这里演示数据库配置

在数据库中创建数据库nacos_config

然后在数据库中执行/mydata/nacos/conf/目录中的mysql-schema.sql1.4.0-ipv6_support-update.sqlsql文件生成初始数据库。

然后编辑/mydata/nacos/conf/目录中application.properties

java 复制代码
db.url.0=jdbc:mysql://182.***.72:3306/nacos_config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
db.user.0=root
db.password.0=123456

如上设置自己的账号密码,注意如果是在mysql服务在同一个电脑上不可以使用127.0.0.1或者localhost。
因为在docker容器中,127.0.0.1或者localhost代表的是容器本身的网络,而不是宿主机的网络,因此这里使用宿主机的真实ip

配置完成之后重启dockers容器

docker restart nacos

这块我配置的过程中不知道哪里写错了还是怎的,我猜测是因为向服务器上面复制的时候意外粘贴到了vim的命令行中,触发了某些参数,导致我复制的时候复制不进去,并且会改文件中的文件,导致怎么都运行不起来了。如果大家也遇到看不出来的问题也通过复制上面完整的配置文件放到本地重新赋值里面的环境,再把配置文件上传到服务器上解决问题

7 项目中配置nacos

nacos配置

nacos配置中创建命名空间

点击命名空间

创建配置

数据库是mongdb

项目中 引入pom依赖

java 复制代码
        <!--bootstrap-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.5</version>
        </dependency>
        <!--nacos配置-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

resources目录下新建 bootstrap.yml

java 复制代码
spring:
  application:
    # 确保这个与 Nacos 中的 Data ID 前缀保持一致
    name: application.yml
  cloud:
    nacos:
      config:
        # Nacos 服务器地址
        server-addr: 39.99.$$.$$1:28848
        # 配置文件的格式
        file-extension: yaml
        # Nacos 中的 group 名称
        group: USER_GROUP
        # Nacos 中的 group 名称
        namespace: 01af5f95-0##2-##f1-ab99-b###bb6b082

注释掉原来的配置文件如application.yml

启动运行 搞定

mysql数据库项目

pom.xml中引入依赖

java 复制代码
        <!--bootstrap-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.5</version>
        </dependency>
        <!--nacos配置-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <!-- 引入阿里数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>

引入配置文件bootstrap.yml

java 复制代码
spring:
  application:
    name: springboot-nacos
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        # 配置中心的地址
        server-addr: 127.**.0.**:8848
        # 配置文件prefix
        prefix: application.yaml
        # 配置文件的格式
        file-extension: yaml
        # 配置文件的环境
        group: USER_GROUP
        # 命名空间
        namespace: d88&&e-13%%d-47#b-b42e-cdc##2501273

引入配置文件:DruidDataSourceWrapper

java 复制代码
package cn.wanghaixin.solution.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;


@Configuration
@RefreshScope
public class DruidDataSourceWrapper extends DruidDataSource implements InitializingBean {
//这个对应这nacos配置的yaml中的数据库路径
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    private String passwordCallbackClassName;

    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }

    public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    @Override
    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    @Override
    public void setPasswordCallbackClassName(String passwordCallbackClassName) {
        this.passwordCallbackClassName = passwordCallbackClassName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 如果未找到前缀"spring.datasource.druid"JDBC属性,将使用"Spring.DataSource"前缀JDBC属性。
        super.setUrl(url);
        super.setUsername(username);
        super.setPassword(password);
        super.setDriverClassName(driverClassName);
        super.setInitialSize(initialSize);
        super.setMinIdle(minIdle);
        super.setMaxActive(maxActive);
        super.setMaxWait(maxWait);
        super.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        super.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        super.setValidationQuery(validationQuery);
        super.setTestWhileIdle(testWhileIdle);
        super.setTestOnBorrow(testOnBorrow);
        super.setTestOnReturn(testOnReturn);
        super.setPoolPreparedStatements(poolPreparedStatements);
        super.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        super.setDbType(dbType);
        super.setPasswordCallbackClassName(passwordCallbackClassName);
    }
}

创建配置文件:NacosConfigConfiguration

java 复制代码
package cn.wanghaixin.solution.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@EnableAutoConfiguration
@Configuration
public class NacosConfigConfiguration  {

    @Bean(initMethod = "init")
    @ConditionalOnMissingBean
    @RefreshScope
    public DruidDataSource dataSource() {
        return new DruidDataSourceWrapper();
    }
}

注释掉原来的配置文件

8 效果图

其它问题

vim问题

可能是我在复制信息的时候,意外在命令模式输入了,导致我继续再编辑模式复制时,复制不上,并且会改变文件中原本有的内容。 尝试了很多方法都没有解决,为了进度,我暂时通过其它方式达到了目的。但是这个问题没有解决!!

有知道的小伙伴可以留言,还请赐教!!

nacos版本问题

我最开始下拉镜像的时候是直接下拉了官方最新的

docker pull nacos/nacos-server

运行竟然报一下错误,搜索了一下这个方法是java

vim打开配置文件之后粘贴不进去

我使用的是xshell 比如我复制了数据库的url粘贴到vim打开的文本时,光标在文本中进行了跳动,并没有粘贴进去我指定的内容。

问题原因:vim的自动缩进造成的

解决方法:

使用 :set paste命令

进入 Vim 后,输入 :set paste 并回车。

然后按 i 进入插入模式,尝试右键粘贴文本。

粘贴完成后,输入 :set nopaste 回到正常模式。

然后i 进入输入模式,然后粘贴即可

初始化数据库

报错: Invalid default value for 'gmt_create'

在5.6.5之后的版本才能使用CURRENT_TIMESTAMP作为DATETIME的默认值,但是当前MySQL数据库的版本为5.5,CURRENT_TIMESTAMP只能作为TIMESTAMP的默认值。

可以通过一下命令查看数据库版本,进一步确定问题

SELECT VERSION();

解决方法

  1. 将datetime类型改为timestamp类型即可。
  2. 去掉DEFAULT CURRENT_TIMESTAMP即可。

权限认证失败

首次登录提示:

权限认证失败

没有 命名空间的访问权限!

不用管哈哈 。重新登陆就没有了

新建命名空间失效

配置文件中,指定初始化数据库类型的位置

spring.sql.init.platform=${SPRING_DATASOURCE_PLATFORM:}

显示调整为mysql

spring.sql.init.platform=mysql

相关推荐
Abladol-aj1 小时前
并发和并行的基础知识
java·linux·windows
清水白石0081 小时前
从一个“支付状态不一致“的bug,看大型分布式系统的“隐藏杀机“
java·数据库·bug
JunLan~5 小时前
Rocky Linux 系统安装/部署 Docker
linux·docker·容器
吾日三省吾码6 小时前
JVM 性能调优
java
弗拉唐7 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
海岛日记7 小时前
centos一键卸载docker脚本
linux·docker·centos
oi778 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
2401_857610038 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
少说多做3438 小时前
Android 不同情况下使用 runOnUiThread
android·java