目录

  • Docker-第四部分
  • 容器编排工具Docker Compose
  • Docker Compose特点
  • Docker Compose安装
  • Docker-compose 命令
  • Docker Compose完整部署应用程序实例
  • 准备:安装Dcoker,Docker Compose,下载程序jar包等
  • 编辑应用Dockerfile
  • 编辑自定义MYsql的Dockerfile
  • 编辑docker-compose.yml文件
  • docker-compose up 启动
  • docker-compose down 停止应用
  • 解决无法连接数据库的问题


Docker-第四部分

容器编排工具Docker Compose

Compose是用于定义和运行多容器Docker应用程序的工具。通过Compose,您可以使用YAML文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。

在宿主机中安装Nginx,Apache Tomcat,Msql.Nginx web应用服务,对Tomcat提供负载均衡和反向代理支持。Tomcat通过内部的web程序访问Mysql数据库。每个应用都有自己的配置文件,如果这组应用需要上线,需要提供很多docker 命令和配置文件给运维,才能正确部署应用。这样做是比较麻烦的,所以Dcoker提供了容器编排工具Docker compose 来解决这个问题。Docker compose 通过一个脚本,可以先安装MySql容器,再安装Tomcat,然后安装Nginx,并把几个容器形成依赖,每个容器所需的配置文件只需要绑定就可以了。这样只需要一个文件就能完成一件部署和发布应用。

Docker Compose特点

  • Docker Compose单机多容器部署工具(集群环境中使用k8s进行编排)
  • 通过yml文件定义多容器如何部署
  • WIN/MAC默认在安装Dcoker时提供Docker Compose 无需单独安装,Linux需要安装

Docker Compose安装

官网介绍地址: https://docs.docker.com/compose/install/

获取并自动安装Docker comppose,当前版本为1.25.5,r若要安装其他版本,版本即可,,默认安装路径是

/usr/local/bin/docker-compose(如果下载失败,多试几次,因为连接国外网,可能会超时)

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

对docker-compose赋可执行权限

sudo chmod +x /usr/local/bin/docker-compose

查看docker-compose的版本

docker-compose -version

显示如下,docker-composean安装成功:

[root@localhost ~]# docker-compose -version
docker-compose version 1.24.1, build 4667896b

Docker-compose 命令

docker-compose操作命令,https://docs.docker.com/engine/reference/commandline/docker/

下面列出本例中使用

docker-compose up : 启动,解析docker-compose.yml 的内容并执行,会构建镜像并运行容器

docker-compose logs [服务名] :查看日志,后面加服务名,可查看具体的服务日志

docker-compose down: 停止容器,容器会被停止并移除,但是构建的镜像不会移除

docker logs 容器id或容器名:可以查看容器的运行日志

Docker Compose完整部署应用程序实例

准备:安装Dcoker,Docker Compose,下载程序jar包等

现在有一个使用spring boot+spring data jpa搭建的一个web应用,应用连接mysql数据库

项目git地址: https://github.com/yumaoying/spring-jpa-demon.git

使用maven打包编译后,把项目上传到linux上/usr/image/app 目录中,

同时将程序所需的初始化sql文件也下载上传到db目录

[root@localhost app]# ll
总用量 0
drwxr-xr-x. 2 root root 21 4月  18 18:13 db
drwxr-xr-x. 3 root root 88 4月  18 18:11 spring-jpa-demon
[root@localhost app]#

spring-jpa-demon中包含如下文件:

application.yml是项目运行的一些配置,

其中lib目录中包含项目运行所依赖jar包

spring-jpa-demon.jar是程序运行的jar包

[root@localhost spring-jpa-demon]# ll
总用量 28
-rw-r--r--. 1 root root  507 4月  18 18:02 application.yml
drwxr-xr-x. 2 root root 8192 4月  18 13:29 lib
-rw-r--r--. 1 root root 9152 4月  18 13:29 spring-jpa-demon.jar
[root@localhost spring-jpa-demon]#

db目录中的init.sql文件是程序需要的建表的初始化sql语句

[root@localhost app]# cd db
[root@localhost db]# ls
init.sql

init.sql的内容如下

-- 建库
CREATE DATABASE IF NOT EXISTS test default charset utf8 COLLATE utf8_general_ci;

-- 切换到数据库
use test;

-- 如果表存在先删除表
DROP TABLE IF EXISTS `tb_user`;


-- 创建表
CREATE TABLE `tb_user`(
  `id` VARCHAR(32),
  `username`       VARCHAR(64),
  `password`     VARCHAR(64),
  `email`    VARCHAR(64),
  PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;


-- 初始化数据
insert into `tb_user`(id,username,password,email) values('1','admin','123456','test@xx.com');
commit;

其中application.yml的配置如下,应用端口是8010,数据库使用mysql

server:
  port: 8010
  servlet:
    context-path: /
spring:
  thymeleaf:
    cache: false
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: 123456
  jpa:
    database: MySQL
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    hibernate:
      ddl-auto: none

由于项目使用java开发的可以到https://hub.docker.com/ 搜索java的运行jdk环境,

docker容器编排工具 docker的编排工具_Docker

在tag位置找到与开发时匹配的环境(在tag中搜索8u222,可以找到),使用openjdk:8u222-jre构建Dockerfile文件

docker容器编排工具 docker的编排工具_docker_02

编辑应用Dockerfile

  1. 切换到spring-jpa-demon目录,编辑文件 vim Dockerfile
FROM openjdk:8u222-jre
#切换工作目录(不存在时会创建)
WORKDIR /usr/local/spring-jpa-demon
#复制项目到当前目录
ADD application.yml .
ADD spring-jpa-demon.jar .
ADD lib/ ./lib/
#对外暴露端口
EXPOSE 8010
#运行容器时默认执行命令
CMD ["java","-jar","spring-jpa-demon.jar"]

2.使用当前Dockerfile构建应用镜像

镜像名spring-jpa-demon

docker build -t spring-jpa-demon .

过程如下

[root@localhost spring-jpa-demon]# vi Dockerfile 
[root@localhost spring-jpa-demon]# docker build -t spring-jpa-demon .
Sending build context to Docker daemon   52.8MB
Step 1/7 : FROM openjdk:8u222-jre
 ---> 25073ded58d2
Step 2/7 : WORKDIR /usr/local/spring-jpa-demon
 ---> Running in 7f49bdae7e09
Removing intermediate container 7f49bdae7e09
 ---> 46da6f207d2d
Step 3/7 : ADD application.yml .
 ---> 1a572155fcb0
Step 4/7 : ADD spring-jpa-demon.jar .
 ---> 885855b35646
Step 5/7 : ADD lib/ ./lib/
 ---> 9e35538a9235
Step 6/7 : EXPOSE 8010
 ---> Running in e49a667e8aee
Removing intermediate container e49a667e8aee
 ---> 5b4fe8273074
Step 7/7 : CMD ["java","-jar","spring-jpa-demon.jar"]
 ---> Running in bdf07bd274ad
Removing intermediate container bdf07bd274ad
 ---> 1a64e429bdbc
Successfully built 1a64e429bdbc
Successfully tagged spring-jpa-demon:latest

显示Successfully 说明镜像构建成功,运行测试

3.使用docker images 查看镜像

[root@localhost spring-jpa-demon]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
spring-jpa-demon    latest              1a64e429bdbc        14 seconds ago      299MB
openjdk             8u222-jre           25073ded58d2        6 months ago        246MB

运行容器

docker run spring-jpa-demon

由于没有安装mysql,无法和mysql建立连接,所以项目运行失败

编辑自定义MYsql的Dockerfile

4.切换到db目录,编辑Dockerfile文件

docker-entrypoint-initdb.d 是Docker 官方定义初始化数据库脚本的目录,还有其他参数配置可参考https://hub.docker.com/_/mysql

FROM mysql:5.7
#Docker 官方定义初始化数据库脚本的目录
WORKDIR /docker-entrypoint-initdb.d
#拷贝sql文件
ADD init.sql .

5.构建mysql镜像

docker build -t my_db .

执行如下,docker images查看镜像

[root@localhost db]# docker build -t my_db .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM mysql:5.7
 ---> 273c7fcf9499
Step 2/3 : WORKDIR /docker-entrypoint-initdb.d
 ---> Running in 4b83d6306b30
Removing intermediate container 4b83d6306b30
 ---> 164890d28b86
Step 3/3 : ADD init.sql .
 ---> 0fb0bb5709c4
Successfully built 0fb0bb5709c4
Successfully tagged my_db:latest
[root@localhost db]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my_db               latest              0fb0bb5709c4        43 seconds ago      455MB
spring-jpa-demon    latest              1a64e429bdbc        4 hours ago         299MB
mysql               5.7                 273c7fcf9499        22 hours ago        455MB
tomcat              latest              f43f44c16fb0        2 days ago          529MB
centos              latest              470671670cac        3 months ago        237MB
openjdk             8u222-jre           25073ded58d2        6 months ago        246MB
[root@localhost db]#

6.运行容器,设置mysql数据库的root的密码为123456

docker run -d  -e MYSQL_ROOT_PASSWORD=123456 my_db

docker ps查看是否运行,如果没有运行,可以使用docker ps -a查看容器是否在运行,然后使用docker start 容器id 启动

[root@localhost db]# docker run --name mysql_db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d my_db
f04354787d24fd45f782f1f14a2093c190f4c9c405440f20e548a94e30e66896
[root@localhost db]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
f04354787d24        my_db               "docker-entrypoint.s…"   12 seconds ago      Up 6 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql_db
[root@localhost db]# docker start a62fd18fee87
a62fd18fee87
[root@localhost db]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
2095ff272efb        my_db               "docker-entrypoint.s…"   49 seconds ago      Up 46 seconds       3306/tcp, 33060/tcp   vigilant_merkle

docker exec -it 容器名或id /bin/bash 进入容器内部,可以看到init.sql

[root@localhost db]# docker exec -it 2095ff272efb  /bin/bash
root@2095ff272efb:/docker-entrypoint-initdb.d# ls
init.sql

mysql -u用户,-p密码,可进入mysql,创建数据库database并查看是否创建数据库

对数据库进行操作,SHOW DATABASES查看数据库mysql的database,

root@2095ff272efb:/docker-entrypoint-initdb.d# mysql -uroot -p123456
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.12 sec)

mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| tb_user        |
+----------------+
1 row in set (0.00 sec)

mysql> select * from tb_user;
+----+----------+----------+-------------+
| id | username | password | email       |
+----+----------+----------+-------------+
| 1  | admin    | 123456   | test@xx.com |
+----+----------+----------+-------------+
1 row in set (0.00 sec)

mysql>

可以看到test数据库已经创建了,use 数据库 切换到这个数据库,查看表数据,此时自定义的mysql数据库波u见运行

编辑docker-compose.yml文件

切换到app目录,编辑docker-compose.yml文件

#Dcoker-compose文件的解析规则为3.3版本
version: '3.3'
#用于描述部署容器及容器信息
services:
  #db服务名,创建的容器为数据库,多个容器之间互通,也是容器的主机名
  db:
    #对指定目录中的Dockerfile进行解析并构建镜像
    build: ./db/
    #容错机制,如果镜像对应的容器错误或退出,会自动重启
    restart: always
    #环境变量,设置容器的属性
    environment:
      #设置mysql数据库root的密码
      MYSQL_ROOT_PASSWORD: 123456
  app:
    build: ./spring-jpa-demon/
    #设置依赖,程序依赖于db及mysql数据库,这只这个之后两个程序可以互连
    depends_on:
      - db
    #宿主机端口和容器端口映射
    ports: 
      - "8010:8010"
    restart: always

docker-compose up 启动

自动读取docker-compose.yml的内容创建镜像并运行容器

docker-compose up

执行过程如下:

在屏幕上可看到会先创建镜像,再启动容器

docker容器编排工具 docker的编排工具_spring_03

镜像创建后关联容器,启动容器

docker容器编排工具 docker的编排工具_spring_04

启动app

docker容器编排工具 docker的编排工具_Docker_05


但是启动应用的过程中报错了,无法和数据库建立连接(这里是因为应用的application.yml中和数据库连接的参数没有修改,无法和mysql建立连接,后面步骤修正)

docker容器编排工具 docker的编排工具_Docker_06


注:因为docker-compose up 默认在前台运行,如果在执行过程中按ctl+z或关闭会话,进程就会结束,可以使用-d参数来让命令在后台执行,即docker-compose up -d打开另一个会话,docker ps查看运行容器,可以看到容器是正在运行的

docker容器编排工具 docker的编排工具_spring_07


在浏览器输入虚拟机地址访问 http://192.168.22.128:8010/,访问主页能成功,但是查看用户,由于需要连接数据库所以会报错。

docker容器编排工具 docker的编排工具_docker_08

docker-compose down 停止应用

docker-compose down

docker容器编排工具 docker的编排工具_docker_09

可以看到docker-compose down执行后会先停止容器,然后再移除,使用docker ps查看运行容器时容器已移除,但是镜像未移除。

解决无法连接数据库的问题

修改application.yml文件中的数据库连接地址,因为外部无法和容器内部建立连接,所以将原有的localhost替换为docker-compose中定义的数据库服务名db,保存后重新执行。

url: jdbc:mysql://db:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
[root@localhost spring-jpa-demon]# vi application.yml 
[root@localhost spring-jpa-demon]# cat application.yml 
server:
  port: 8010
  servlet:
    context-path: /
spring:
  thymeleaf:
    cache: false
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://db:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: 123456
  jpa:
    database: MySQL
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    hibernate:
      ddl-auto: none
[root@localhost spring-jpa-demon]#

使用docker images查看镜像,然后docker rmi 命令把原有镜像删除重新构建(这一步可不执行,不执行时docker-compose up -d会直接启动容器,不会重新构建容器)

docker rmi -f 容器id

docker容器编排工具 docker的编排工具_docker容器编排工具_10


重新执行

docker-compose up -d

执行过程如下,由于删除了镜像,这一步会创建并运行容器

docker容器编排工具 docker的编排工具_spring_11

docker-compose logs查看日志

docker-compose logs

docker容器编排工具 docker的编排工具_docker_12

docker容器编排工具 docker的编排工具_docker容器编排工具_13


docker-compose logs 会将两个服务的日志都进行输出,如果想看某个服务的日志,可以加上服务名,这个服务名是在docker-compose中定义的服务名,如本例中的app和db

docker-compose logs app

docker容器编排工具 docker的编排工具_docker_14

也可以查看容器日志

docker logs 容器id或容器名称

docker容器编排工具 docker的编排工具_spring_15

容器已正常启动,此时访问网页

点击查看用户,已经能从从数据库查询数据显示

docker容器编排工具 docker的编排工具_docker_16