在文章 docker容器网络 - 同一个host下的容器间通信 中,我们已经了解怎么在同一个host中容器间互相通信,本文将会利用学会的知识,部署一个“复杂”的springboot应用。该应用实现一个计数服务,springboot应用暴露服务接口,通过redis实现计数功能。该应用在docker里的部署图如下图所示:
我们先看下应用的代码,初步了解下应用提供什么服务。
在配置文件中配置了一个redis。redis地址将会在容器启动的时候通过设置环境变量修改
spring.application.name=springboot-redis
server.port=8080
logging.file=app.log
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
应用通过rest的方式提供了计数的服务
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/count")
public Long count() {
ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
Long next = valueOperations.increment("counter", 1);
System.out.println("get next counter, value=" + next);
return next;
}
要成功部署该服务,共需要三步:1、创建网络;2、部署redis;3、部署app。
创建网络
为了能够通过容器名访问其它容器,这里需要创建一个bridge网络,名字为my_bridge
[root@localhost data]# docker network create --driver bridge my_bridge
6067b2b842be2daf748bd8300eff2d63cbb9cb15746a4fd540621010e684daf6
部署redis
redis的官方镜像可以在 链接 中查看,里面有详细的配置信息和启动说明。本文将会采用redis 4.0.11版本。
(1) 拉取redis镜像
docker pull redis:4.0.11
(2)运行redis容器
[root@localhost data]# docker run --name redis --network my_bridge -v /data/redis:/data -d redis:4.0.11 redis-server --appendonly yes
68334422af05dba03d87ec1dafbc1dc0bb85302389b0e7f04722405f80074d95
- --name:容器名为redis
- --network:redis容器连接到my_bridge网络
- -v:redis的持久化数据默认存放在容器的/data目录,这里把/data目录映射到宿主主机的/data/redis数据卷中
- -d:后台运行
- --appendonly yes:redis数据持久化
(3)验证redis是否运行正常
因为redis容器在启动的时候没有暴露端口到宿主主机,所以我们需要进入到redis容器中,并通过redis-cli操作redis验证是否正常工作。
交互方式进入容器:
[root@localhost data]# docker exec -it redis bash
root@68334422af05:/data#
运行redis-cli客户端,与redis交互
root@68334422af05:/# redis-cli
127.0.0.1:6379> set 123 123
OK
127.0.0.1:6379> get 123
"123"
OK,redis运行正常。
部署应用
springboot-redis的dockerfile如下,如果对dockerfile不熟悉,可以通过 构建一个简单的docker镜像 、 Dockerfile常用指令、 dockerfile构建一个简单的springboot应用镜像 熟悉。
FROM openjdk:8u181-jdk-alpine
ARG workdir=/app
VOLUME ${workdir}
WORKDIR ${workdir}
ADD springboot-redis-1.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
创建springboot-redis:1.0镜像
[root@localhost springboot-redis]# docker build -t springboot-redis:1.0 .
Sending build context to Docker daemon 25.47MB
Step 1/7 : FROM openjdk:8u181-jdk-alpine
---> 97bc1352afde
Step 2/7 : ARG workdir=/app
---> Running in 65e48ea3ccf6
Removing intermediate container 65e48ea3ccf6
---> 15ef3bac3e17
Step 3/7 : VOLUME ${workdir}
---> Running in 0b5421f1827d
Removing intermediate container 0b5421f1827d
---> ce5e62a86355
Step 4/7 : WORKDIR ${workdir}
Removing intermediate container 9009b9ac08e6
---> 2e50c02c2f88
Step 5/7 : ADD springboot-redis-1.0.jar app.jar
---> 20e46c2d3b76
Step 6/7 : EXPOSE 8080
---> Running in c58cf2d973ee
Removing intermediate container c58cf2d973ee
---> bc5cb5e87d27
Step 7/7 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]
---> Running in b66b3e2ecf6e
Removing intermediate container b66b3e2ecf6e
---> 05de26e57ed3
Successfully built 05de26e57ed3
Successfully tagged springboot-redis:1.0
运行springboot-redis容器。
[root@localhost ~]# docker run -p 8080:8080 -d --name springboot-redis --network my_bridge --env spring.redis.host=redis springboot-redis:1.0
因为设置了容器的网络是前面定义的my_bridge,所以在springboot-redis容器中,可以通过redis容器名访问到容器。所以,可以通过--env参数设置redis的地址是 redis 。
通过下面的命令可以实时查看日志输出
[root@localhost ~]# docker logs -f springboot-redis
在浏览器上验证一下服务是否正常。192.168.88.30是我的宿主机IP。
总结
有时,一个应用需要很多个服务同时部署,如果都按照上面的方式进行部署,将是一个很吃力的事情。那么,有什么样的方式可以简化我们的部署呢?docker-compose是docker官方提供的服务编排工具,通过docker-compose脚本可以批量启动我们的服务。