docker-compose 安装、语法 build、image、environment、expose、ports、restart、volume、depends_on、links 容器编排实践

细节请参考:
https://docs.docker.com/engine/reference/run/
https://docs.docker.com/compose/reference/

Github: https://github.com/docker/compose
官网:https://docs.docker.com/compose/compose-file/

1. 概述

问题:如果要使用 Docker 运行 LNMP 架构,那么 NginxMySQLPHPLinux三个服务运行在一个容器里,还是运行在多个容器里呢?

答案是都可以。

  • 你可以分别放在三个容器中
  • 也可以全部放在一个容器中
  • 还可以 PHPLinuxNginx共用一个容器,MySQL 单独一个容器
  • 甚至还可以分别做多个容器,实现更复杂的架构

如果实现一个容器架构(微服务架构),一个个的 docker run 启动很麻烦,更麻烦的是容器之间的连接与交互。所以我们需要用到容器编排。

2. 使用步骤

Docker Compose 将所管理的容器分为三层:

  • 工程(project)
  • 服务(service)
  • 容器(contaienr)

Docker Compose 运行的目录下的所有文件(docker-compose.ymlextends 文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。

一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、关系,一个服务当中可包括多个容器实例。

使用 Compose 基本上分为三步:

  1. Dockerfile 定义应用的运行环境(镜像)
  2. docker-compose.yml 定义组成应用的各服务
  3. docker-compose up -d 构建并启动整个应用

​Docker Compose 是一个由 Python 编写的软件,在拥有 Python 运行环境的机器上,我们可以直接运行它,不需要其它的操作。

3. 安装

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$
$ sudo docker-compose version
docker-compose version 1.21.2, build a133471
docker-py version: 3.3.0
CPython version: 3.6.5
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

我们也能够通过 Python 的包管理工具 pip 来安装 Docker Compose

$ sudo pip install docker-compose

docker-compose 最早是用 Python 编写的,2.0 版本后改用 Go 语言重新实现, 1.x 的用法和 2.x 略有些不同,最后一个 Python 开发的版本是 1.29.2

1.xdocker-comose 的默认文件是 docker-compose.yml2.x 后默认文件也可以使用compose.yml

有的 docker-compose YAML 文件开头有一个 version 字段,它标记了规范的版本,用来实现向后兼容,但现在它已经被废弃了,不建议再使用。

4. 常见语法

Docker Compose 使用 Yaml 格式文件来编排。

参考: https://docs.docker.com/compose/compose-file/

Dockerfile 采用 Dockerfile 这个名字作为镜像构建定义的默认文件名一样,Docker Compose 的配置文件也有一个缺省的文件名,也就是 docker-compose.yml,如非必要,我建议大家直接使用这个文件名来做 Docker Compose 项目的定义。

4.1 build

指定镜像构建时的 dockerfile 目录,格式一般为绝对路径目录或相对路径目录(dockerfile需要命名为 Dockerfile):

build: /path/to/build/dir
或者
build: ./dir

4.2 image

指定要启动容器的镜像:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd

如果镜像不存在,Compose 尝试拉它。

如果指定了构建,可以使用指定的选项构建它,并使用指定的 tag 进行标记。

4.3 environment

设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置。

environmentDockerfile 中的 ENV 指令一样,会把变量一直保存在镜像、容器中。

格式

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

4.4 expose:

这个标签与 Dockerfile 中的 EXPOSE 指令一样,用于指定暴露的端口,但只将端口暴露给连接的服务,而不暴露给主机。

expose:
 - "3000"
 - "8000"

4.5 ports

映射端口,可以使用 HOST:CONTAINER 的方式指定端口,也可以指定容器端口(选择临时主机端口),宿主机会随机映射端口。

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"

我们可以利用它进行宿主机与容器端口的映射,这个配置与 docker CLI-p 选项的使用方法是近似的。

需要注意的是,由于 YAML 格式对 xx:yy 这种格式的解析有特殊性,在设置小于 60 的值时,会被当成时间而不是字符串来处理,所以我们最好使用引号将端口映射的定义包裹起来,避免歧义。

4.6 restart

指定 Docker 容器的重启策略。

默认值为 no,即在任何情况下都不会重新启动容器

  • 当值为 always 时,容器退出时总是重新启动(会随着 Docker 服务启动而启动容器)
  • 当值为 on-failure 时,当出现 on-failure 报错(非正常退出,退出状态非 0),才会重启容器
  • 当值为 unless-stopped 时,在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器
restart: "no"
restart: always
restart: on-failure
restart: on-failure:3
restart: unless-stopped

4.7 volume

数据卷挂载,可以直接使用 HOST:CONTAINER 这样的格式,或者使用 HOST:CONTAINER:ro 这样的格式,ro 代表数据卷是只读的。

volumes:
  ### 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql

  ### 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql

  ### 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
  - ./cache:/tmp/cache

  ### 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro

  ### 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql
 

在使用外部文件挂载的时候,我们可以直接指定相对目录进行挂载,这里的相对目录是指相对于 docker-compose.yml 文件的目录。

由于有相对目录这样的机制,我们可以将 docker-compose.yml 和所有相关的挂载文件放置到同一个文件夹下,形成一个完整的项目文件夹。这样既可以很好的整理项目文件,也利于完整的进行项目迁移。

4.8 depends_on

虽然我们在 Docker Compose 的配置文件里定义服务,在书写上有由上至下的先后关系,但实际在容器启动中,由于各种因素的存在,其顺序还是无法保障的。

所以,如果我们的服务间有非常强的依赖关系,我们就必须告知 Docker Compose 容器的先后启动顺序。只有当被依赖的容器完全启动后,Docker Compose 才会创建和启动这个容器。

此标签解决了容器的依赖、启动先后的问题。

version: '3'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: mysql

使用 docker-compose up web 启动,会先启动 RedisDB,再启动 Web

Docker Compose 为我们启动项目的时候,会检查所有依赖,形成正确的启动顺序并按这个顺序来依次启动容器。

4.9 links

链接到其它服务的中的容器,与 link 连接一样效果,会连接到其它服务中的容器。

web:
  links:
   - db
   - db:database
   - redis

4.10 实践

version: "3"

services:

  redis:
    image: redis:3.2
    networks:
      - backend
    volumes:
      - ./redis/redis.conf:/etc/redis.conf:ro
    ports:
      - "6379:6379"
    command: ["redis-server", "/etc/redis.conf"]

  database:
    image: mysql:5.7
    networks:
      - backend
    volumes:
      - ./mysql/my.cnf:/etc/mysql/my.cnf:ro
      - mysql-data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=my-secret-pw
    ports:
      - "3306:3306"

  webapp:
    build: ./webapp
    networks:
      - frontend
      - backend
    volumes:
      - ./webapp:/webapp
    depends_on:
      - redis
      - database

  nginx:
    image: nginx:1.12
    networks:
      - frontend
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./webapp/html:/webapp/html
    depends_on:
      - webapp
    ports:
      - "80:80"
      - "443:443"

networks:
  frontend:
  backend:

volumes:
  mysql-data:

在这个 Docker Compose 的示例中,我们看到占有大量篇幅的就是 services 部分,也就是服务定义的部分了。Docker Compose 中的服务,是对一组相同容器集群统一配置的定义。

在使用时,我们首先要为每个服务定义一个名称,用以区别不同的服务。在这个例子里,redisdatabasewebappnginx 就是服务的名称。

Docker Compose 里,我们可以通过两种方式为服务指定所采用的镜像。

  • 一种是通过 image 这个配置,这个相对简单,给出能在镜像仓库中找到镜像的名称即可。
  • 另外一种指定镜像的方式就是直接采用 Dockerfile 来构建镜像,通过 build 这个配置我们能够定义构建的环境目录,这与 docker build 中的环境目录是同一个含义。如果我们通过这种方式指定镜像,那么 Docker Compose 先会帮助我们执行镜像的构建,之后再通过这个镜像启动容器。

当然,在 docker build 里我们还能通过选项定义许多内容,这些在 Docker Compose 里我们依然可以。

## ......
  webapp:
    build:
      context: ./webapp
      dockerfile: webapp-dockerfile
      args:
        - JAVA_VERSION=1.6
## ......

由于 Docker Compose 的配置已经固化下来,所以我们不需要担心忘记之前执行了哪些命令来启动容器,当每次需要开启或关闭环境时,只需要 docker-compose up -ddocker-compose down 命令,就能轻松完成操作。

5. 综合案例:容器化应用部署实践

5.1 环境配置

在宿主机上打开 ip_forward,为我们下面要映射容器的端口到宿主机,只有打开 ip_forward 才能映射成功。

### vim /etc/sysctl.conf
net.ipv4.ip_forward=1
### sysctl -p

5.2 部署 WordPress 应用

  1. 创建一个名为 wordpress 的 project(工程):
[root@daniel ~]### mkdir -p /docker-compose/wordpress
[root@daniel ~]### cd /docker-compose/wordpress
  1. 创建 docker-compose.yml:
[root@daniel wordpress]### vim docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - "./data:/var/lib/mysql"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    expose:
      - "3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    links:
      - db
    ports:
      - "8010:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306	# 注意这里,数据库的网络标识
      WORDPRESS_DB_PASSWORD: wordpress

说明:这个应用定义了两个容器服务:dbwordpress

因为 docker-compose 会自动把 db 的名字用做网络标识,所以在连接数据库的时候(字段 WORDPRESS_DB_HOST )就不需要手动指定 IP 地址了,直接用“service”的名字 db 就行了。

db 容器通 mysql:5.7 镜像启动:

  • MySQL 的数据目录挂载到当前目录 ./data,此目录不存在会自动创建
  • 容器重启策略为 always
  • 设置了连接 MySQL 的 4 个变量

wordpress 容器通过 wordpress:latest 启动:

  • 需要 db 容器先启动再启动 wordpress 容器
  • wordpress 容器要 link 连接 db 容器
  • wordpress 容器将 80 端口映射到宿主机的 8010 端口
  • 容器重启策略为 always
  • 设置连接数据库的变量
  1. 启动:

对于开发来说,最常使用的 Docker Compose 命令就是 docker-compose updocker-compose down 了。

docker-compose up 命令类似于 Docker Engine 中的 docker run,它会根据 docker-compose.yml 中配置的内容,创建所有的容器、网络、数据卷等等内容,并将它们启动。与 docker run 一样,默认情况下 docker-compose up 会在“前台”运行,我们可以用 -d 选项使其“后台”运行。事实上,我们大多数情况都会加上 -d 选项。

[root@daniel wordpress]### docker-compose up -d

如果本地没有镜像,下载的两个镜像比较大。

[root@daniel wordpress]### docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               5.7                 e9c354083de7        3 days ago          373MB
wordpress           latest              4ba1e63bd20c        8 days ago          501MB

需要注意的是,docker-compose 命令默认会识别当前控制台所在目录内的 docker-compose.yml 文件,而会以这个目录的名字作为组装的应用项目的名称。如果我们需要改变它们,可以通过选项 -f 来修改识别的 Docker Compose 配置文件,通过 -p 选项来定义项目名。

docker-compose -f ./compose/docker-compose.yml -p myapp up -d

docker-compose up 相反,docker-compose down 命令用于停止所有的容器,并将它们删除,同时消除网络等配置内容,也就是几乎将这个 Docker Compose 项目的所有影响从 Docker 中清除。

 docker-compose down
  1. 安装与访问

在浏览器端,访问容器主机的 8010 端口,安装访问,最终效果如下:
21

6. docker-compose 常用命令

Docker Engine 中,如果我们想要查看容器中主进程的输出内容,可以使用 docker logs 命令。而由于在 Docker Compose 下运行的服务,其命名都是由 Docker Compose 自动完成的,如果我们直接使用 docker logs 就需要先找到容器的名字,这显然有些麻烦了。我们可以直接使用 docker-compose logs 命令来完成这项工作。

$ sudo docker-compose logs nginx

docker-compose logs 衔接的是 Docker Compose 中所定义的服务的名称。

同理,在 Docker Compose 还有几个类似的命令可以单独控制某个或某些服务。

通过 docker-compose createdocker-compose startdocker-compose stop 我们可以实现与 docker createdocker startdocker stop 相似的效果,只不过操作的对象由 Docker Engine 中的容器变为了 Docker Compose 中的服务。

$ sudo docker-compose create webapp
$ sudo docker-compose start webapp
$ sudo docker-compose stop webapp

https://gitbook.cn/books/5fb91715f25ffc2d3e3d2983/index.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值