欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Docker:集群 有大用

Docker Swarm 是创建服务器集群用的工具。

封面摄影:Martin Worsøe Jensen

来自  https://ninghao.net/course/3870


介绍

1)docker swarm

docker swarm 是创建集群服务器用的工具 .. 只需要几个命令就可以创建一个服务器集群,它内置了一些集群需要的工具,比如服务查找,网络,负载平衡 ...

先初始化一个集群,然后让服务器都加入到这个集群里面,这样我们就可以在这个服务器集群上运行服务了,一个服务可以用一个或者多个容器来支持,这些容器之间使用 overlay 类型的网络可以相互沟通 ... 每个服务器节点都知道集群里的其它的服务器 ...

如果有服务器出了问题,Docker 会把在有问题的服务器上运行的容器转移到集群里的其它的服务器上。 我们不再需要配置服务器之间,还有容器之间的负载均衡,它现在是 docker swarm 内置的功能。

来自  https://ninghao.net/video/3872#info


集群

2)创建集群 - swarm init

在本地我创建了三台 linux 系统的虚拟机,可以用它们来模拟远程的服务器 ...

先 ssh 到一台服务器 ... 我这里就是在本地创建的一台虚拟机 .. 名字是 node1 ... 进来以后,可以先去初始化一个 Swarm ,也就是 Docker 里的服务器集群 ... 执行一下 docker swarm init 再用一个 --listen-addr 设置一下监听的地址跟端口号 ... 192.168.33.11 .. 它是 node1 这台服务器的 ip 地址 .. 端口号是 2377 ...

docker swarm init --listen-addr 192.168.33.11:2377

docker swarm init 192.168.33.11:2377

执行一下 ... 会提示 Swarm initialized ... current node is now a manager ... 集群已经初始化了 ... 当前这个节点服务器是一个管理员 ...

也就是我们可以在这台服务器上去分配任务 ... 再查看一下集群里的服务器的列表 ... 

docker node ls

 ... 现在我们的集群里只有一台服务器 ... 就是这个 node1 ... 它是一个 Leader ... 也就是服务器集群里面的领头的 ...

https://docs.docker.com/engine/reference/commandline/swarm_init/

来自  https://ninghao.net/video/3874#toc


3)添加服务器到集群里 - swarm join


登录到想要加入到集群的服务器 ... 比如 node2 ... 它也是我在本地创建的一台虚拟机 ... 进入以后执行一下 docker swarm join .. 同样可以使用一个 --listen-addr .. 设置一下监听的地址还有端口号 .. 这个地址就是本机的 ip 地址 ... 192.168.33.12 ... 端口号是 2377 ...

然后再设置一下这台服务器要加入的集群里的管理员 ... 我们在 node1 上初始化了一个集群,默认它就会是这个集群里的管理员 .. 它的地址是 192.168.33.11 ... 端口号是 2377 ...

 docker swarm join --listen-addr 192.168.33.12:2377  192.168.33.11:2377

This node joined a Swarm as a worker

再登录到另一台服务器 ... 名字是 node3 ... 同样再用一下 docker swarm join ,把这台服务器也加入到我们的集群里... 这台服务器的 ip 地址是 192.168.33.13 ...

docker swarm join --listen-addr 192.168.33.13:2377  192.168.33.11:2377

回到集群的管理员这台服务器 .. 查看一下集群里的服务器列表 ...

 docker node ls 

...

现在这个集群里面一共有三个服务器 .. node1 ,它是集群里的 manager .. 管理员 ... node2 还有 node3 是集群里的 worker ... 工人 ..

它们现在的状态都是 Ready,表示准备好了 ... AVAILABILITY, 是否可用,都是 Active .. 表示它们都可以使用 ...

 来自  https://ninghao.net/video/3875#info



4)创建集群网络 - overlay

在集群服务器上运行的容器需要使用一种 overlay 类型的网络 ... 我们可以先去创建一个 overlay 类型的网络,然后在创建服务的时候可以让容器使用这个网络 ...

docker network create ,创建一个网络 ... --driver 是 overlay ... 网络的名字我们可以随便起一个,比如 skynet ...

docker network create --driver overlay skynet

完成以后,再检查一下网络的列表 ... 

docker network ls

 ... 在这里会有一个名字是 skynet ,类型是 overlay 的网络 ... 这样在我们的集群里就可以使用它了 ...

来自  https://ninghao.net/video/3876#info



5)Swarm 状态的图形界面

为了更好的演示与理解集群,可以创建一个 visualizer ,在上面可以实时的观察集群里的服务器的状态,还有在这些服务器上运行的容器 ...

登录到集群的 Manager ... 去运行一个容器 ... 添加几个参数 ... 再发布一个端口号 ... 5000 对应容器的 5000 .. 设置一个 HOST 环境变量 ... 它的值可以是这台服务器的 IP 地址 ... 再设置一下 PORT 环境变量 ... 值是 5000 ... 再挂载一个文件 ... 位置是 /var/run/docker.sock ... 放到容器的 /var/run/docker.sock ...

再指定一下要使用的镜像 ... manomarks/visuallizer .. 

docker run -itd -p 5000:5000 -e HOST=192.168.33.11

-e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock manomarks/visualizer 


执行一下 ... 这可能需要等一段时间 .. 因为需要先去下载容器需要的这个镜像 ...

完成以后,打开浏览器 ... 访问一下 192.168.33.11:5000 ...

在这个页面上,你可以观察到集群的一些情况,现在这个集群上有三台服务器 .. node1 ,node2 ,还有 node3 。都是正在运行的状态 ...

一会儿我们会在集群里创建服务 ... 在这里会显示服务相关的容器是在哪台服务器上运行的 ... 你也可以实时的观察到运行的容器的变化 ...

docker run -it-d -p 5000:5000 -e HOST=192.168.33.11 -e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock manomarks/visualizer

来自  https://ninghao.net/video/3877#info


服务

6)创建服务 - service create

我们已经有了一个集群服务器,现在就可以在这个集群上去运行服务了 .. 在集群的管理员上面 ... 执行一下 docker service create ,去创建一个服务 .. 服务的名字是 web ... --network 使用的网络是之前我们自己创建的 skynet 这个 overlay 类型的网络 ... --publish 发布的端口是 3000:3000 ...

再设置一下需要的数量 ... 用一个 --replicas ... 先把它设置成 1 ... 然后是镜像的名字,这里用我自己构建的一个镜像,名字是 ninghao/node ... 它里面是一个用 node.js 创建的小应用 ...

docker service create --name web --network skynet --publish 3000:3000 --replicas 1 ninghao/node

查看一下服务的列表 ...

 docker service ls

 ... 这里会出现刚才我们创建的 web 这个服务 ..

容器的数量是 1 ... 前面还有一个 0 ,表示这个容器还没有启动 ...

再查看一下创建 web 服务的任务 ... sudo docker service tasks web ...

docker service tasks web

注意 LAST STATE 这栏的内容 ... 显示正在准备 ... 因为我们创建的服务里指定要使用的镜像在服务器上不存在,所以 Docker 会先去下载镜像 ... 需要等一段时间 ... DESIRED 是 running ...

最后这个 NODE 表示的是这个容器运行在哪个服务器上 .. 这里显示的是 node1 ...

我们可以在创建的这个 Visualizer 上面观察到集群的变化 ... 稍等几分钟 ... 你会发现,在 node1 这台服务器上已经有一个服务正在运行了 ...

回到终端 ... 再查看一下创建 web 服务的任务 ... 

docker service tasks web

现在它的 LAST STATE 是 Running .. 表示已经运行了一段时间了 ...

打开浏览器 ... 访问一下 http://192.168.33.11:3000 ... 会显示一个页面 ... 它是用 nodejs 创建的一个应用 ... 上面显示一个 hello .. 下面还会显示运行这个应用的容器的 ID 号 ...

来自 https://ninghao.net/video/3879#info


7)负载均衡 - load balancing

现在我们的集群里创建了一个名字是 web 的服务,这个服务只用了一个容器 ... 在这里你可以看到这个容器是在 node1 这台服务器上 ...

我们可以直接访问一下为 node1 这个服务器指定的主机名 ... node1:3000 ... 显示的就是应用的页面 ...

新建一个浏览器标签 ... 再访问一下 node2 这台服务器 .. 端口仍然是 3000 ... 你会发现,同样可以正常打开应用的页面 .. 虽然在 node2 上并没有容器运行我们的应用 ...

注意页面上显示的容器的 id 号是一样的 ... 也就是这两个页面是同一个容器提供的服务 ...

再访问一下 node3 ... 同样可以打开 ... 这就是 Docker 的 Routing Mesh 技术 ... 它内置了负载均衡的功能 ...

在集群里的每台服务器,都会知道在集群上运行的所有的服务,这些服务都在哪些服务器上 ... 如果访问的服务器上没有指定的容器 ... docker 会把访问的请求重定向到有这个容器的服务器上 ...

来自  https://ninghao.net/video/3880#info


8)扩展服务 - service scale

下面我们再去 scale up 一下 web 这个服务 ... 现在这个服务只有一台容器 ... 在集群的 manager 服务器上,执行一下 docker service scale ... 然后是服务的名字 ... 这里就是 web ... 等号的右边是需要的数量 ... 比如我想用 6 个容器运行这个 web 服务 ...

docker service scale web=6

执行一下 ... 回到这个 Visualizer 观察一下 ... 你会发现 node1 这台服务器上会立即出现一个容器 ... 现在它上面有两个容器 ...

剩下的容器应在 node2 还有 node 3 上面去创建 ... 因为它们上面还没有我们的应用需要的镜像 ... 要现去下载 .. 所以需要等一段时间 ...

过一阵子以后 ... 在 node2 还有 node3 上也分别出现两个容器 ... 三台服务器上的容器加起来正好是六个 ...

再查看一下运行 web 服务的这个任务 ... 

# docker service tasks web

 ... 这里也会显示一共有六个服务 ... 名字就是从 web.1 到 web.6 ..

再回到浏览器 .. 访问一下 node1:3000 ... 注意上面显示的容器的 ID 号 .. 刷新一下 ... 这个容器 ID 号会有变化 .. 也就是现在我们的应用会同时使用多个容器提供服务 ...

我们可以再打开一个浏览器 ... 同样访问一下 node1:3000 ... 看一下这个页面的容器的 ID 号 ... 跟之前是不一样的 ...

这就是 Docker 的负载均衡功能起作用了 ... 我们的 web 服务会由来自不同的服务器上的不同的容器一块儿向用户提供服务 ...

scale 可以 up 也可以 down ... 比如我想让 web 这个服务由 3 个容器提供支持 .. 

# docker service scale web=3

现在每台服务器都运行了一个容器 ... 加起来一共是三个 ... 这是我们期望的 web 服务的状态 ... docker 会维护这个服务的状态 ...

# exit ( 这是有node1上退出)

下面我们去关掉 node3 这个服务器 ...

# vagrant halt node3 (此时在物理机上)

你会看到 node3 已经关掉了 ... 它上面的那个容器也不见了

image.png


 ... 再等一下 ... web 服务少的那个容器,会出现在集群里的其它的服务器上 ... 这里它会跑到 node2 这个服务器上 ...

image.png

因为 docker 会维护我们想要的服务的状态 ... 再到终端上验证一下 ... 在集群的 manager 上面 .. 

# docker service tasks web

查看一下 web 这个服务 ...

会显示这个服务的两个容器是在 node2 这台服务器的上面 ...

image.png

来自 https://ninghao.net/video/3881#toc


9)更新服务 - service update

先把 web 这个服务 scale up 到 6 个容器

docker service scale web=6


 ... 完成以后查看一下应用的页面 ... 

image.png

页面上现在显示的是 hello ... 使用 service update 可以更新服务相关的东西 ... 比如端口,网络,挂载的数据卷等等 ...

比如现在我想更新一下服务使用的镜像 ... 

docker service update -help (这是帮助命令)

image.png

先查看一下帮助 ... 更新镜像需要用到这个 image 选项 ... 先指定一下要更新的服务 .. 这里就是 web ... 后面再添加一个 --image .. 把镜像换成 ninghao/node:hola ... hola 是镜像的标签 ... 在找构建镜像的时候,你可以为镜像打上一些标签 ... 可以用它们来表示应用的不同的版本 ...

docker service update web --image ninghao/node:hola

执行一下 ... 你会看到集群上的跟 web 服务相关的容器会一起被关掉 ... 

image.png

然后 docker 会使用我们新指定的镜像重新为 web 服务创建容器 ...

image.png


新容器创建以后 .. 我们可以再去预览一下应用 ...

刷新一下页面 ... 之前的 hello ... 会变成 hola ... 也就是现在集群上运行的是我们的另一个版本的应用 ...

这个更新的动作我们也可以一点一点的来 ... 比如我想一次更新两个容器 ... 每次更新中间停几秒 .. 再用一下 docker service update web --image 这回我们再把镜像换成原来的 ninghao/node ...

再添加一个 --update-parallelism .. 指定一下每次更新的数量 .. 再用一个 --update-delay ... 指定一下每次更新间隔的时间 ...

docker service update web --image ninghao/node --update-parallelism 2 --update-delay 6s

执行一下 ... 你会看到,会先去更新两个容器 ... 重新给我们再生成两个 .. 中间隔上几秒钟 ... 又会去更新两个容器 ... 再等一会儿 ... 会更新剩下的两个容器 ..

都完成以后,我们再访问一下应用的页面 ... 应用显示的页面,又会恢复成了在 ninghao/node 这个镜像里的版本 ...

来自  https://ninghao.net/video/3882#info











普通分类: