1. 概述
问题:如果要使用 Docker 运行 LNMP 架构,那么 Nginx 、MySQL 、PHP 、 Linux 三个服务运行在一个容器里,还是运行在多个容器里呢?
答案是都可以。
- 你可以分别放在三个容器中
- 也可以全部放在一个容器中
- 还可以
PHP 、 Linux 、Nginx 共用一个容器,MySQL 单独一个容器 - 甚至还可以分别做多个容器,实现更复杂的架构
如果实现一个容器架构(微服务架构),一个个的 docker run 启动很麻烦,更麻烦的是容器之间的连接与交互。所以我们需要用到容器编排。
2. 使用步骤
Docker Compose 将所管理的容器分为三层:
- 工程(project)
- 服务(service)
- 容器(contaienr)
Docker Compose 运行的目录下的所有文件(docker-compose.yml 、extends 文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。
一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、关系,一个服务当中可包括多个容器实例。
使用 Compose 基本上分为三步:
- Dockerfile 定义应用的运行环境(镜像)
- docker-compose.yml 定义组成应用的各服务
- docker-compose up -d 构建并启动整个应用
?
3. 安装
curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
4. 常见语法
Docker Compose 使用 Yaml 格式文件来编排。
参考: https://docs.docker.com/compose/compose-file/
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
设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置。
environment 和 Dockerfile 中的 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"
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:
- /var/lib/mysql
- /opt/data:/var/lib/mysql
- ./cache:/tmp/cache
- ~/configs:/etc/configs/:ro
- datavolume:/var/lib/mysqlvolumes:
- /var/lib/mysql
- /opt/data:/var/lib/mysql
- ./cache:/tmp/cache
- ~/configs:/etc/configs/:ro
- datavolume:/var/lib/mysql
4.8 depends_on
此标签解决了容器的依赖、启动先后的问题。
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
使用 docker-compose up web 启动,会先启动 Redis 和 DB ,再启动 Web 。
4.9 links
链接到其它服务的中的容器,与 link 连接一样效果,会连接到其它服务中的容器。
web:
links:
- db
- db:database
- redis
5. 综合案例:容器化应用部署实践
5.1 环境配置
在宿主机上打开 ip_forward ,为我们下面要映射容器的端口到宿主机,只有打开 ip_forward 才能映射成功。
net.ipv4.ip_forward=1
5.2 部署 WordPress 应用
- 创建一个名为 wordpress 的 project(工程):
[root@daniel ~]
[root@daniel ~]
- 创建 docker-compose.yml:
[root@daniel wordpress]
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
说明:这个应用定义了两个容器服务:db 、wordpress 。
db 容器通 mysql:5.7 镜像启动:
MySQL 的数据目录挂载到当前目录 ./data ,此目录不存在会自动创建- 容器重启策略为
always - 设置了连接
MySQ L 的 4 个变量
wordpress 容器通过 wordpress:latest 启动:
- 需要
db 容器先启动再启动 wordpress 容器 wordpress 容器要 link 连接 db 容器wordpress 容器将 80 端口映射到宿主机的 8010 端口- 容器重启策略为
always - 设置连接数据库的变量
- 启动:
[root@daniel wordpress]
如果本地没有镜像,下载的两个镜像比较大。
[root@daniel wordpress]
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 e9c354083de7 3 days ago 373MB
wordpress latest 4ba1e63bd20c 8 days ago 501MB
- 安装与访问
在浏览器端,访问容器主机的 8010 端口,安装访问,最终效果如下:
https://gitbook.cn/books/5fb91715f25ffc2d3e3d2983/index.html
|