容器化部署

码匠君 ... 2021-10-28 大约 10 分钟

# 容器化部署

# 后端本地容器部署

本地采用容器方式进行项目的部署,因为每个人使用的电脑,操作系统都各不相同,加之不同人的喜好和偏好也不尽相同,无法做到全覆盖。

提示

这里仅以容器方式安装Nacos,ELK,Kafka,Zookeeper,Sentinel,本地安装PostgreSQL,MySQLRedis的方式,进行示意性说明。仅供参考,具体安装请结合自身及时情况,适时调整。

# 基础设施参考的安装方式如下

  1. 本地安装
  • PostgreSQL
  • MySQL
  • Redis

如果对容器比较数据,以上内容也可以以容器的方式安装

  1. 容器安装
  • Nacos
  • ELK
  • Kafka & Zookeeper
  • Sentinel

# [1]本地 Docker 安装(Windows 版)

  • Windows 本地安装 Docker 请参考个人博文:
  1. Windows 10 2004 (20H1) 安装 Docker Desktop for Windows (2.3.0.2) 以 WSL 2 方式运行容器 (opens new window)
  2. Windows 10 将 Docker Desktop for Windows(WSL 2 方式)文件存储移出 C 盘放置到其它目录 (opens new window)

# [2]安装配置 MySQL

  1. 正常安装 MySQL
  2. 创建 Nacos 持久化数据库

即在 MySQL 中,为 Nacos 新建用户,新建数据库,给数据库用户分配数据库权限。

  1. 导入 Nacos 初始脚本

下载 (opens new window)最新稳定版的 Nacos 压缩包。解压后,在{NACOS_HOME}/conf目录下,找到nacos-mysql.sql导入到数据库中。

提示

在工程的${project home}/configurations/scripts目录下,保存了一份 Nacos 脚本可以使用,如果不是最新请自行重新下载。

  1. 开放 MySQL 数据库 IP 访问

正常情况下,本地开发使用localhost就可以访问已安装的 mysql 服务; 因为 Docker 是使用内部的独立网络,Docker 内部容器想要访问外部的数据库,只能通过 ip 地址才能访问。所以需要开放数据库的 IP 访问,否则会出现 Docker 容器发无法连接数据库的情况。

使用命令行工具,登录进入 MySQL,输入以下脚本查看数据库的可访问情况:

mysql> select host,user from mysql.user;
1

查询结果示例:

| host      | user             |
| --------- | ---------------- |
| localhost | root             |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
1
2
3
4
5
6

host 字段的值是 localhost,说明只允许本地访问

找到对应你所用的用户,设置允许任意 IP 访问,执行语句:

mysql> update mysql.user set host = '%' where user = 'root';

mysql> flush privileges;
1
2
3

# [2]安装配置 PostgreSQL

  1. 安装 PostgreSQL 数据库

正常安装即可。跟随安装的 Wizard 一步一步进行即可。

  1. 创建应用数据库

参见:创建应用数据

  1. 导入建表数据

参见:导入数据库脚本

  1. 开放 IP 访问

如果想要使用 Docker 封装的服务,就需要开放PostgreSQL的 IP 访问。Windows 环境,链接PostgreSQL是主机名填写“localhost”可以正常链接,使用 IP 地址不能进行链接

${PostgreSQL_HOME}/12/data目录下,找到postgresql.confpg_hba.conf

  • 打开postgresql.conf,在 59 行,找到listen_addresses,修改为:
listen_addresses = '*'
1
  • 修改端口号打开postgresql.conf,在 63 行,找到 port

PostgreSQL 12 中,该项默认就为 ‘*’,所以可以不用修改

  • 打开pg_hba.conf,在最后增加:
host    all             all             192.168.0.0/16          trust
1

允许访问 PostgreSQL 服务器的客户端 IP 地址, 其中:192.168.0.0/16 表示允许 192.168.0.1-192.168.255.255 网段访问。可根据实际情况调整

  • 重启数据服务

# [3]安装配置 Redis

  1. 安装 Redis

正常安装即可

  1. 开放 IP 访问

redis安装目录下,找到redis.windows-service.conf

  • 56bind 127.0.0.1 注释掉,修改为
#bind 127.0.0.1
1
  • 75protected-mode 参数改为 no
protected-mode no
1

生产环境不建议这样,还是要指定具体 IP 安全一些

  • 重启服务

# [4]部署 Kafka,Zookeeper,Nacos,ELK,Sentinel Dashboard

除了MySQL,PostgreSQLRedis以外,其它相关运行环境组件 Zookeeper,Kafka,Nacos,ELK,Sentinel Dashboard,可以通过docker-compose方式进行部署,执行以下命令即可:

  • 运行容器

注意:

ELK 依赖一个重要参数 vm.max_map_count,如果这个值小于262144ELK 会无法正常启动

一种解决办法

如果是采用 WSL2 的方式运行容器,那么在 Linux 中输入以下命令

sudo -i
sudo sysctl vm.max_map_count=524288
1
2

然后在启动 Docker Desktop

另一种解决办法:

  • open powershell
  • wsl -d docker-desktop
  • echo "vm.max_map_count = 262144" > /etc/sysctl.d/99-docker-desktop.conf

参考 : https://github.com/docker/for-win/issues/5202 (opens new window)

说明

已经将 Dockerfile 以及 docker-compose 修改为参数运行。

因此运行一下命令时,请确保.env 文件在执行命令的目录下。

例如:如果在C:\Users\Administrator\Desktop执行命令,那么.env文件,就需要在C:\Users\gengwei.zheng\Desktop目录下

docker-compose -f ${project_home}/configurations/docker/docker-compose/linux/herodotus/env.base.yml up -d
1

该命令会查看本地是否已经有了相关镜像,如果没有会首先下载镜像,然后再运行,请先保证网络畅通

  • 停止容器
docker-compose -f ${project_home}/configurations/docker/docker-compose/linux/herodotus/env.base.yml stop
1
  • 停止并删除容器
docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/env.base.yml down
1

# [5]部署 Skywalking

注意

由于 Skywalking 采用 Elasticsearch 进行数据存储,因此 Skywalking运行之前,要保证 Elasticsearch 已经正常运行。

虽然 docker-compose 有 depends_on 属性,但是该属性只能解决容器启动的先后顺序问题,并不能实现某一个容器及容器内部所有应用启动成功之后再运行的问题。

因此,这里将环境依赖的应用,拆分为两个docker-compose文件,

  • 先运行${project_home}/configurations/docker/docker-compose/linux/herodotus/env.base.yml,待所有容器及内部服务成功运行之后,
  • 再运行${project_home}/configurations/docker/docker-compose/linux/herodotus/env.skywalking.yml

通过 docker-compose 方式进行部署,执行以下命令即可:

  • 运行容器
docker-compose -f ${project_home}/configurations/docker/docker-compose/linux/herodotus/env.skywalking.yml  up -d
1

该命令会查看本地是否已经有了相关镜像,如果没有会首先下载镜像,然后再运行,请先保证网络畅通

  • 停止容器
docker-compose -f ${project_home}/configurations/docker/docker-compose/linux/herodotus/env.skywalking.yml stop
1
  • 停止并删除容器
docker-compose -f ${project_home}/configurations/docker/docker-compose/linux/herodotus/env.skywalking.yml down
1

# [6]服务打包部署

在命令行中,执行以下命令即可

  • 运行容器
docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/services.dev.yml --env-file=${project_home}/configurations/docker/docker-compose/linux/herodotus/.env up -d
1

该命令会查看本地是否已经有了相关镜像,如果没有会首先构建镜像,然后再运行,请先保证网络畅通

  • 停止容器
docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/services.dev.yml --env-file=${project_home}/configurations/docker/docker-compose/linux/herodotus/.env up -d stop
1
  • 停止并删除容器
docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/services.dev.yml --env-file=${project_home}/configurations/docker/docker-compose/linux/herodotus/.env up -d down
1

# 服务器容器部署

提示

应用环境的部署是一项大工程,同样的基础设施根据不同应用场景需求,可以采用多种多样不同的方式进行部署。基础设施的部署也比较复杂,其中任意一项都可以单独作为专门话题进行讨论。这就是所谓的“千人千面”, 而且基础设施部署并不是本项目的重点,所以此处不再展开。当然,只要是技术问题,欢迎在群里积极讨论交流。

使用 Docker-compose 打包 Docker,参见[Dante Cloud Docker 打包使用方法](#Dante Cloud Docker 打包使用方法)

# Docker 打包设计

# Dante Cloud Docker 打包设计初衷

Dante Cloud Docker 打包的设计,采取了与大多数开源微服务框架不同的方式。采取这种不同的方式进行打包,主要是考虑解决以下两方面问题:

# [1]Skwalking Agent 的引入问题

系统中为了解决服务链路跟踪及监控的问题,引入了 Skywalking 组件。Skywalking 想要正确运行,除了要保证 Skywalking Server 的正常运行外,还要将 Skywalking"注入"到服务的运行环境中。

  1. 如果是以fat jar的方式运行服务,需要在服务的运行命令中指定 Skywalking Agent 以及相关的参数,如下命令
java -javaagent:/skywalking-agent.jar=agent.service_name=${SW_AGENT_SERVICE_NAME},collector.backend_service=${SW_COLLECTOR_BACKEND_SERVICE} ${JAVA_OPTS} -jar /app.jar
1
  1. 如果是以 Docker 的方式运行服务,传统的方式就需要把skywalking-agent.jar一并打入到服务的 docker 中。

由于 Docker-compose 打包上下文的问题,就需要在每一个模块中都复制一份 skywalking-agent.jar。很不好管理,看着也不舒服。

# [2]Dockerfile 的编写和放置问题

常规 Java 微服务的 Docker 打包方式,要么采用 Maven Plugin 的方式,要么采用 docker-compose 的方式。不管哪一种方式,都需要在该服务代码所在目录下新建一个 Dockerfile 文件。

一方面,每个服务下的 Dockerfile 文件中的配置信息,除了服务的 JAR 包名不同以外,其余的所有配置都相同,就是一种重复劳动。 另一方面,如果要增加 Skywalking,那么需要在每一个服务所在目录下都拷贝一份skywalking-agent.jar。不仅重复工作,代码结构也不美观整洁。

# Dante Cloud Docker 打包的设计

为了解决上述两方面问题,Dante Cloud 在所有模块之外之指定了一个统一的目录,将需要打包的 jar 以及 dockerfile 全部放入该目录,通过该目录形成一个统一的上下文环境。在Dante Cloud工程中,${project_home}/configurations/docker/context就是这个上下文环境。

在这个上下文环境中,除了包含通用的 Dockerfile,Skywalking Agent 以外,在使用 Maven 进行编译的过程中,还会将所有需要打包服务的对应的 jar 包拷贝到${project_home}/configurations/docker/context/target目录下。这样打包的所有资源就都已经具备,同时还解决了上述两个问题。

提示

可以通过修改${project_home}/pom.xml 中的<docker.build.directory>值,来改变拷贝 jar 包的目录

# Dante Cloud Docker 打包使用方法

# [1]修改信息

由于使用了一个统一的 Dockerfile 来解决重复定义 Docker 打包配置文件的问题,想要实现使用一个 Dockerfile 打出不同的 Docker,那么就需要通过传参的方式来改变 Dockerfile 中的值。

这里采用的是环境变量的方式,在${project_home}/configurations/docker/docker-compose/.env文件中定义这些参数。其中包含版本号以及具体服务对应的包名。所以如果有新增服务或者想要指定版本号,首先就需要修改这个配置文件。

# [2]执行命令

执行打包命令

docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/services.dev.yml --env-file=${project_home}/configurations/docker/docker-compose/linux/herodotus/.env up -d
1

或者

docker-compose -f ${project home}/configurations/docker/docker-compose/linux/herodotus/services.prod.yml --env-file=${project_home}/configurations/docker/docker-compose/linux/herodotus/.env up -d
1

说明

上文说到想要以 Docker 的方式运行服务并且关联 Skywalking,就需要在打包时将 Skywalking Agent 打入到 Docker 中。但实际应用中并不是所有环境都需要使用 Skywalking,比如:在生产环境需要使用 Skywalking,在开发环境中并不需要 Skywalking 以降低资源消耗。

因此,Dante Cloud 提供了两种打包配置

使用${project home}/configurations/docker/docker-compose/linux/herodotus/services.dev.yml这个 Docker-compose 配置文件打包时,对应的 Dockerfile 文件是${project home}/configurations/docker/context/development/Dockerfile。这个 Dockerfile 配置中,没有包含 Skywalking Agent 的拷贝命令。

使用${project home}/configurations/docker/docker-compose/linux/herodotus/services.prod.yml这个 Docker-compose 配置文件打包时,对应的 Dockerfile 文件是${project home}/configurations/docker/context/production/Dockerfile。这个 Dockerfile 配置中,包含了 Skywalking Agent 的拷贝命令。

这样通过不同的命令,实现了对不同 Docker 环境需求的支持。

# 前端容器部署

# [1]修改后端网关地址

在工程根目录下,找到 .env.production 配置文件。

修改配置参数 VITE_API_URL 的值为可以正确访问的后端服务网关地址。

# [2]编译前端代码

使用下面命令,编译前端代码。

// 编译前端工程代码
yarn prod

1
2
3

# [3]打包 Docker 镜像

执行以下命令,将已经编译好的前端代码,打包成 Docker 镜像。


docker-compose -f ${ui-project-home}/container/herodotus/ui.yml up -d

1
2
3

# [4]验证

在浏览器中,访问地址 http://ip:3000。 前端页面正常打开,说明打包部署成功。

上次编辑于: 2022年9月13日 17:42
贡献者: herodotus , 码匠君