之前学习过使用Dockerfile生成镜像和生成启动容器,我们在实际运用中发现:Dockerfile是记录单个镜像的构建过程,一个较大的项目里面包含多个服务时,使用Dockerfile一个个部署会非常耗时,所以这次来学习一个新的Docker服务–Compose。Compose是一个用户定义和运行多个容器的Docker应用程序,具体的下载安装过程可参考: https://docs.docker.com/compose/install/#alternative-install-options。
在Compose中可以使用YAML或YML文件来配置我们的服务,然后只需要一个简单的命令,就可以创建并启动我们在YML文件配置的所有服务。
学习之前的准备工作:linux系统,并安装Docker和Compose(Compose是一个文件)
1.docker-compose.yml文件如何配置?看看下面BLS本地部署的例子
#版本号
version: ‘3’
#服务
services:
#服务名称,用户自定义名称
base-service:
#镜像名:仓库/标签:版本。如果镜像在本地不存在,Compose将会尝试拉取这个镜像
**image**:172.16.0.142:8888/pbplatform/base-service-all:v2.4
#指定一个自定义容器的名称,而不是生成的默认名称
#由于Docker容器名称具有唯一性,因此如果指定了自定义名称,则无法将服务扩展到多个容器
**container_name**:base-service
#映射端口的标签、
#使用HOST端口 : CONTAINER端口格式 或 只是指定容器的端口,宿主机会随机映射端口。
**ports**:
- "8860:8860"
- "8870:8870"
- "8000:8000"
- "8181:8181"
- "8119:8119"
#docker-compose.yml中可以定义一个专门存放变量的文件。在构建镜像时使用
**env_file**:
- ./envs/blsConfig.env
#卷挂载路径设置,挂载一个目录或者一个已存在的数据卷容器,可以直接使用【HOST:CONTAINER】这样的格式,
#或者使用【HOST:CONTAINER:ro】这样的格式,后者对于容器来说,数据卷只是只读的,这样可以有效保护宿主机的文件系统。
#Compose的数据卷指定路径可以是相对路径,使用 . 或者 … 来指定相对目录。
#volumes:
# //只是指定一个路径,Docker会自动再创建一个数据卷(这个路径是容器内部的)。
# - /var/lib/mysql
# //使用绝对路径挂载数据卷
# - /opt/data:/var/lib/mysql
# //以Compose配置文件为中心的相对路径作为数据卷挂载到容器。
# - ./cache:/tmp/cache
# //使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
# - ~/configs:/etc/configs/:ro
# //已经存在的命名的数据卷。
# - datavolume:/var/lib/mysql
**volumes**:
- ./logs/base/:/var/log/
#container是否拥有root权限
**privileged**: true
#在使用compose的时候,最大的好处就是少打启动命令。
#但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖性的问题而启动失败。
#例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是depends_on,
#这个标签解决了容器依赖性的问题。
**depends_on**:
- sso-service
2.docker-compose up -d [服务名] 一条命令自动拉取镜像并生成启动容器
上一次我们用Dockerfile部署jar包,需要docker build和docker run两条命令生成镜像和容器。
使用YML文件运行docker-compose up -d [服务名]命令 可以一步到位,自动拉取镜像后生成启动容器。
Dockerfile和docker-compose.yml
比较:
dockerfile:部署jar包->配置Dockerfile文件->docker build->docker run;
docker-compose.yml:配置docker-compose.yml文件->docker-compose
up -d
从头说起,假如不用docker呢?我们搭建BLS要怎么弄?先找台server,假设其OS是Ubuntu,然后安装JRE,接着一步步敲命令,写配置,启动一个个的jar包。
使用docker呢?随便找台server,不管什么操作系统,只要支持docker就行,docker run Ubuntu,docker就会从官方镜像库拉取最新的Ubuntu镜像,这时可以认为我们已经开了个Ubuntu的虚拟机,然后敲四个命令FROMCOPYRUN~CMD来最后启动容器,这样做有个明显的缺点,一旦容器被删除了,我们之前为了启动每个服务重复敲那四个命令的工作就没了,一个直观的解决方案就是,写个脚本把安装部署过程全部记录下来,这样再次安装的时候,执行脚本就行了,Dockerfile就是这样的脚本,它记录了一个镜像的制作过程。
第二个问题:如果只是启动一个bls-ems服务就够了,那Dockerfile就够了。但我们BLS系统需要多个服务合作才能运作,docker-compose就是解决这个问题的。项目需要哪些镜像,每个镜像怎么配置,要挂载哪些volume, 等等信息都包含在docker-compose.yml 里,要启动服务,只需要docker-compose up -d就行,停止也只需要docker-compse
stop/down。
所以,Dockerfile 或者
docker-compose都是为了帮助我们更方便地创建并启动我们的服务。
3.我们现在的测试环境都是只需要docker-compose的,但其实还有一种方法是Dockerfile+docker-compose
因为docker-compose本身没有镜像构建的信息,如果镜像时从仓库中拉取下来的,那么不需要Dockerfile。但如果需要在本地使用jar包构建镜像,则需要提供Dockerfile。
具体方法是在docker-compose中添加一个build标签,如下:
#构建镜像的标签,服务可以基于指定的镜像,还可以基于一份Dockerfile,在使用up启动之时执行构建任务,build标签可以指定dockerfile所在文件夹的路径。
#build: /path/to/build/dir
#build: ./dir
#compose将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。
#注意:build都是一个目录,如果你要指定dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定,如下面的例子。
#build:
#context: ./dir
#dockerfile: path/to/dockerfile
#如果你同时指定了image和build两个标签,那么compose会构建镜像并且把镜像命名为images后面的那个名字,如:
#image: base-service
#build: ./dir
4.上面提到了使用jar包一步步敲命令部署时需要每次手动写配置,那现在使用Dockerfile或docker-compose的配置又是在哪一步完成的呢?
先看看配置文件的内容:
配置文件里面包含了命令、服务内存分配、jar包的路径(基于容器)等等。回到问题,这个配置是在哪一步完成的呢? 是在构建镜像时完成的,Jenkins构建时执行脚本将配置文件与jar包放在镜像中,服务启动时便按照配置的参数启动。