Docker容器化从零开始搭建Spring Cloud微服务系统:docker-compose

前言

在没有docker-compose之前,我们创建和启动一个容器方式如下:

1.通过类似下面两种方式的命令来构建或者拉取一个docker镜像。

方式1:创建Dockerfile文件来构建镜像(命令最后的点别漏了~):

docker build -t registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.0 .

方式2: 直接从Docker Hub或者阿里云或者网易云等等平台拉取镜像。

docker pull registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.0

2.使用命令docker run ...来来依赖镜像创建并运行一个容器,中间还要加一些复杂的参数。

docker run --restart always --privileged=true -e MODE=standalone -e SPRING_DATASOURCE_PLATFORM="mysql" -e MYSQL_MASTER_SERVICE_HOST="www.wangjihong.com.cn" -e MYSQL_MASTER_SERVICE_PORT="3300" -e MYSQL_MASTER_SERVICE_DB_NAME="nacos" -e MYSQL_MASTER_SERVICE_USER="root" -e MYSQL_MASTER_SERVICE_PASSWORD="123456" -e MYSQL_SLAVE_SERVICE_HOST="www.wangjihong.com.cn" -e MYSQL_SLAVE_SERVICE_PORT="3301" -v=/usr/local/dockerfiles/nacos/data:/home/nacos/data -v=/usr/local/dockerfiles/nacos/logs:/home/nacos/logs --name docker-nacos-server1.0.0 -d -p 8848:8848 registry.cn-beijing.aliyuncs.com/wangjihong/nacos-server:1.0.0

3.使用命令docker exec ...进入容器操作。

docker exec -it docker-nacos-server1.0.0 bash

4.查看容器启动日志。

docker logs -f docker-nacos-server1.0.0

综上我们可以看出,运行单个docker容器我们要用命众多命令来管理容器,这种情况下若是只运行一个容器还好,但如果我们有一堆容器(如: mysqlkibanaelasticsearch 等等...)需要执行的话,这样管理是极其麻烦的,利器docker-compose 的出现便解决了此类问题。


What-什么是docker-compose

  1. Docker Compose 将所管理的容器分为三层,分别是工程(project)、服务(service)、容器(container)。
  2. Docker Compose 运行目录下的所有文件(docker-compose.yml)组成一个工程,一个工程包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖,一个服务可包括多个容器实例。
  3. Docker Compose 是一个批处理工具,我们可以通过配置一个docker-compose.yml文件去定义多个容器的应用,通过一条命令就可以根据docker-compose.yml文件创建出指定的容器,文件格式如下(使用docker-compose.yml部署微服务调用链监控组件skywalking):
version: '2'
services:
  elasticsearch:
    image: elasticsearch:5.6
    container_name: elasticsearch
    ports:
      - 9200:9200
    volumes:
      - ./es/data:/usr/share/elasticsearch/data
      - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

  kibana:
    image: kibana:5.6
    container_name: kibana
    ports:
      - 5601:5601
    links:
      - elasticsearch:elasticsearch
    depends_on:
      - elasticsearch
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200

  skywalking:
      image: weihanli/skywalking:5.0.0-GA
      container_name: skywalking
      ports:
        - 10800:10800
        - 11800:11800
        - 12800:12800
        - 8090:8080
      volumes:
        - ./skywalking/application.yml:/app/skywalking/config/application.yml
      links:
        - elasticsearch:elasticsearch
      depends_on:
        - elasticsearch

Why-为什么要用docker-compose

可参考前言介绍。


How-如何使用docker-compose

安装docker-compose

从github上下载docker-compose二进制文件 https://github.com/docker/com... 并按描述安装。

1.下载最新版的docker-compose文件。

sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2.添加可执行权限。

sudo chmod +x /usr/local/bin/docker-compose

3.测试安装结果。

docker-compose --version

4.安装pip。

sudo pip install docker-compose

运行docker-compose

1.在centos上创建一个docker-compose.yml文件,里面写上自己的多容器内容,如上述skywalking对应的文件内容。

2.最后在centos上打开docker-compose.yml所在的文件夹路径下执行docker-compopse up就可以启动了,如果需要后台启动则为docker-compopse up -d


docker-compose配置文件参数使用详解

通过上述描述我们可以看到一份标准配置文件应该包含 version、services、networks 三大部分,其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则。

version

指定 docker-compose.yml 文件的写法格式,如:

version: '3'

services

定义多个容器服务集合,如定义docker-mysql5.7-master-service和elasticsearch-service两个容器服务写法:

services:
  docker-mysql5.7-master-sevice:
    image: registry.cn-beijing.aliyuncs.com/wangjihong/mysql:5.7
    container_name: docker-mysql5.7-master
    ports:
      - 3300:3306
  elasticsearch-sevice:
    image: elasticsearch:5.6
    container_name: elasticsearch
    ports:
      - 9200:9200

image

标明image的ID,这个image的ID可以是本地也可以是远程的,如果本地不存在,Compose会尝试去pull下来,如在services标签下的第二级标签是docker-mysql5.7-master-service,它表示服务名称,用户可自定义名称,image则是指定服务的镜像名称或镜像ID,如果镜像在本地不存在,Compose将会尝试拉取这个镜像。

services:
  docker-mysql5.7-master-sevice:
    image: registry.cn-beijing.aliyuncs.com/wangjihong/mysql:5.7
    container_name: docker-mysql5.7-master
    ports:
      - 3300:3306

build

配置构建时,Compose会利用它自动构建镜像,该值可以是一个路径,也可以是一个对象,用于指定Dockerfile参数。该参数指定Dockerfile文件的路径,Compose将会以一个已存在的名称进行构建并标记,并随后使用这个image。

示例:

services:
  docker-mysql5.7-master-sevice:
    image: mysql:5.7
    container_name: docker-mysql5.7-master
    ports:
      - 3300:3306
    build:
      context: /usr/local/dockerfiles/mysql
      dockerfile: Dockerfile
      args:
        - buildno=1
        - password=secre

示例说明:
docker-mysql5.7-master-sevice容器服务会根据/usr/local/dockerfiles/mysql路径下的Dockerfile文件以buildno=1,password=secre为环境变量来构建出一个image ID为mysql:5.7的镜像。其中:

context:是一个目录路径,也可以是一个git repository url。 当所提供的值是相对路径的时候,它被解释为compose文件位置的相对路径。目录里的信息会被当做构建内容发送到Docker daemon, context只支持version2+, version1只能使用build。

Dockerfile:Compose将会使用指定的该Dockerfile文件去构建,但必须指定路径,如与context搭配使用。

args:仅支持Version2+,用于添加构建环境变量参数,但是仅构建过程期间可以使用,如:

ARG buildno
ARG password
 
RUN echo "Build number: $buildno"
RUN script-requiring-password.sh "$password"

depends_on

表示服务之间的依赖关系,作用如下:
1.docker-compose up将会根据依赖关系的顺序开启所有服务,下面的例子中, kibana会早于elasticsearch服务先启动。
2.docker-compose upSERVICE会自动包含 SERVICE的依赖,下面的例子中, 执行docker-compose up命令时kibana将会创建,同时也会启动elasticsearch服务。

version: '2'
services:
  elasticsearch:
    image: elasticsearch:5.6
    container_name: elasticsearch
    ports:
      - 9200:9200
    volumes:
      - ./es/data:/usr/share/elasticsearch/data
      - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
  kibana:
    image: kibana:5.6
    container_name: kibana
    ports:
      - 5601:5601
    links:
      - elasticsearch:elasticsearch
    depends_on:
      - elasticsearch
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200

注意:kibana服务启动前并不会等待elasticsearch服务到ready状态才启动。如果需要等待其他服务到ready状态,可以参考https://docs.docker.com/compo...

environment

环境变量配置,可以用数组或字典两种方式。
格式如:

environment:
    RACK_ENV: development
    SHOW: 'ture'
-------------------------
environment:
    - RACK_ENV=development
    - SHOW=ture

示例如:

version: '2'
services:
  kibana:
    image: kibana:5.6
    container_name: kibana
    ports:
      - 5601:5601
    links:
      - elasticsearch:elasticsearch
    depends_on:
      - elasticsearch
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200

env_file

从文件中获取环境变量,可以指定一个文件路径或路径列表,其优先级低于 environment指定的环境变量。

env_file: .env
---------------
env_file:
    - ./common.env

links

将指定容器连接到当前连接,可以设置别名,避免ip方式导致的容器重启动态改变的无法连接情况,达到服务之间可以使用服务名称相互访问,links 允许定义一个别名,从而使用该别名访问其它服务,类似于微服务中的根据服务名查找主机服务的场景。

version: '2'
services:
  kibana:
    image: kibana:5.6
    container_name: kibana
    ports:
      - 5601:5601
    links: 
      # 指定服务名称:别名
      - elasticsearch:elasticsearch-server

备注:示例中kibana服务就可以使用elasticsearch或elasticsearch-server作为hostname访问elasticsearch:elasticsearch服务了。

volumes

挂载指定的路径或者named 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

示例
将容器的/usr/share/elasticsearch/data挂载到宿主机的./es/data文件下。目的是可以不进入容器内部直接通过宿主机的./es/data目录就可以看到容器的数据内容,避免容器删除销毁后造成把数据也销毁了的严重问题。

version: '2'
services:
  elasticsearch:
    image: elasticsearch:5.6
    container_name: elasticsearch
    ports:
      - 9200:9200
    volumes:
      - ./es/data:/usr/share/elasticsearch/data
      - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

expose

对外暴露端口,只将端口暴露给连接的服务(已经linked的service可访问),而不暴露给主机。

expose:
 - "6666"
 - "8888"

ports

对外暴露的端口定义,和expose对应。
格式:- "宿主机端口:容器暴露端口"

ports:   
  # 暴露端口信息
  - "3300:3306"
  - "8080:8080"

注意
当以 HOST:CONTAINER的形式映射端口的时候,当容器的端口低于60的时候可能会遇到错误,因为YAML会解析xx:yy数字为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

command

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

command: bundle exec thin -p 3000
----------------------------------
command: [bundle,exec,thin,-p,3000]

dns

配置 dns 服务器,可以是一个值或列表。

dns: 8.8.8.8
------------
dns:
    - 8.8.8.8
    - 9.9.9.9

dns_search

配置 DNS 搜索域,可以是一个值或列表。

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

network_mode

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

logs

--no-color          单色输出,不显示其他颜.
-f, --follow        跟踪日志输出,就是可以实时查看日志
-t, --timestamps    显示时间戳
--tail              从日志的结尾显示,--tail=200

labels

添加 metadata 到容器中。可以使用数组或字典。

labels:
  app-description: "website for wangjihong"
  app-website: "www.wangjihong.com.cn"
  app-memo: "一个不太神奇的网站"
  
labels:
  - "app-description=website for wangjihong"
  - "app-website=www.wangjihong.com.cn"
  - "app-memo=一个不太神奇的网站"

pid

将当前的PID设置为主机的PID,从而打开容器和host操作系统之间的PID地址共享。带有PID启动的容器可以访问和操纵其他真实机器空间容器。

pid:"host"

docker-compose命令使用详解

Docker Compose 常用命令与配置如下(与docker命令基本一致)。

ps

列出所有运行容器。

docker-compose ps

logs

查看服务日志输出。

docker-compose logs

port

打印绑定的公共端口,下面命令可以输出 elasticsearch 服务 9002 端口所绑定的公共端口。

docker-compose port elasticsearch 9002

build

构建或者重新构建服务。

docker-compose build

start

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

docker-compose start elasticsearch

stop

停止已运行的服务的容器。

docker-compose stop elasticsearch

rm

删除指定服务的容器。

docker-compose rm elasticsearch

up

构建、启动容器。

----前台启动---
docker-compose up
----后台启动---
docker-compose up -d
----指定文件后台启动---
docker-compose -f docker-compose-nacos.yml up -d

kill

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

docker-compose kill elasticsearch

pull

下载服务镜像。

docker-compose pull elasticsearch

scale

设置指定服务运行容器的个数,以 service=num 形式指定。

docker-compose scale user=3 movie=3

run

在一个服务上执行一个命令。

docker-compose run elasticsearch bash

总结

本文只是介绍了docker-compose基本内容,想深入了解可以自行查资料,嘿嘿。
Docker容器化从零开始搭建Spring Cloud微服务系统:docker-compose

相关推荐