内网环境使用docker部署微服务系统记录

背景

内网环境部署一套微服务应用系统,采用docker方式部署。包括mysql、redis、nginx、nacos、gateway以及应用程序的jar包。下面记录部署的过程和遇到的问题。

一、内网dockcer部署mysql服务

内网生成mysql镜像

  1. 在一个可以连接外网的环境中,下载mysql镜像:
bash 复制代码
docker pull mysql:5.7
  1. 将镜像打包:
bash 复制代码
docker save -o mysql.tar mysql:5.7
  1. 将打好的mysql.tar包传到内网服务器中,解压:
bash 复制代码
docker load -i mysql.tar 

此时,内网环境中就具备了mysql镜像。执行docker images命令可以查看是否有mysql镜像。

mysql容器启动

  1. 在内网宿主机上创建mysql容器的挂载目录,分别为:

创建数据目录:

bash 复制代码
mkdir /usr/local/mysql/data

创建配置文件目录:

bash 复制代码
mkdir /usr/local/mysql/conf

创建日志目录:

bash 复制代码
mkdir /usr/local/mysql/logs

创建配置文件:

bash 复制代码
cd /usr/local/mysql/conf
touch my.cnf
  1. 启动mysql容器:
bash 复制代码
docker run -p 3306:3306 --name mysql -v /usr/local/mysql/conf:/etc/mysql/conf.d -v /usr/local/mysql/logs:/logs  -v /usr/local/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.40

其中,通过-e 参数设置mysql的登录密码。

启动容器后,在/data目录下,就有了数据库的数据文件。

  1. 远程连接数据库,创建数据库。至此,mysql部署完成。

踩坑记录

如果启动docker容器时,查看容器的日志报错:(13: Permission denied)。

查阅资料给出的解决方案是docker启动容器命令增加 --privileged=true 参数,但是并没有效果。经过多次尝试,通过赋予宿主机mysql挂载文件权限接口:

bash 复制代码
chmod -R 777 /usr/local/mysql/

这样就解决了容器日志报权限不足的问题。在下面的redis容器,nginx容器部署时,也报这个错误,解决方案都是给挂载文件目录赋予权限解决。

二、内网dockcer部署redis服务

与mysql步骤类似,下面记录一下步骤过程:

  1. 外网环境拉取redis镜像:
bash 复制代码
docker pull redis
  1. 镜像文件打包:
bash 复制代码
docker save -o redis.tar redis
  1. 将redis.tar复制到内网环境,解压:
bash 复制代码
docker load -i redis.tar 
  1. 内网宿主机创建挂载目录:
bash 复制代码
mkdir /usr/local/redis/conf
bash 复制代码
mkdir /usr/local/redis/data
bash 复制代码
touch /usr/local/redis/redis.log
chmod 777 redis.log
  1. 配置redis配置文件redis.conf
bash 复制代码
#bind 127.0.0.1            #注释掉这部分,使redis可以外部访问
requirepass 123456  
logfile /data/redis.log  
protected-mode no  


# 设置 RDB 文件名和文件路径
dbfilename dump.rdb 
dir /data
#----------------------------------------------------------------------(下面的不用修改)
# RDB 默认的设置 ,可以按照如下规则,根据自己的实际请求压力进行设置调整。
# 如果900秒内有1条Key信息发生变化,则进行快照;
save 900 1
#如果300秒内有10条Key信息发生变化,则进行快照;
save 300 10
#如果60秒内有10000条Key信息发生变化,则进行快照。
save 60 10000

# 启动备份文件压缩
rdbcompression yes
#redis 5之后,64位的CRC冗余校验码会放在RDB文件的末尾,以对文件完整性进行验证,但是在保存和加载RDB文件时,会损失10%左右的性能
rdbchecksum yes
# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

#---------------------AOF配置文件---------------------------
# 开启AOF 备份
appendonly yes
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir /data

# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# 同步策略
# appendfsync always
appendfsync everysec
# appendfsync no

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 触发设置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof出错如何处理
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes
  1. 将redis.conf传到宿主机/usr/local/redis/conf目录下
  2. 启动镜像:
bash 复制代码
docker run -d --name redis -p 6379:6379 --restart=always -v /usr/local/redis/conf:/usr/local/etc/redis -v /usr/local/redis/data:/data redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes

三、内网docker部署nginx服务

  1. 外网环境下载nginx镜像:
bash 复制代码
docker pull nginx
bash 复制代码
docker save -o nginx.tar nginx
  1. 将tar包放入内网环境,解压:
bash 复制代码
docker load -i nginx.tar
  1. 宿主机创建挂载目录:
bash 复制代码
mkdir /usr/local/nginx/web
  1. 第一次启动nginx容器,目的是复制容器内部nginx相关文件到宿主机:
bash 复制代码
docker run -d --name nginx -p 3100:80  -v /usr/local/nginx/web:/usr/share/nginx/html nginx
  1. 复制文件到宿主机:
bash 复制代码
docker cp nginx:/etc/nginx /usr/local/nginx

此时,在/usr/local/nginx/nginx下就有了nginx的相关文件,如下图:

  1. 停止并删除刚刚启动的nginx容器:
bash 复制代码
docker stop  nginx
bash 复制代码
docker rm nginx
  1. 修改上图中conf.d/default.conf文件,配置nginx转发信息
bash 复制代码
server {
    listen       3100;
    server_name  localhost;
    location / {
            root    /usr/share/nginx/html/xxx/portal; #/usr/share/nginx/html对应/usr/local/nginx/web路径,后面填项目路径

          index  index.html index.htm;
          if (!-e $request_filename) {
            rewrite ^(.*)$ /index.html?s=$1 last;
            break;
            }
        }
        
    
    location ^~ /xxx-gateway/{
          proxy_pass              http://xxx.xxx.xxx.xxx:9999/;
          proxy_set_header        X-Real-IP $remote_addr;
          proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

       }

}
  1. 将前端工程放入到web路径下。
  2. 启动nginx容器:
bash 复制代码
docker run -d --name nginx -p 3100:3100  -v /usr/local/nginx/nginx/:/etc/nginx -v /usr/local/nginx/web:/usr/share/nginx/html nginx

四、java服务jar包镜像制作

nacos、gateway和应用微服务都采用jar包形式部署,这里以nacos为例,记录部署过程,其他服务部署方式步骤一致。

  1. 外网环境下载jdk镜像,打包:
bash 复制代码
docker pull java:8
bash 复制代码
docker save -o  java_8.tar java:8
  1. 将java_8.tar传入内网环境,解压:
bash 复制代码
docker load -i java_8.tar
  1. 制作Dockerfile文件
bash 复制代码
FROM java:8
MAINTAINER xiaoxiaosu
#VOLUME指定临时文件目录为tmp,在主机/var/lib/docker目录下创建一个临时文件并连接到容器的tmp
#VOLUME /tmp
ADD jeecg-cloud-nacos-3.5.0.jar jeecg-cloud-nacos-3.5.0.jar
#运行jar包
RUN bash -c 'touch jeecg-cloud-nacos-3.5.0.jar'
ENTRYPOINT ["java","-jar","jeecg-cloud-nacos-3.5.0.jar"]
EXPOSE 8848
  1. 将Dockerfile和nacos.jar传入内网服务器,且在一个目录下,生成镜像:
bash 复制代码
docker build -t nacos .

至此jar包镜像生成。

  1. 启动jar包镜像:
bash 复制代码
docker run -d --network host -p 8848:8848 --name nacos nacos

注意: --network host参数是为了让容器共用宿主机ip,这样就可以通过宿主机ip访问nacos了。否则无法通过宿主机ip访问nacos。其他jar包程序也是一样。

五、使用docker-compose编排微服务

上述用了mysql、nginx、redis、nacos、gateway和三个业务微服务,一个一个启动容器很费力,因此使用docker-compose编排启动微服务。

踩坑

起初,通过depends_on参数指定各个微服务的启动顺序。发现业务微服务无法注册到nacos上,报错为连接nacos失败,微服务也起不来。

网上搜索资料得知,depends_on是微服务启动成功后,依赖于它的其他微服务就立即启动。而nacos微服务启动成功后,还需等待一段时间,才能让其他微服务去注册。因此会出现注册连接失败的问题。

网上给出的方案是使用wait-for-it脚本进行解决。博主尝试了一下并没有成功,而是用另一种方式进行了解决。

解决方案

写了两个docker-compose.yml文件,一个文件里定义nginx、redis、mysql、nacos这些基础组件。另一个文件里定义gateway和三个业务微服务。先一键启动有nacos的编排,再启动业务微服务编排。

两个docker-compose.yml放在两个文件夹,启动即可。

bash 复制代码
version: "3"
services:
  nacos:
    image: xxx_nacos
    ports:
      - "8848:8848"
    networks:
      - bonc
    depends_on:
      - mysql
  nginx:
    image: nginx
    ports:
      - "3100:3100"
    volumes:
      - /usr/local/nginx/nginx/:/etc/nginx
      - /usr/local/nginx/web:/usr/share/nginx/html
    networks:
      - bonc


  mysql:
    image: mysql:5.7.40
    container_name: mysql
    ports:
      - "3306:3306"
    volumes:
      - /usr/local/mysql/conf:/etc/mysql/conf.d
      - /usr/local/mysql/logs:/logs
      - /usr/local/mysql/data:/var/lib/mysql
    networks:
      - bonc
    environment:
      MYSQL_ROOT_PASSWORD: 123456

  redis:
    image: redis
    ports:
      - "6379:6379"
    volumes:
      - /usr/local/redis/conf:/usr/local/etc/redis
      - /usr/local/redis/data:/data
    networks:
      - bonc
    command: redis-server /usr/local/etc/redis/redis.conf --appendonly yes
networks:
  bonc:
    external: true
bash 复制代码
version: "3"
services:
  gateway:
    image: xxx_gateway
    ports:
      - "9999:9999"
    networks:
      - bonc
  xxxsystem:
    image: xxx_xxxsystem
    ports:
      - "7001:7001"
    networks:
      - bonc
  xxxsystem:
    image: xxx_system
    ports:
      - "7019:7019"
    networks:
      - bonc
  xxx:
    image: xxx
    ports:
      - "7018:7018"
    networks:
      - bonc
networks:
  bonc:
    external: true

需要注意的是docker-compose需要定义自定义网络,然后在yml里配置networks项。

分别进入两个yml目录下,执行

bash 复制代码
docker-compose up -d 

参考文章:
内网如何下载docker镜像
docker安装mysql5.7
Nginx 的 Docker 镜像使用教程
Docker安装Redis镜像

相关推荐
tangdou3690986553 小时前
Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)
docker·容器
王彬泽3 小时前
【微服务】组件、基础工程构建(day2)
微服务
Cikiss3 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss3 小时前
微服务实战——平台属性
java·数据库·后端·微服务
代码敲上天.5 小时前
数据库语句优化
android·数据库·adb
漫无目的行走的月亮6 小时前
在Docker中运行微服务注册中心Eureka
docker
攸攸太上8 小时前
JMeter学习
java·后端·学习·jmeter·微服务
妍妍的宝贝9 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
大道归简9 小时前
Docker 命令从入门到入门:从 Windows 到容器的完美类比
windows·docker·容器
zeruns80210 小时前
如何搭建自己的域名邮箱服务器?Poste.io邮箱服务器搭建教程,Linux+Docker搭建邮件服务器的教程
linux·运维·服务器·docker·网站