Docker容器编排
案例——Docker容器编排
一、案例目标
(1)了解Docker容器主流的编排技术。
(2)掌握Docker Swarm的部署和基本使用。
(3)掌握Docker Compose的部署和基本使用。
二、案例分析
1.规划节点
主机名 |
节点 |
master |
swarm集群manage节点 |
node |
swarm集群node节点 |
compose |
compose节点 |
- 基础准备
所有节点已安装好docker-ce。
三、案例实施
1. Docker Swarm的部署和基本使用
(1)配置主机映射
登录master和node节点,配置主机映射。
(2)配置Docker API
master节点和node节点均需开启Docker API。
[root@master ~]# vi /lib/systemd/system/docker.service
将ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
修改为ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker
(3)拉取Swarm镜像
所有节点拉取Swarm镜像。
在master节点创建Swarm集群。
初始化命令中“--advertise-addr”选项表示管理节点公布它的IP是多少。其它节点必须能通过这个IP找到管理节点。输出结果中包含了加入swarm集群的命令,通过“--token”选项来判断加入集群时,是作为管理节点还是工作节点。
(5)Node节点加入集群
在node节点执行加入Swarm集群的命令,如果加入不了,尝试先清空iptables和关闭master节点防火墙。
(6)验证集群
登录master节点,查看各节点状态。
(7)安装Portainer
Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型企业对容器管理的全部需求。
登录master节点,安装Portainer。
(8)登录Portainer
打开浏览器,输入http://192.168.50.19:9000访问Portainer主页
首次登录时需设置用户名和密码,输入设置的用户名和密码
(9)运行service
部署 service 的命令形式与运行容器的 docker run 很相似
--name为service命名,nginx为镜像的名字,--replicas参数指定此服务在工作节点上运行的任务数。
通过docker service ls命令,可以查看当前Swarm中的service。
REPLICAS显示当前副本信息,2/2的意思是web这个service期望的容器副本数量为2,目前已经启动的副本数量为2,也即当前service已经部署完成。命令docker service ps可以查看service每个副本的状态。
可以看到service两个副本分别被分派到master和node节点,当前的状态是Running。
(10)service伸缩
之前部署了只有两个副本的service,不过对于Web服务,通常会运行多个实例。这样可以负载均衡,同时也能提供高可用。
Swarm要实现这个目标非常简单,执行命令“docker service scale 服务名=副本数量”就可以增加service的副本数。在master上执行如下命令。
副本数增加到5,通过docker service ls和docker service ps命令查看副本的详细信息。
5个副本已经分布在Swarm的各个节点上。
(11)调度节点
默认配置下master也是worker node,所以master上也运行了副本。如果不希望在master上运行service,可以执行如下命令。
Drain表示master已经不负责运行service,之前master运行的那2个副本会如何处理呢?使用docker service ps查看一下。
master上的副本web.1和web.3已经被Shutdown了,为了达到5个副本数的目标,在node上添加了新的副本web.1和web.3。
(12)访问service
前面已经学习了如何部署service。不过到目前为止,有一个重要问题还没有涉及:如何访问service?要访问Nginx服务,首先要保证网络是联通的,其次服务的IP也需要知道。这些信息目前都没有掌握,但每个副本都是一个运行的容器,可以先查看容器的网络配置。
在node节点上运行了5个容器,是Web的副本,容器监听了80端口,但并没有映射到Docker Host。服务并没有暴露给外部网络,只能在Docker主机上访问。换句话说,当前配置下,无法访问service web。
要将service暴露到外部,方法其实很简单,执行下面的命令即可。
如果是新建service,可以直接用使用--publish参数,比如:
[root@master ~]# docker service create --name web_server --publish 8080:80 --replicas=2 httpd
容器在80端口上监听HTTP请求,--publish-add8080:80将容器的80映射到主机的8080端口,这样外部网络就能访问到service了
要关闭 节点node 的防火墙
为什么curl集群中任何一个节点的8080端口,都能够访问到web?这实际上就是使用Swarm的好处了,这个功能叫做routing mesh。routing mesh将外部请求路由到不同主机的容器,从而实现了外部网络对service的访问
所以,无论访问哪个节点,即使该节点上没有运行service的副本,最终都能访问到service。
2. Docker-Compose的部署和基本使用
(1)安装Docker-Compose
下载Docker-Compose,此处选择1.25.0-rc2版本。可以从网络下载,也可以从提供的光盘包里上传后使用。
[root@compose ~]# curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
赋予可执行权限,创建项目目录
(3)定义app.py文件
在项目路径下创建app.py文件,并将以下内容写入文件。
在这个例子中,Redis就是应用网络中Redis容器的主机名。端口使用的Redis默认端口6379。
(4)定义requirements.txt文件
在项目路径下创建requirements.txt文件,并将以下内容写入文件。
(5)定义Dockerfile
在这一步中,需要编写一个Dockerfile来构建一个Docker镜像。这个镜像包含Python应用的所有依赖,也包含Python其本身。
在项目路径下创建一个Dockerfile文件,并将以下内容写入文件。
本Dockerfile主要完成以下工作:
① 构建一个基于Python 3.4的镜像。
② 把当前目录添加到镜像中的/code路径下。
③ 把工作路径设置成/code。
④ 安装Python依赖。
⑤ 设置容器的默认命令为python app.py。
(6)定义服务
在工作路径下创建一个docker-compose.yml文件并写入以下内容。
这个Compose文件中定义了两个服务Web与Redis。
Web服务使用当前目录Dockerfile构建出来的镜像,并且将容器上暴露的5000端口转发到主机的5000端口,使用Flask Web服务器的默认端口5000。
Redis服务使用从Docker Hub注册表中拉取的公有镜像。
(7)运行服务
在项目路径下通过docker-compose up命令启动应用。
重新打开shell窗口,查看。
Compose拉取一个Redis镜像,以案例代码构建一个镜像,并启动定义的服务。在这种情况下,代码在构建镜像时被静态拷贝到镜像中。
(8)验证服务
输入docker image ls命令,列举所有本地镜像,镜像列表中将返回Reidis与Web。
(9)停止服务
可以在项目路径下使用docker-compose down命令停止服务,也可以在终端上按Ctrl+C键停止当前启动着的应用。
[root@compose composetest]# docker-compose down
(10)更新服务文件
在项目路径下编辑docker-compose.yml为Web服务添加一个绑定挂载。
新的volumes键将当前路径(项目路径)与容器中的/code路径挂载到一起,允许用户及时修改代码而不用重新构建镜像。
(11)重建服务
在项目路径下,使用docker-compose up命令启动服务,使用更新后的Compose文件构建应用并启动。
[root@compose composetest]# docker-compose up
重新打开另一个shell窗口测试下面命令。
(12)更新服务
因为应用程序的代码通过volume挂载到容器中,你可以更改其代码并立即查看更改,而不必重新生成镜像。
修改app.py中的欢迎语并保存。例如,将Hello World!改成Hello from Docker!:
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
重开窗口之后进行测试输出,查询输出的内容已经更新。