1 什么是 Docker Compose
前面我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知。
使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具
2 安装 Docker Compose
安装命令:
[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]# curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]# chmod +x /usr/local/bin/docker-compose
复制代码
检查是否安装成功:
[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]# docker-compose -v
复制代码
3 Docker Compose 文件格式的简单介绍
Docker Compose 文件一般命名为 docker-compose.yml,并且执行 Docker-compose 命令时在该文件所在目录下执行。
例如:
docker-compose.yml # 一个文件代表一个project
serveices: # 服务
container-name: # 容器
build:
- xxx:xxx
network: # 引用标签
xxx:
复制代码
下面是一个标准的 docker-compose.yml 文件
version: "3" # 指定版本
services: # services
proxy: # 自定义容器名称
build: ./proxy # Dockerfile所在目录,用于构建容器
networks: # 自定义容器网络
- frontend
app:
build: ./app
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: custom-driver-1
backend:
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"
复制代码
4 Docker Compose 常用命令
docker-compose port eureka 8761
复制代码
docker-compose start eureka
复制代码
docker-compose stop eureka
复制代码
docker-compose kill eureka
复制代码
docker-compose pull eureka
复制代码
docker-compose scale user=3 movie=3
复制代码
docker-compose run web bash
复制代码
5 使用 Docker Compose 一键部署 Spring Boot+Redis 实战
5.1 构建应用
5.1.1 Spring Boot 项目
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码
配置文件:
spring:
redis:
#host: 127.0.0.1
host: ymx.redis
port: 6379
password:
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 500
min-idle: 0
lettuce:
shutdown-timeout: 0
复制代码
controller 代码:
@RestController
public class HelloController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@RequestMapping("/hello/{id}")
public String hello(@PathVariable("id") Integer id) {
return redisTemplate.opsForValue().get(String.valueOf(id));
}
@RequestMapping("/save/{id}/{name}")
public String save(@PathVariable("id") Integer id, @PathVariable("name") String name) {
try {
redisTemplate.opsForValue().set(String.valueOf(id), "Hello " + name + "!");
} catch (Exception e) {
return "false";
}
return "success";
}
}
复制代码
5.1.2 Redis 配置文件
只是将 redis 自带的 redis.conf 做了一点修改
#注释掉bind 127.0.0.1
# bind 127.0.0.1 -::1
#修改protected-mode yes->no
protected-mode no
复制代码
5.2 打包应用并构建目录
5.2.1 打包 Spring Boot 项目
5.2.2 上传 redis.conf 配置文件
5.2.3 目录结构
- mycompose
- docker-compose.yml
- rd
- Dockerfile
- redis.conf
- sp
- Dockerfile
- sp_redis-0.0.1-SNAPSHOT.jar
复制代码
5.3 编写 Dockerfile
5.3.1 Spring Boot 容器的 Dockerfile
FROM java:8
MAINTAINER YMX "1712229564@qq.com"
COPY sp_redis-0.0.1-SNAPSHOT.jar /root/sp_redis-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar","/root/sp_redis-0.0.1-SNAPSHOT.jar"]
复制代码
5.3.2 redis 容器的 Dockerfile
FROM redis
MAINTAINER ymx 1712229564@qq.com
COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
CMD ["redis-server","/usr/local/etc/redis/redis.conf" ]
复制代码
5.4 编写 docker-compose.yml
version: "2.8" # 表示该 Docker-Compose 文件使用的是 Version 2 file
services:
sp-demo: # 指定服务名称
build: ./sp # 指定 Dockerfile 所在路径
ports: # 指定端口映射
- "9001:8080"
links:
- re-demo:ymx.redis # 进行容器链接
re-demo:
build: ./rd
复制代码
5.5 运行并测试部署结果
运行:
[root@iZ2ze4m2ri7i mycompose]# docker-compose up
Creating network "mycompose_default" with the default driver
Building re-demo
Sending build context to Docker daemon 96.77kB
Step 1/5 : FROM redis
latest: Pulling from library/redis
......
复制代码
测试:
[root@iZ2ze4m2ri7i mycompose]# curl http://localhost:9001/save/2/Ymx
success
[root@iZ2ze4m2ri7i mycompose]# curl http://localhost:9001/hello/2
Hello Ymx!
复制代码
6 小总结
在 Spring Boot 配置文件中,redis 的 host 没有使用 localhost 或者 127.0.0.1,而是使用了域名 ymx.redis,这一域名在 docker-compose.yml 文件中进行了映射,进而 Spring Boot 的容器能够链接到 redis 容器,但是这一情况依赖于一个默认条件,就是 docker 的网络默认是桥接模式,两个容器都在同一子网中,因此才能够互相访问。
因此,links 并不是唯一的容器网络解决方案,在容器较多时,需要使用 networks 进行网络的管理。
参考文章:
https://www.jianshu.com/p/658911a8cff3
https://www.jianshu.com/p/3004fbce4d37
https://blog.csdn.net/luo15242208310/article/details/88642187
https://blog.csdn.net/qq_36781505/article/details/86612988
评论