前言
谈到微服务的话题,技术上我们往往会涉及到多服务、多容器的部署与管理。
Docker 有三个主要的作用:Build, Ship和Run。使用docker compose我们可以在Run的层面解决很多实际问题,如:通过创建compose(基于YUML语法)文件,在这个文件上面描述应用的架构,如使用什么镜像、数据卷、网络、绑定服务端口等等,然后再用一条命令就可以管理所有的服务(如启动、停止、重启、日志监控等等)。
1、docker-compose是什么
Compose是定义和运行多容器Docker应用程序的工具。 使用Compose,您可以使用YAML文件来配置应用程序的docker服务。 然后,使用单个命令,您可以创建并启动配置中的所有docker服务。
Compose适用于所有环境:生产,开发,测试以及CI工作流程。使用Compose基本上是一个三步过程:
- 使用Dockerfile定义应用程序的环境,以便在任何地方进行复制。
- 在docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
- 运行docker-compose并撰写开始并运行你的整个应用程序。
2、谈谈容器编排与部署
Docker有很多优势,但对于运维或开发者来说,Docker最大的有点在于它提供了一种全新的发布机制。这种发布机制,指的是我们使用Docker镜像作为统一的软件制品载体,使用Docker容器提供独立的软件运行上下文环境,使用Docker Hub提供镜像统一协作,最重要的是该机制使用Dockerfile定义容器内部行为和容器关键属性来支撑软件运行。
Dockerfile作为整个机制的核心。这是一个非常了不起的创新,因为在Dockerfile中,不但能够定义使用者在容器中需要进行的操作,而且能够定义容器中运行软件需要的配置,于是软件开发和运维终于能够在一个配置文件上达成统一。运维人员使用同一个Dockerfile能在不同的场合下“重现”与开发者环境中一模一样的运行单元(Docker容器)出来。
3、为什么要使用Compose
先来想一下我们平时是怎么样使用docker的?把它进行拆分一下:
1、docker search 镜像,是不是先查找一个镜像;
2、docker run -itd 镜像名称 ,然后在运行这个镜像;
3、然后如果你要在运行第二个镜像、第三个镜像.....等等镜像,你是不是又要docker search、docker run运行。
上面“ docker run it 镜像名称 ”这只是最小的动作, 如果你要映射硬盘,设置nat网络或者映射端口等等…你就要做更多的 docker 操作, 这显然是非常没有效率的,况且如果你要大规模部署,是不是觉得就很麻烦了。
如果将上面的操作写在docker-compose.yml里面。你只需要写好后只运行一句:docker-compose up -d就好了
4、了解下编排和部署
编排,即orchestration,它根据被部署的对象之间的耦合关系,以及被部署对象环境的依赖,制定部署流程中各个动作的执行顺序,部署过程所需要的依赖文件的存储位置和获取方式,以及如何验证部署成功。这些信息都会在编排工具中以指定的格式(比如配置文件或者特定的代码)来要求运维人员定义并保存起来,从而保证这个流程能够随时在全新的环境中可靠有序地重现出来。
部署,即deployment,它是指按照编排所指定的内容和流程 ,在目标机器上执行编排指定环境初始化,存放指定的依赖和文件,运行指定的部署动作,最终按照编排中的规则来确认联署成功。
而在Compose的世界里,编排和部署的组合结果,就是一朵“容器云”。
docker-compose.yml
Services:
- 一个service代表一个container,这个container可以通过dockerhub的image创建,或者通过本地的Dockerfile build出来的image创建出来。
- Service的启动类似docker run,我们可以给其指定network和volume,所以可以给service指定network和Volume的引用
docker-compose中YAML常用的字段:
安装docker-compose
下载最新版本安装,下载时间可能比较长
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于docker-compose:
sudo chmod +x /usr/local/bin/docker-compose
验证docker-compose是否下载成功
[root@192 ~]# docker-compose --version
docker-compose version 1.25.0, build 0a186604
docker-compose用法
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose命令
build 构建或重建服务
help 命令帮助
kill 杀掉容器
logs 显示容器的输出内容
port 打印绑定的开放端口
ps 显示容器
pull 拉取服务镜像
restart 重启服务
rm 删除停止的容器
run 运行一个一次性命令
scale 设置服务的容器数目
start 开启服务
stop 停止服务
up 创建并启动容器
更多查看帮助 docker-compose -h
一键部署lnmp平台
我们先来看下/compose_lnmp目录下的docker-compose.yml文件:
[root@ganbing compose_lnmp]# ls
docker-compose.yml mysql nginx php wwwroot
[root@ganbing compose_lnmp]# cat docker-compose.yml
version: '3'
services:
nginx:
hostname: nginx
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- 80:80
networks:
- lnmp
volumes:
- ./wwwroot:/usr/local/nginx/html
php:
hostname: php
build:
context: ./php
dockerfile: Dockerfile
networks:
- lnmp
volumes:
- ./wwwroot:/usr/local/nginx/html
mysql:
hostname: mysql
image: mysql:5.6
ports:
- 3306:3306
networks:
- lnmp
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/data:/var/lib/mysql
command: --character-set-server=utf8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: ganbing
MYSQL_PASSWORD: ganbing123
networks:
lnmp:
driver: bridge
可以看到一份标准配置文件应该包含 version、services、networks 三大部分,共有三级标签,每一级都是缩进两个空格。下面来详细说明一下里面的内容:
1、version: '3'
这是定义compose的版本号为version 3,可以参考官方文档详细了解具体有哪些版本 https://docs.docker.com/compose/compose-file/
2、services:
nginx:这是services下面的二级标签,名字用户自己定义,它将是服务运行后的名称;
hostname: nginx 这是定义容器的主机名,将写入到/etc/hostname中;
build:
context: ./nginx 指定nginx服务的上下文路径;
dockerfile:Dockerfile 指定通过上面指定路径中的Dockerilfe来构建;
ports:
- 80:80 端口映射没什么好说的;
networks:
-lnmp 指定的网络环境
volumes:把宿主机的/wwwroot目录绑定到容器中的/usr/local/nginx/html目录;
php:这个二级标签服务和下面的内容跟nginx差不多;
mysql:这个二级标签服务也和nginx、php差不多,唯一不同的是多了个images标签、还有定义了些环境变量。
image: mysql:5.6 它是通过mysql:5.6镜像来构建mysql服务器,前面nginx、php都指定了上下文通过Dockerfile来构建的。
environment:
MYSQL_ROOT_PASSWORD:定义root用户密码变量为123456;
MYSQL_DATABASE:定义了数据变量为wordpress;
MYSQL_USER:定义了普通用户变量为ganbing;
MYSQL_PASSWORD:定义了普通用户密码变量为ganbing123;
3、networks:
lnmp: 相当于执行docker network create lnmp命令了;
最后来运行docker-compose命令来启动:
[root@ganbing /]# cd compose_lnmp/
[root@ganbing compose_lnmp]# docker-compose -f docker-compose.yml up -d
来查看一下是否启动完成:
[root@ganbing compose_lnmp]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
composelnmp_mysql_1 docker-entrypoint.sh --cha ... Up 0.0.0.0:3306->3306/tcp
composelnmp_nginx_1 ./sbin/nginx -g daemon off; Up 0.0.0.0:80->80/tcp
composelnmp_php_1 ./sbin/php-fpm -c /usr/loc ... Up 9000/tcp
从上面可以看出这3个服务都是UP状态,运行 docker-compose ps必须要在有docker-compose.yml文件目录下执行才可以。
总结思考
大家想想,仅仅使用Compose,就可以构建自己的容器云吗?答案显然是否定的。docker-compose解决的问题局限在“编排”二字,甚至连“部署”范畴都涉足甚少,而在一个能够服务于大众的云平台中,编排与部署也仅仅是其中的一个组成部分而已。来一起分析一下它的局限制会有哪些:
1、docker-compse是面向单宿主机部署的,这是一种部署能力的欠缺。在更多的场合下,管理员需要面对大量物理服务器(或者虚拟机),这时如果要实现基于docker-compose的容器自动化编排与部署,管理员就得借助成熟的自动化运维工具(ansible、puppet、chef、saltstack)来负责管理多个目标主机,将docker-compose所需的所有资源(配置文件、用户代码)交给目标主机,然后在目标主机上执行docker-compose指令。
2、同样网络和存储也比较棘手,Docker不能提供跨宿主机的网络,完全面向Docker daemon的docker-compose当然也不支持。这意味着管理员必须部署一套类似于Open vSwich的独立网络工具,而且管理员还需要完成集成工作。当好不容易把容器编排都安排妥当之后,又会发现容器还处在内网环境中,于是负载均衡、服务发现等一堆问题就面临而来了,这些问题很快能消耗掉工程师所有的耐心。
那么,是否有一种能够提供完善的面向服务器集群的Docker编排和部署方案呢?Docker官方给出的答案是Compose同Machine和Swarm联动,其实还有大家近期经常听到了kubernetes(k8s)
参考
https://www.cnblogs.com/elvi/p/8424753.html
https://www.cnblogs.com/nulige/articles/10931047.html
https://docs.docker.com/compose/compose-file/