[DevOps] Docker三剑客
Docker 三剑客介绍
为了把容器化技术的优点发挥得更好,docker 公司先后推出了三大技术:
- docker-machine
- docker-compose
- docker-swarm
使用"三剑客"可以帮助我们解决 docker host 维护,多容器编排部署,多个 docker host 集群的各个难题。
Docker machine
docker 使用了 linux 的内核技术(namespace,cgroup 等),那么如果我想在 windows 或 Mac 系统上运行 docker 怎么办呢?
答案是借助虚拟机来实现,也就是说我在 windows 或 Mac 上运行一个 linux 虚拟机,再在虚拟机里运行 docker。
docker-machine 就是 docker 公司官方提出的,用于在各种平台上快速创建具有 docker 服务的虚拟机的技术.
参考: https://docs.docker.com/machine/
Docker compose
用容器运行一个服务,需要使用 docker run 命令。但如果我要运行多个服务呢? 假设我要运行一个 web 服务,还要运行一个 db 服务,那么是用一个容器运行,还是用多个容器运行呢?
一个容器运行多个服务会造成镜像的复杂度提高,docker 倾向于一个容器运行一个应用。
那么复杂的架构就会需要很多的容器,并且需要它们之间有关联(容器之间的依赖和连接)就更复杂了。
这个复杂的问题需要解决,这就涉及到了容器编排
的问题了。
docker-compose 就是可以做容器编排的小工具,它可以在一个文件中定义多个容器,只用一行命令就可以让一切就绪并运行。
docker-compose 安装
方法 1: 使用 pip 安装
# yum install epel-release -y
# yum install python2-pip -y
# pip2.7 install docker-compose
卸载方法:
# pip uninstall docker-compose
方法 2: 直接下载
# curl -L
"https://github.com/docker/compose/releases/download/1.24.
1/docker-compose-$(uname -s)-$(uname -m)" -o
/usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
卸载方法:
# rm /usr/local/bin/docker-compose
安装完后验证
# docker-compose -v
docker-compose version 1.24.1, build 4667896
使用 docker-compose 的三个步骤
Docker Compose 将所管理的容器分为三层
- 工程(project)
- 服务(service)
- 容器(contaienr)
Docker Compose 运行的目录下的所有文件(docker-compose.yml,extends 文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。
一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。
一个服务当中可包括多个容器实例
使用 Compose 基本上分为三步:
- Dockerfile 定义应用的运行环境(镜像)
- docker-compose.yml 定义组成应用的各服务
- docker-compose up 构建并启动整个应用
docker compose 常见语法
docker compose 使用.yml 或.yaml 后缀
参考: https://docs.docker.com/compose/compose-file/
build
指定镜像构建时的 dockerfile 目录,格式一般为绝对路径目录或相对路径目录(dockerfile 需要命名为 Dockerfile)
build: /path/to/build/dir
或者
build: ./dir
image
指定要启动容器的镜像
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
如果镜像不存在,compose 尝试拉它
如果指定了构建, 可以使用指定的选项构建它,并使用指定的 tag 进行标记
environment
设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置
environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像容器中
environment:
RACK_ENV: development
SHOW: 'true'
或
environment:
- RACK_ENV=development
- SHOW=true
expose
这个标签与 Dockerfile 中的 EXPOSE 指令一样,用于指定暴露的端口,但只将端口暴露给连接的服务,而不暴露给主机.
expose:
- "3000"
- "8000"
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"
restart
指定 Docker 容器的重启策略
默认值为 no ,即在任何情况下都不会重新启动容器
当值为 always 时,容器退出时总是重新启动;
当值为 on-failure 时,当出现 on-failure 报错(非正常退出,退出状态非 0),才会重启容器
当值为 unless-stopped 时, 在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器
restart: "no"
restart: always
restart: on-failure
restart: on-failure:3
restart: unless-stopped
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
depends_on
此标签解决了容器的依赖、启动先后的问题
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
使用 docker-compose up web 启动,会先启动 redis 和 db,再启动 web
links
链接到其它服务的中的容器, 与 link 连接一样效果,会连接到其它服务中的容器
web:
links:
- db
- db:database
- redis
docker-compose 基础应用案例一
参考: https://docs.docker.com/compose/gettingstarted/
案例 1: wordpress 应用
1, 创建一个名为 wordpress 的 project(工程)
[root@daniel ~]# mkdir -p /doker-compose/wordpress
[root@daniel ~]# cd /doker-compose/wordpress
2, 创建 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
说明:
这个应用定义了两个容器服务:db, wordpress
db 容器通过 mysql:5.7 镜像启动
- MySQL 的数据目录挂载到当前目录./data,此目录不存在会自动创建
- 容器重启策略为 always
- 设置了连接 mysql 的 4 个变量
wordpress 容器通过 wordpress:latest 启动
- 需要 db 容器先启动再启动 wordpress 容器
- wordpress 容器要 link 连接 db 容器
- wordpress 容器将 80 端口映射到宿主机的 8010 端口
- 容器重启策略为 always
- 设置连接数据库的变量
3, 启动
[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
4, 访问
访问容器主机的 8010 端口
5, 不用了可以关闭并删除
[root@daniel wordpress]# docker-compose stop
Stopping wordpress_wordpress_1 ... done
Stopping wordpress_db_1 ... done
[root@daniel wordpress]# docker-compose rm
Going to remove wordpress_wordpress_1, wordpress_db_1
Are you sure? [yN] y 输
入y确认删除容器
Removing wordpress_wordpress_1 ... done
Removing wordpress_db_1 ... done
案例 2: haproxy 应用
1, 创建一个工程目录 haproxy
[root@daniel ~]# mkdir -p /docker-compose/haproxy
[root@daniel haproxy]# cd /docker-compose/haproxy
2, 准备 haproxy.cfg 配置文件
[root@daniel haproxy]# vim haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
stats uri /status
frontend balancer
bind 0.0.0.0:80
mode http
default_backend web_backends
backend web_backends
mode http
option forwardfor
balance roundrobin
server web1 web1:80 check
server web2 web2:80 check
server web3 web3:80 check
option httpchk GET /
http-check expect status 200
3, 创建编排脚本
[root@vm1 haproxy]# vim docker-compose.yml
web1:
image: httpd:latest
volumes:
- ./httpd1:/usr/local/apache2/htdocs/
expose:
- 80
web2:
image: httpd:latest
volumes:
- ./httpd2:/usr/local/apache2/htdocs/
expose:
- 80
web3:
image: httpd:latest
volumes:
- ./httpd3:/usr/local/apache2/htdocs/
expose:
- 80
haproxy:
image: haproxy:latest
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- web1
- web2
- web3
ports:
- "80:80"
expose:
- "80"
4, 启动应用
[root@daniel haproxy]# docker-compose up -d
5, 在挂载目录建立不同的主页用于测试
[root@daniel haproxy]# echo web1 > httpd1/index.html
[root@daniel haproxy]# echo web2 > httpd2/index.html
[root@daniel haproxy]# echo web3 > httpd3/index.html
6, 访问 http:// docker 宿主机 IP :80 验证是否负载均衡调度
访问 http:// docker 宿主机 IP :80/status 验证是否有状态页面