目前为止,我花了很多时间在单个容器中运行程序,并开始思考了一些问题:
“如果你有一个有多服务的程序,并且可能需要扩展几个独立的服务,那么怎么做呢?”以及
“如何让一个容器中的应用程序如何与另一个容器(中的程序)进行通信?”
Kubernetes的一个特性是从多个容器中构建应用程序并进行可操作的扩展,但是我现在还没有准备好一下子去完全实现这个想法。况且,Docker 1.12添加了“swarm模式”以及docker-compose工具,看起来Docker已经拥有了帮助构建和扩展多容器应用的大部分工具,我们并不需要去找额外的工具来做这些事情。
所以这里是我开始着手的地方:
事实证明,为每一个容器编写一个单独的dockerfile后重新在docker-compose.yml进行连接并不会麻烦很多。
从每个容器开始,下面是每个简单的Docker文件:
FROM java:openjdk-8-alpine
ADD SpringBootAddressBook-0.0.1-SNAPSHOT.jar /opt/SpringBootAddressBook-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENV MONGODB_DB_NAME addressbook
ENV MONGODB_DB_HOST mongo
ENV MONGODB_DB_PORT 27017
ENTRYPOINT ["java", "-jar", "/opt/SpringBootAddressBook-0.0.1-SNAPSHOT.jar"]
MongoDB可以直接利用Docker Hub上的官方dockerfiles运行,使用一个容器作为服务容器,另一个作为数据容器 - 请参阅下面的完整docker-compose文件。
把它们放在一起,这里是Docker Compose文件,将容器联在一起:
version: '2'
services:
mongodata:
image: mongo:3.2
volumes:
- /data/db
entrypoint: /bin/bash
mongo:
image: mongo:3.2
depends_on:
- mongodata
volumes_from:
- mongodata
ports:
#kh: only specify internal port, not external, so we can scale with docker-compose scale
- "27017"
addressbook:
image: addressbook
depends_on:
- mongo
environment:
- MONGODB_DB_NAME=addressbook
ports:
- 8080:8080
links:
- mongo
现在,这个容器集群可以重新作为一个整体运行:
$ docker-compose up
...停止:
$ docker-compose down
你可以单独的对任何容器进行扩展:
$ docker-compose scale containername=count
...其中count是调整的容器实例的数量。
那么,如果你想添加一个Web前端作为一个容器呢?很简单。这里有一个由nginx提供的AngularJS前端:
web:
image: docker-web-angularjs
ports:
- "80"
现在,如果我们想为REST后端和Nginx前端启动多个容器,我们还缺一个负载平衡器,对不对?同样也很简单,只需添加haproxy:
lb:
image: dockercloud/haproxy
depends_on:
- addressbook
environment:
- STATS_PORT=1936
- STATS_AUTH="admin:password"
links:
- addressbook
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 80:80
- 1936:1936
我注意到容器的启动顺序并不总是可预测的,有时Spring Boot容器会在MongoDB容器启动之前启动。这可以通过添加depends_on关键字来解决。我不确定是否真的需要添加所有的依赖项来强制实现特定的启动顺序,但是这适用于我。我写在完整的docker-compose.yml中的顺序是(从头到尾):
AddressBook后端的完整源代码托管在GitHub。deploy- *文件夹包含各个dockerfiles。