到目前为止,我使用单个docker容器部署过很多应用程序并开始思考下面的问题:
“如何扩展一个有多个服务的应用的单个服务?”
“不同容器间应用程序如何通信?”
对于这些问题,我认为 Kubernetes是构建和扩展灵活的多服务应用程序的一个不错的选择,但是Docker自身也提供了相应的功能:Docker 1.12添加了swarm和docker-compose模块,使用这些足够在不添加额外工具的情况下构建和扩展多服务应用程序。
所以我开始了构建多服务应用的尝试,以下是我使用的容器:
事实证明,这并不比构建单个容器复杂多少。只需要构建单个容器的Dockerfiles,然后通过配置docker-compose.yml文件将单个容器组合。
下面是各容器的Dockerfile文件:
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构建,这里使用一个容器作为mongodb服务器,另一个作为数据容器 - 请参阅下面完整的docker-compose.yml文件。
这是将数据库容器与数据卷容器组合的Docker Compose文件:
version: '2'
services:
mongodata:
image: mongo:3.2
volumes:
- /data/db
entrypoint: /bin/bash
mongo:
image: mongo:3.2
depends_on: 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前端应用启动多个容器,我们也需要一个负载均衡应用对吧?实现也很简单,只需在docker-compose.yml中添加haproxy参数设置:
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中配置的容器启动顺序是(从第一个到最后一个):
在GitHub上有AddressBook后端应用的完整源代码,其中eploy- *文件夹包含各个dockerfiles。