部署docker1.12 Swarm
实验环境:
这里选择三台主机运行Swarm,依次为:
node1192.168.1.104
node2192.168.1.105
node3192.168.1.113
基本环境配置
3台主机确保时间一致ntp
3台主机均关闭selinux,开启路由转发。
3台主机根据上面的实验环境描述修改主机名和ip地址
系统环境准备
准备系统环境, 配置host列表
3台主机均修改/etc/hosts/etc/hosts /etc/hosts /etc/hosts/etc/hosts/etc/hosts/etc/hosts文件,添加所有主机的 ip地址和主机名的映射记录
以 node node 1 为例子为例子 :
开启宿主机之间的端口
TCP端口2377集群管理端口
TCP与UDP端口7946节点之间通讯端口
TCP与UDP端口4789overlay网络通讯端口
配置所有节点密钥登录.
配置所下节点密钥互信, 在node1可以免密码登录各节点,只在node1上执行:
生成 sshkey
在node1发布sshkey到各个节点
测试密钥登录
安装 docker package
yum -y install docker-engine
启动 docker
检查docker版本
创建Swarm集群
在node1上初始化swram集群:
注意你只需要在一个node1上初始化swarm集群, 其他node加入这个集群就行了, 所以以下命令只需要在node1上运行.
解释:根据如上命令的提示:我们的其他节点服务器,以worker角色加入swarm集群需要登录到服务器运行如下命令:
advertise-addr参数,后面跟你swarm集群的通讯地址, 也就是node1的地址.
查看端口号监听情况
检查node1 docker swarm mode信息:
#docker info
显示信息如下:
查看swarm集群node列表
需要先 tag 这个镜像的名字成
需要先 tag 这个镜像的名字成
dockerserviceinspect 命令用户查看 service 详细信息
使用 docker serviceps
扩展已有的服务的副本数,这里将 web1 服务扩展到 3 个副本
Node1 节点上运行着容器 3 个容器还有一个私有仓库注册服务器容器
可以看到,我们的swarm集群中只有一个节点.现在我们把其他节点加入我们的集群中:
把其他节点加入集群中:在node1通过ssh, 在node2-node3上执行上面的加入集群命令:
注:如果你不记得上面提示的加入swarm集群的命令和密钥可以使用如下方式查看worker节点和manager节点的加入命令
再次检查集群节点列表, 我们可以看到所有的服务器都已经加入swarm集群了
不过现在集群只有一个manager节点node1, 为了swarm集群的高可用,和避免单点故障. 我们希望建立多个manager节点集群.
只需要通过如下命令, 提升worker节点成manager节点:
[root@node1 ~]# docker node promote node2
查看node2的docker info
现在我们可以看到, 已经有2个manager节点了, 一个Leader节点, 一个Reachable节点. 现
在你也可以在 node2 上面管理整个 swarm 集群.
我们的 swarm 集群就搭建完毕了. 超级简单
习惯使用 docker 命令帮助:docker
总结:
dockerswarm:集群管理,子命令主要有下面几个。
dockerswarm init 命令用于初始化一个集群
dockerswarmjoin 命令用于加入一个现有集群
dockerswarmleave 命令由于离开集群
附:node 下线
有些时候需要维护一个节点,此时此节点可能会网络断开或者需要关机,造成节点上服务不
可用。使用 docker node update --availability drain
状态即可,命令如下:docker node update --availability active
有了 Docker Swarm 集群我们如何把我们的应用跑在 Swarm 集群上呢?
很简单, 基本上原来我们使用 docker run 的命令创建容器, 把前面替换成 docker service
create 就行了.建议搭建一个 registry,为所的 docker 主机提供镜像下载,否则你需要在每个 docker 主机本地存在容器镜像。所以搭建一个私有仓库,由私有仓库提供所需要的镜像,
本实验环境中用 node1 同时作为 registry。拉取本地私有仓库 registry,查看 registry 镜像
开启路由转发
vi /etc/sysctl.cof
添加 net.ipv4.ip_forward=1
执行 sysctl -p 使修改生效
#docker pull registry:2
#docker images
上传一个本地镜像,然后使用命令导入images中
docker load --input registry.tar
附:registry1 是 python 语言写的,而现在 registry2 版本即 docker distribution 更加安全和快
速,并且是用 go 语言写的。
基于私有仓库镜像运行容器
默认情况下,registry2 会将仓库存放于容器的/var/lib/registry 目录下,这样如果容器被删除,
则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器的
/var/lib/registry下,两个目录下都有!
·registry 的默认存储路径是/var/lib/registry,只是个临时目录,一段时间之后就会消失
·所以使用-v 参数,指定个本地持久的路径,
返回{"repositories":[]} 说明 registry 服务工作正常.
注:镜像信息存放在/var/lib/registry 目录下,因此这里将宿主机目录映射到/var/lib/registry
所有主机都指向 registry 服务器:
停止 docker 服务
#systemctlstop docker
修改/usr/lib/systemd/system/docker.service,修改后保存退出
然后把配置好的文件,拷贝到node2/node3一份
重载 docker 服务并启动 docker 服务
#systemctldaemon-reload
#systemctlstartdocker
测试本地镜像仓库
有了本地镜像仓库 registry, 现在我们推送一个测试镜像到本机镜像仓库, 测试下 registry 服务.
测试:在 node2 主机上推送镜像到 registry
如果想把镜像推送到本地 registry.
需要先 tag 这个镜像的名字成
将 tag 后的镜像上传到 registry.
push 成功后, 可以调用 registry API 查看 registry 中的镜像
在 node3 主机测试从 registry 下载镜像
overlay 网络
解决了镜像构建问题, 为了让应用跑在 swram集群 上,我们还需要解决容器间的网络访问问题.
单台服务器的时候我们应用所有的容器都跑在一台主机上, 所以容器之间的网络是互通的.
现在我们的集群有 3 台主机, 所以 docker 应用的服务会分布在这 3 台主机上.
如何保证不同主机上的容器网络互通呢?
swarm 集群 已经帮我们解决了这个问题了,就是只用 overlay network .
在 docker 1.12 以前, swarm 集群需要一个额外的 key-value 存储(consul, etcd). 来同步
网络配置, 保证所有容器在同一个网段中.
在 docker 1.12 已经内置了这个存储, 集成了 overlay networks 的支持.
下面我们演示下如何创建一个 overlay network:
注:swarm 上默认已有一个名为 ingress 的 overlay 网络, 可以直接使用, 但本文会创建一个新的
为我们的 docker 应用创建一个名为 dockercoins 的 overlay network
查询 docker network 列表
在网络列表中你可以看到 dockercoins 网络的 SCOPE 是 swarm, 表示该网络在整个 swarm 集群生效的, 其他一些网络是 local, 表示本机网络.
你只需要在 manager 节点创建 network, swarm 集群会自动处理配置到其他的节点,这是你可以查看其他节点的 network. dockercoins 网络已经都创建了.:
注:一旦新的任务被指定给这个节点,Overlay 网络就会被按需创建。
在 swarm 集群上运行 docker 应用概念解释:serviceDocker1.12 swarm 引入了服务的概念,一个服务由多个任务组成,一个任务即一个运行的容器。服务包括两种类型:
复制服务(replicated services):类似 k8s 中复制集的概念,保持一定数量的相同任务在集
群中运行;全局服务(global services):类似 k8s 中 daemon 的概念,每个工作节点上运行一个。发布服务:在 manager 上执行如下命令:下面我们可以使用之前 push 到本地镜像仓库的镜像启动服务, 以 centos:http 为例:
以复制服务类型运行服务
在 manager 上执行如下命令:
dockerservice create 命令创建一个 service.
--name 标签命名 service 为 web1.
--replicas标签来声明 1 个运行实体(即容器副本数)
注意, 我们启动的镜像名字 192.168.1.104:5000/centos:http 使用我们本地镜像仓库的镜像名称, 这样当主机上没有这个镜像时, 会自动到本地镜像仓库拉取镜像.
使用 docker service ls 查看服务
dockerserviceinspect 命令用户查看 service 详细信息
使用 docker serviceps
现在你可以用浏览器访问 http://192.168.1.104:8000 就能访问测试页
事实上, 你可以访问swarm集群中的所有节点 192.168.1.105、192.168.1.113的8000端口, 都
可以访问测试页。(注:将 firewall 防火墙默认区域设置为 trusted)
在 manager 上执行如下命令:
--replicas标签来声明 2 个运行实体
查看服务:
从上图可以看到 web2 名称的 service 有 2 个副本分别运行在 node2 和 node3 节点上。
以全局服务类型运行服务
从下图可以看到服务 web4 在每个节点上都运行一个
下面我们扩展旧的服务,从下图可以看到 web1 service 目前只有一个副本
扩展已有的服务的副本数,这里将 web1 服务扩展到 3 个副本
缩减已有的服务的副本数,这里将 web1 服务缩减到 2 个副本
Swarm 节点是自组织(self-organizing)和自修复(self-healing)的,什么意思?只要有节
点或容器宕掉,swarm engine 就会尝试修复,下面我们来具体看一下自修复(self-healing)经过上面的操作之后,我们有以下 3 个节点:
运行着 4 个服务共 7 个任务(容器)
Node1 节点上运行着容器 3 个容器还有一个私有仓库注册服务器容器
Node2 节点上运行着容器 2 个容器
Node3 节点上运行着容器 2 个容器
现在我们让 node3 上的容器都宕掉或部分宕掉
一旦 node3 上所有容器停止,Docker 就会试图在相同的节点上启动 2 个不同 ID 的容器。
这就是 Docker Swarm Engine 的 self-healing 功能。
在 node3 节点上执行 dockerps 查看
Self-Organizing
现在我们让 node3 整个宕掉,node3 上的容器会自动在其它节点上启动。
在 manager 节点上执行 docker server ps 服务名
此上图多了一个运行任务,那就是node3的任务转移到了node1上。