一、Compose简介
(一)简单介绍
Compose项目是 Docker官方的开源项目,负责实现对基于 Docker容 器的多应用服务的快速编排 。 从功能上看,跟 OpenStack 中的 Heat 十分类 似。 其代码目前在https://github.com/docker/compos巳上开源。
Compose定位是“定义和运行多个 Docker容器的应用”,其前身是开源项目 Fig,目前仍然兼容 Fig格式的模板文件。
我们知道,可以使用一个 Dockerfile模板文件,来方便地定义一个单独的应用容器 。 然而,在日常工作中,经常会碰到需要多个 容器相互配合来完成某项任务的情况 。 例如要实现一个 Web 项目,除了 Web 服务容器本身, 往往还需要再加上后端的数据库服务容器,甚至还包括前端的负载均衡容器等。
Compose恰好满足了这样的需求。 它允许用户通过一个单独的 docker-compose.yml 模板文件( YAML 格式)来定义一组相关联的应用容器为一个服务樵( stack)
(二)核心概念
- 任务( task) : 一个容器被称为一个任务。 任务拥有独一无二的 ID,在同一个服务中 的多个任务序号依次递增 。
- 服务( service):某个相同应用镜像的容器副本集合,一个服务可以横 向扩展为多个 容器实例 。
- 服务栈 ( stack) :由 多个服务组成 ,相互配合完成特定业务 , 如 Web 应用服务、数据 库服务共同构成 Web 服务钱 ,一般由一个 docker-cornpose .yrnl 文件定义 。
Compose 的默认管理对象是服务钱,通过子命令对楼 中的多个服务进行便捷的生命周期 管理。
Compose项目由 Python编写 ,实现上调用了 Docker服务提供的 API来对容器进行管理。 因此,只要所操作的平台支持 DockerA凹,就可以在其上利用 Compose来进行编排管理
二、安装
参看地址:https://docs.docker.com/compose/install/
在mac和windows上由于是安装的是docker客户端,会自带compose,就不需要再安装,Linux下安装方式如下:
- 获取并解压安装包
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
这里下载的是1.24.1版本,其他版本参看:https://github.com/docker/compose/releases - 修改docker-compose权限
sudo chmod +x /usr/local/bin/docker-compose
- 创建连接到系统环境变量
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
这样,我们在任何地方可以执行docker-compose命令了 - 验证,执行
docker-compose
,效果如下:[root@localhost bin]# docker-compose version
docker-compose version 1.24.1, build 4667896b
docker-py version: 3.7.3
CPython version: 3.6.8
OpenSSL version: OpenSSL 1.1.0j 20 Nov 2018
三、入门案例
(一)案例介绍
这里通过一个web应用访问redis来演示,希望项目启动之后,通过在浏览器输入地址,能够显示出如下内容:
this is 6 time to say hello !!!
其中这个6是从redis中获取到的,而且,每次都会加1
(二)代码
项目使用springboot开发,没什么好说的,这里除了主启动类,就只有一个控制器:
package com.firewolf.test.compose.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@Configuration
public class HelloController implements CommandLineRunner {private final String TIME_KEY &#61; "times";&#64;Autowiredprivate RedisTemplate redisTemplate;&#64;GetMappingpublic String sayHello() {Long value &#61; redisTemplate.opsForValue().increment(TIME_KEY);return String.format("this is %d time to say hello !!!", value);}&#64;Overridepublic void run(String... args) throws Exception {redisTemplate.opsForValue().set(TIME_KEY, "0");}&#64;Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate redisTemplate &#61; new RedisTemplate<>();redisTemplate.setValueSerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(redisConnectionFactory);return redisTemplate;}
}
可以看到&#xff0c;项目用到了redis&#xff0c;至于redis集成到springboot中&#xff0c;就是一个Maven依赖的问题&#xff1a;
org.springframework.bootspring-boot-starter-data-redis
同时添加日志输出配置logback.xml&#xff1a;
applogs/compose.logtrue%-4relative [%thread] %-5level %logger{35} - %msg%n%-4relative [%thread] %-5level %logger{35} - %msg %n
之后&#xff0c;打包成一个jar包compose-1.1.jar
&#xff08;三&#xff09;利用compose构建
- 把compose-1.1.jar拷贝到一个目录&#xff08;我这里是composetest&#xff09;&#xff1b;
- 编写构建应用的配置的Dockerfile
FROM maven:3.5.0-jdk-8-alpine
WORKDIR /
COPY compose-1.1.jar .
CMD java -jar compose-1.1.jar --spring.redis.host&#61;redis
这里在启动参数里面指定了redis地址
此时如果使用docker build … 方式进行构建&#xff0c;生产的镜像肯定不能使用&#xff0c;因为redis连接不上
- 编写docker-compose.yml
version: &#39;3&#39;
services:web:build: .ports:- "8089:8080"redis:image: "redis:5.0.5"
在这个服务栈里面启动了两个应用&#xff1a;
①. 从镜像启动的redis
②. 从当前目录构建的web
- 通过compose启动服务&#xff1a;
docker-compose up
&#xff0c;效果如下&#xff1a;Creating network "composetest_default" with the default driver
Building web
Step 1/4 : FROM maven:3.5.0-jdk-8-alpine---> 67d11473f554
Step 2/4 : WORKDIR /---> Running in 012ca6dd3480
Removing intermediate container 012ca6dd3480---> c8874b813831
Step 3/4 : COPY compose-1.1.jar .---> 7c1e7f2a2ed2
Step 4/4 : CMD java -jar compose-1.1.jar --spring.redis.host&#61;redis---> Running in 30ea85faacd4
Removing intermediate container 30ea85faacd4---> ca32a1a65894
Successfully built ca32a1a65894
Successfully tagged composetest_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use &#96;docker-compose build&#96; or &#96;docker-compose up --build&#96;.
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1 | 1:C 15 Aug 2019 03:37:04.820 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 15 Aug 2019 03:37:04.821 # Redis version&#61;5.0.5, bits&#61;64, commit&#61;00000000, modified&#61;0, pid&#61;1, just started
redis_1 | 1:C 15 Aug 2019 03:37:04.821 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 15 Aug 2019 03:37:04.825 * Running mode&#61;standalone, port&#61;6379.
redis_1 | 1:M 15 Aug 2019 03:37:04.825 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 15 Aug 2019 03:37:04.825 # Server initialized
.....
- 测试
在浏览器输入http://localhost:8089/&#xff0c;多次刷新。效果如下&#xff1a;
&#xff08;四&#xff09;绑定数据卷
修改docker-compose.yml&#xff1a;
version: &#39;3&#39;
services:web:build: .volumes:- ./logs/:/applogsports:- "8089:8080"redis:image: "redis:5.0.5"
这里指定了绑定当前目录的./logs/目录到web容器的/applogs目录&#xff08;日志位置&#xff09;&#xff0c;再次重启&#xff0c;在当前目录生成了logs目录&#xff0c;并且&#xff0c;可以看到web容器中的日志compose.log&#xff0c;接下来&#xff0c;项目打印的日志就可以在logs里面动态更新查看了。