Docker Compose编排微服务

在前面的文章Docker部署Spring Boot中,使用maven构建镜像,然后使用docker命令操作容器。微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。Docker Compose可以轻松的管理容器,降低维护工作量。

一、Docker Compose简介

Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。官网地址
Compose 中有两个重要的概念:

  • 服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
  • 项目 ( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义。
    Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。可见,一个项目可以由多个服务(容器)关联而成, Compose 面向项目进行管理

Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose 来进行编排管理。

二、CentOS 7 安装docker compose

Compose有很多种安装方式,例如通过Shell、pip以及将Compose作为容器安装等。本文通过pip来安装Compose,其它安装方式可以参照官方文档

  1. 检查linux有没有安装python-pip包
pip -V
  1. 没有安装python-pip执行下面命令
yum -y install epel-release
  1. 执行成功之后,再次执行下面的命令
yum -y install python-pip
  1. 对安装好的pip进行升级
pip install --upgrade pip
  1. 安装docker compose
pip install docker-compose
  1. 检查安装的docker compose版本
docker-compose -version
  1. 安装compose命令补全工具
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose

这样重新登陆之后,输入docker-compose并按下tab键,Compose就可以自动补全命令。

三、docker compose入门

3.1 基本步骤

  1. 在 Dockfile 中定义你的应用环境,使其可以在任何地方重现该环境。
  2. docker-compose.yml 中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
  3. 运行dcoker-compose up,Compose 将启动并运行整个应用程序。

3.2 工程、服务、容器

Docker Compose将所管理的容器分为三层,分别是工程(project)、服务(service)、容器(container)。Docker Compose运行目录下的所有文件(docker-compose.yml、extends文件或环境变量文件)组成一个工程(默认为docker-compose.yml所在目录的目录名称)。一个工程可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖,一个服务科包括多个容器实例

3.3 docker-compose.yml常用命令

  1. build

    配置构建时的选项,Compose会利用它自动构建镜像。build的值可以是一个路径,例如:

    build: ./dir
    

    也可以是一个对象,用于指定Dockerfile和参数,例如:

    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
    
  2. command

    覆盖容器启动后默认执行命令:

    command: bundle exec thin -p 3000
    

    也可以是一个list,类似于Dockerfile中的CMD指令,格式如下:

    command: ["bundle", "exec", "thin", "-p", "3000"]
    
  3. dns

    配置DNS服务器。可以是一个值,也可以是一个列表。例如:

    dns: 8.8.8.8
    dns:
      - 8.8.8.8
      - 9.9.9.9
    
  4. dns_search

    配置DNS搜索域,可以是一个值,也可以是一个列表。例如:

    dns_search: example.com
    dns_search:
      - dc1.example.com
      - dc2.example.com
    
  5. environment

    环境变量设置,可使用数组或字典两种方式,例如:

    environment:
      RACK_ENV: development
      SHOW: 'true'
      SESSION_SECRET:
     
    environment:
      - RACK_ENV=development
      - SHOW=true
      - SESSION_SECRET
    
  6. env_file

    从文件中获取环境变量,可指定一个文件路径或路径列表。如果通过docker-compose -f FiLE指定了Compose文件,那么env_file中的路径是Compose文件所在目录的相对路径。使用environment指定的环境变量会覆盖env_file指定的环境变量。例如:

    env_file: .env
     
    env_file:
      - ./common.env
      - ./apps/web.env
      - /opt/secrets.env
    
  7. expose

    暴露端口,只将端口暴露给连接的服务,而不暴露给宿主机。例如:

    expose:
    - "3000"
    - "8000"
    
  8. external_links

    连接到docker-compose.yml外部的容器,甚至并非Compose管理的容器,特别是提供共享或公共服务的容器。格式跟links类似,例如:

    external_links:
    - redis_1
    - project_db_1:mysql
    - project_db_1:postgresql
    
  9. image

    指定镜像名称或镜像ID,如果本地不存在该镜像,Compose会尝试下载该镜像。例如:

    image: java
    
  10. links

    连接到其他服务容器。可以指定服务名称和服务列表(SERVICE:ALIAS),也可只指定服务名称。例如:

    web:
      links:
       - "db"
       - "db:database"
       - "redis"
    
  11. network_mode

    设置网络模式,例如:

    network_mode: "bridge"
    network_mode: "host"
    network_mode: "none"
    network_mode: "service:[service name]"
    network_mode: "container:[container name/id]"
    
  12. ports

    暴露端口信息,可使用HOST:CONTAINER的格式,也可只指定容器端口(此时缩主机将会随机选择端口),类似于docker run -p
    需要注意的是,当使用HOST:CONTAINER格式映射端口时,容器端口小于60将会得到错误的接口。因此,建议使用字符串的形式,例如:

    
    ports:
    - "3000"
    - "3000-3005"
    - "8000:8000"
    - "9090-9091:8080-8081"
    - "49100:22"
    - "127.0.0.1:8001:8001"
    - "127.0.0.1:5000-5010:5000-5010"
    - "6060:6060/udp"
    - "12400-12500:1240"
    
  13. volumes

    卷挂载路径设置。可以设置宿主机路径(HOST:CONTAINER),也可指定访问模式(HOST:CONTAINER:ro),例如:

    volumes:
      # Just specify a path and let the Engine create a volume
      - /var/lib/mysql
     
      # Specify an absolute path mapping
      - /opt/data:/var/lib/mysql
     
      # Path on the host, relative to the Compose file
      - ./cache:/tmp/cache
     
      # User-relative path
      - ~/configs:/etc/configs/:ro
     
      # Named volume
      - datavolume:/var/lib/mysql
    
  14. volumes_from

    从另外一个服务或容器挂载卷。可指定只读(ro)或读写(rw),默认是读写(rw),例如:

    
    volumes_from:
    - service_name
    - service_name:ro
    - container:container_name
    - container:container_name:r
    

四、docker-compose常用命令

下面讨论docker-compose的常用命令。

  1. build

    构建或重新构建服务。服务被构建后将会以project_service的形式存在,例如:compo-setest_db

  2. help

    查看指定命令的文档

    docker-compose help COMMAND
    
  3. kill

    通过发送SIGKILL信号停止指定服务的容器。示例:

    docker-compose kill eureka
    
  4. logs

    查看服务的日志输入

  5. port

    打印绑定的公共端口。示例:

      docker-compose port eureka 8761
    

    可输出eureka服务8761端口所绑定的公共端口

  6. ps

    列出所有容器。示例:

    docker-compose ps
    
  7. pull

    下载服务镜像

  8. rm

    删除指定服务的容器。示例:

    docker-compose rm eureka
    
  9. run

    在一个服务上执行一个命令。示例:

    docker-composse run web bash
    

    这样可以启动一个web服务,同时执行bash命令

  10. scale

    设置指定服务运实例的个数,以service=num的形式 指定。示例:

    docker-compose sscale user=3 movice=3
    
  11. start

    启动指定服务已存在的容器。示例 :

    docker-compose start eureka
    
  12. stop

    停止已运行的容器。示例:

    docker-compose sstop eureka
    
  13. up

    构建、创建、重新构建启动连接服务相关的容器。所有连接的服务都会启动,除非它们已运行。docker-compose up命令会聚合所有容器的输出,当命令退出时,所有容器都会退出。使用docker-compose up -d可在后台启动并运行所有容器。

五、部署示例

本节使用docker compose部署spring cloud项目。

  1. 服务概述
    我们一共部署四个服务,如下所示:
服务 端口 备注
eureka-server 1111,1112 服务注册与发现中心(高可用部署)
demo 8102 服务1
feign-upload_first 8100 服务2
feign_upload_second 8101 服务
  1. 各服务添加Docker构建插件

    <!-- Docker maven plugin -->
          <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>
            <configuration>
              <imageName>simon/${project.artifactId}:${project.version}</imageName>
              <!--<dockerDirectory>src/main/docker</dockerDirectory>-->
              <forceTags>true</forceTags>
              <baseImage>java</baseImage>
              <entryPoint>["java","-jar","/${project.build.finalName}.jar"]</entryPoint>
              <resources>
                <resource>
                  <targetPath>/</targetPath>
                  <directory>${project.build.directory}</directory>
                  <include>${project.build.finalName}.jar</include>
                </resource>
              </resources>
            </configuration>
          </plugin>
    
  2. 修改服务注册中心地址
    一组 compose 的服务通讯需要使用 services 的名称进行访问
    之前各个项目配置的服务注册中心地址如下:

    eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
    

    由于Docker默认网络模式是bridge,各个容器的IP不相同,因此上面的配置不满足需求。可为Eureka Server所在的容器配置主机名,并让各个服务使用主机名访问Eureka Server。所有服务修改配置如下:

    eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
    

    由于Eureka server是高可用部署,所以配置文件如下:

    • application-peer1.properties
    server.port=1111
    spring.application.name=eureka-server
    eureka.instance.hostname=peer1
    eureka.client.service-url.defaultZone=http://peer2:1112/eureka/
    
    • application-peer2.properties
    server.port=1112
    spring.application.name=eureka-server
    eureka.instance.hostname=peer2
    eureka.client.service-url.defaultZone=http://peer1:1111/eureka/
    
  3. 编写docker-compose-manage.yml

    version: "2"
    services:
      # 指定服务名称
      peer1:
        image: ibase/eureka-server:0.0.1-SNAPSHOT
        ports:
          - "1111:1111"
        environment:
          - spring.profiles.active=peer1
      peer2:
        image: ibase/eureka-server:0.0.1-SNAPSHOT
        hostname: peer2
        ports:
          - "1112:1112"
        environment:
          - spring.profiles.active=peer2
    
  4. 编写docker-compose-services.yml

    version: "2"
    services:
      # 指定服务名称
      feign_upload_first:
        #指定服务所使用的镜像名称
        image: ibase/feign_upload_first:0.0.1-SNAPSHOT
        ports:
        - "8100:8100"
      feign_upload_second:
        image: ibase/feign_upload_second:0.0.1-SNAPSHOT
        ports:
        - "8101:8101"
      demo:
        image: ibase/demo:0.0.1-SNAPSHOT
        ports:
        - "8102:8102"
    

    这里说明一下,为什么有两份配置,不清楚什么原因,配置写在一起,启动容器会报错,服务治理与服务service分开就不会出错,这个需要研究一下。

  5. 编译部署
    将所有项目和配置文件上传到linux上,在各个服务根目录使用如下命令构建镜像:

    mvn clean package docker:build
    

    先后执行如下命令启动项目:

    docker-compose docker-compose-manage.yml up
    
    docker-compose docker-compose-services.yml up
    
  6. 启动后测试
    正常访问服务接口。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容