使用Docker 1.12.x构建多容器Web应用程序

时间:2022-04-21
本文章向大家介绍使用Docker 1.12.x构建多容器Web应用程序,主要内容包括Spring Boot 容器、MongoDB容器、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

到目前为止,我使用单个docker容器部署过很多应用程序并开始思考下面的问题:

“如何扩展一个有多个服务的应用的单个服务?”

“不同容器间应用程序如何通信?”

对于这些问题,我认为 Kubernetes是构建和扩展灵活的多服务应用程序的一个不错的选择,但是Docker自身也提供了相应的功能:Docker 1.12添加了swarm和docker-compose模块,使用这些足够在不添加额外工具的情况下构建和扩展多服务应用程序。

所以我开始了构建多服务应用的尝试,以下是我使用的容器:

  • 容器1:基于JAX-RS和Spring Boot的 RESTful应用。
  • 容器2:MongoDB数据库。
  • 容器3:MongoDB的docker容器数据卷。

事实证明,这并不比构建单个容器复杂多少。只需要构建单个容器的Dockerfiles,然后通过配置docker-compose.yml文件将单个容器组合。

下面是各容器的Dockerfile文件:

Spring Boot 容器

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容器

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中配置的容器启动顺序是(从第一个到最后一个):

  • mongodata(数据容器)
  • mongo
  • addressbook(提供REST接口的后端应用)
  • web(基于AngularJS前端应用)
  • haproxy

在GitHub上有AddressBook后端应用的完整源代码,其中eploy- *文件夹包含各个dockerfiles。