swarm集群

容器集群 swarm

容器生态包含三个部分

  • 容器核心知识 架构、镜像、容器、网络、存储
  • 容器平台技术 容器编排引擎、容器管理平台、基于容器的paas
  • 容器支持技术 多主机管理、跨主机网络方案、监控、日志管理

docker Swarm

从主机层面上来讲,docker swarm 管理的是 docker host 集群

集群化
  • 服务器集群由一组网络上相互连接的服务器组成,他们协同工作。集群能够像 单个 系统那样工作,同时提供高可用、负载均衡和并行处理
  • 如果部署应用和服务时选择的是多个独立的服务器而非集群,资源整体利用率很难到达最优。而且,应用使用资源的趋势是波动的,丧失了业务的弹性。当某个服务器宕机时,我必须手动将受影响的应用迁移到其他服务器
docker swarm mode

在docker v1.12中 docker重现实现了容器集群的编排方式。docker swarm 集成到 docker engine 。在此之前,提供集群的功能的 docker swarm 是一个独立的软件,而且依赖外部数据库。

重要概念

swarm

  • swarm运行docker engine 的多个主机组成的集群
  • 从 v1.12开始,集群管理和编排功能已经集成到 docker engine。当 docker engine 初始化了一个swarm 或者加入到一个已经存在的 swarm 时,他就启动了 searm mode
  • 运行searm mode后,docker 增加了编排service的能力
  • docker允许在同一台主机上运行swarm server,同时运行单独的容器

node

  • swarm中的每个docker engine都是一个node 有两种类型的node:managerworker
  • 在manager node上执行部署命令 manager将任务进行拆分分配给一个或多个worker node完成部署
    *manager node 负责执行编排集群管理工作,保持并维护swarm处于期望状态。swarm 上如果有多个manager node ,他们会自己协商一台个manager节点为leader执行编排任务。
  • worker node接受并处理,manager node 派发的任务。默认配置下manager node 同时也是一个worker node,不过可以配置成manager-only node 让其专门负责编排和集群管理工作
  • worker node 会定时向 manager node 报告自己的状态和正在执行的任务的状态,这样manager 就可以维护整个集群的状态

server

  • service 定义了worker node 上要执行的任务。swarm编排任务就是保证service处于期望状态下

例:
1、在swarm中运行一个httpd服务,使用httpd镜像,副本数为3;
2、manager node 负责创建这个service ,分析需要启动3个httpd容器,根据当前各个worker node的状态,然后将任务分配下去,node1 创建两个容器,node2 创建1个容器;
3、运行了一段时间后,node2突然宕机了,manager 监控到node2异常,根据各个worker node 状态,在node3上又启动了一个httpd容器
保证了service 处于期望的三个副本的状态

部署集群

1、创建swarm集群manager节点(初始化)
# docker swarm init --advertise-addr 192.168.1.90
--advertise-addr :指定与其他节点通信的地址

命令执行成功后会输出三部分信息
>swarm创建成功,此node成为manager节点
以worker身份加入此集群需要的命令(可以复制去worker node执行)
以manager身份加入此集群需要的命令

查看此集群内的节点列表
# docker node ls
docker node ls --filter role=manager
--filter 按角色进行过滤

2、在worker节点上运行加入到集群的命令(manager安装时生成)

# docker swarm join \
--token SWMTKN-1-1daezk9u1u8f1ul7xt5reneubhqkaowdmwt8bgw382517r7vn3-be37t5k6wzd9brjykdc7iaigg \
192.168.1.90:2377

Error response from daemon: rpc error: code = 14 desc = grpc: the connection is unavailable
工作节点加入集群时报错 关闭防火墙

再次查看集群的节点列表
# docker node ls

查看以worker加入此集群的命令
# docker swarm join-token worker
查看以manager加入此集群的命令
docker swarm join-token manager

运行service

1、创建名为web_service的服务
# docker service create --name web_server httpd
--name 为服务命名 使用指定镜像

# docker service ls
查看服务列表
列表中的REPLICAS列为服务的副本信息

# docker service ps
查看服务每个副本的状态 服务的镜像名、副本在那个节点上运行、运行状态、错误信息
报错信息 No such image: ubuntu:lates
记得添加国内加速器配置

实现service的伸缩

1、增加web_server服务的副本数 scale up
(依赖以创建的服务)(增加指定数量,并非增加指定数量)
# docker service scale web_server=5

通过docker service ls docker service ps web_server查看详细

让manager node 不运行容器
# docker node update --availability drain swarm1
更新设置 从有效主机里移除 swarm1

# docker node ls
再次查看 AVAILABILITY列swarm1节点已经从Active状态到Drain状态

# docker service ps web_server
再次查看服务的状态 swarm1 节点上的副本已经被shutdown了,并且已经在其他节点生成了副本

2、减少副本数 scale down
# docker service scale web_server=3
# docker service ls
# docker service ps web_server

故障切换 failover

failover 失效备援

swarm 内置了failover策略,swarm会尽力保证我们要求的期望状态

访问容器

将容器公布出去

# docker service rm web_server
删除服务

# docker service create --name web_server --replicas=2 httpd
创建服务并拥有两个副本

# docker service ps web_server
查看服务的信息

# docker ps
在实际运行容器的机器上查看容器

# netstat -antp | grep 80
查看主机监听的端口

# docker exec web_server.2.rt2nabx6qnon874ypzmf5fuuq ifconfig
查看容器的网络信息

# curl 172.17.0.2
访问容器IP地址上的80端口(只能在host上访问容器运行的应用,并未暴露到外部)

# docker service update --publish-add 8080:80 web_server
修改web服务的端口暴露到外部网络

# docker service create --name web_server1 --publish 80:80 --replicas=2 httpd
创建服务时声明服务暴露到外部网络

这样在集群的任何一个节点 访问 publish 映射的端口,都可以访问到服务内容器副本中的应用。

神奇的 routing mesh

swarm的每个节点上都运行着 load balancer 负载均衡器

上述环境下,当我们访问swarm集群的任意节点时,swarm内部的 load balancer 就会将请求转发给web_server其中的一个副本。

这就是 routing mesh 路由网格,所以访问swarm集群的那个节点,即使此节点上没有运行这个服务的副本,最终都可以访问到service

ingress网络

当我们应用 --publish-add 时,swarm 会重新配置service

# docker service ps web_server
查看service内容器的变化

之前的所有副本被shutdown,然后启动了新的副本

# docker exec web_server.2.q9rxkj6q9zk4q6o9uvgx2lu7b ifconfig
再次查看新建容器内部的网络情况
发现相比之前的容器多出一张网卡 10.255.0.7

# docker network ls
# docker network inspect ingress
查看网络的详细信息

观察发现现在的容器副本有两张网卡,eth0为ingress提供,eth1为bridge提供

eth0 连接的是overlay类型的ingress网络,让在不同host上运行的容器可以互相通信

eth1 连接的是bridge类型的docker_gwbridge网络,,让其可以通过host主机访问外网

ingress网络是创建swarm集群,或加入集群时自动创建的overlay网络

通过overlay网络,主机和容器,容器和容器之间可以相互访问;同时 routing mesh 将外部请求路由到不同主机的容器,从而实现了外部网络对service的访问。

service之间的通信

微服务架构的应用由多个service组成。每个service都运行了若干个容器。service之间必然是要通信的。

服务发现

1、将所有service都publish出去,然后通过routing mesh访问。但缺点就是把不应该公布出去的服务也全部公布出去,增加了安全隐患。

如果不采用publish方式,swarm集群就要提供一种满足以下要求的机制
1、让service之间可以简单的方式进行访问
2、当service副本的IP发生改变,不会影响service之间的访问
3、当service副本数发生改变时,不会影响service之间的访问

docker swarm 原生支持服务发现,通过服务发现,service使用者不需要知道service运行在哪,ip多少,几个副本,就能与service通信。

创建overlay网络
要使用服务发现,相互通信的service就要在同一overlay网络下
ingress网络没有提供服务发现的功能,必须手动创建新的overlay网络

# docker network create --driver overlay myapp_net
# docker network ls
# docker network inspect myapp_net
创建一个overlay网络

# docker service create --name my_web --network myapp_net --publish 80:80 --replicas 3 httpd
# docker service create --name util --network myapp_net busybox sleep 10000000
将两个服务运行在指定网络中

# docker service ps util
查看服务的副本运行在那台worker上

# docker exec util.1.r6cur67bppq1us4brhgdpy612 ping -c 4 my_web
尝试ping web服务

ping服务名解析出了一个ip地址,着就是web服务的vip,swarm会对vip的访问负载均衡到每一个副本
对于服务的使用者来说,根本不需要知道my_web副本的ip,也不需要知道my_web的vip,只需要使用service的名字就能访问服务。

Rolling update 滚动更新

滚动更新降低了应用更新的风险,如果某个副本更新失败,整个更新将暂停,其他副本则可以继续提供服务。同时在更新的过程中一直有副本在运行的,因此也保证了业务的连续性。

创建一个服务
# docker service create --name my_web --replicas 3 --network myapp_net --publish 80:80 httpd:2.2.31
# docker service ps my_web
创建一个特定版本的web服务

# docker service update --image httpd:2.2.32 my_web
# docker service ps my_web
将服务的容器副本更新为另一个版本
默认配置下每次只更新一个副本,且副本之间没有等待时间

# docker service update --replicas 6 --update-parallelism 2 --update-delay 1m40s my_web
更新web服务service的设置
将容器拓展为6个副本 每次滚动升级时2个一组,每100秒升级一组
--update-parallelism 设置并行更新的副本数
--update-delay 设置滚动更新的间隔时间

# docker service inspect --pretty my_web
检查web服务service的设置

# docker service ps my_web
查看服务的状态,容器副本数量的变化

# docker service update --image httpd:2.4.16 my_web
# docker service ps my_web
将web服务容器副本滚动升级到2.4

# docker service update --rollback my_web
--rollback 回滚升级
--rollback 只能回滚到上次update的状态,不能无限制的回滚
# docker service ps my_web | grep Run

global mode

searm可以在service创建或运行过程中通过--replicas灵活的增加减少副本数,内部调度器会根据当前集群的资源使用情况在不同的node上启停容器,这就是service默认的replicas mode
service还提供了一个global mode,其作用是强制在每个worker节点上运行一个且最多一个副本,即使之后有新的node加入,swarm也会在新的节点上启动一个副本。

docker service create --mode global --name logspout \
--mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock  \
gliderlabs/logspout

创建一个service,在每个node节点上运行一个副本

# docker service inspect logspout --pretty
查看service的设置 Service Mode:global

Label

精细控制service的运行的位置
1、为每个node定义label
2、设置service运行在指定的node上
label可以灵活的描述node的属性,用户可以任意指定

# docker node update --label-add env=test worker1
给node打标签
# docker node inspect worker1 --pretty
查看节点配置 查看标签信息

# docker node update --label-add env=prod swarm1
# docker node update --label-add env=prod worker2
打标签

# docker service create --constraint node.labels.env==test --replicas 3 --name my_web_test --publish 8080:80 httpd
指定在test标签上的节点运行服务

# docker service ps my_web_test
查看副本运行的节点
# docker service inspect my_web_test --pretty
查看服务约束的设置 --constraint 的设置

# docker service update --constraint-rm node.labels.env==test my_web_test
# docker service update --constraint-add node.labels.env==prod my_web_test
将服务从test环境迁移到prod环境下

Health Check

健康检查
docker 只能容器启动进程的返回代码判断其运行状态,对于容器内部应用的运行状态没有了解。
执行run命令时,通常根据dockerfile的CMD或ENTRYPOINT启动一个进程,这个进程的状态就是docker ps 显示的状态。

你可能感兴趣的:(swarm集群)