kubernetes集群中的master节点是集群的控制节点, 负责整个集群的管理和控制。执行的控制命令都是发送给master节点。 Master节点上运行的主要组件如下:
Node节点时kubernetes集群中的工作负责节点,Node上的工作负载由master分配, 当某个Node宕机时,Master会将上面的工作负载转移到其他节点上去, Node节点上运行的主要组件如下:
上图为kubernetes中所有组件一起工作时的示意图,由此我们可以得出以下几个通信流程,
根据上面节点通信的介绍我们会产生一个疑问, 这个看起来好复杂的样子。 臣妾看不懂呀。 如果想进一步了解集群中详细的工作流程请移驾 kubectl创建pod背后发生了什么 探索背后的秘密
要求结果为所有的 Kubernetes Master 服务器没有单点故障,任何一台服务器当机均不影响Kubernetes的正常工作。
为了实现没有单点故障的目标,需要为以下几个组件建立高可用方案:
etcd是Kubernetes当中唯一带状态的服务,也是高可用的难点。Kubernetes选用etcd作为它的后端数据存储仓库正是看重了其使用分布式架构,没有单点故障的特性。
虽然单节点的etcd也可以正常运行。但是推荐的部署方案均是采用3个或者5个节点组成etcd集群,供Kubernetes使用。
etcd的高可用基本有三种思路:
一是使用独立的etcd集群,使用3台或者5台服务器只运行etcd,独立维护和升级。甚至可以使用CoreOS的 update-engine 和 locksmith ,让服务器完全自主的完成升级。这个etcd集群将作为基石用于构建整个集群。 采用这项策略的主要动机是etcd集群的节点增减都需要显式的通知集群,保证etcd集群节点稳定可以更方便的用程序完成集群滚动升级,减轻维护负担。
二是在Kubernetes Master上用static pod的形式来运行etcd,并将多台Kubernetes Master上的etcd组成集群。 在这一模式下,各个服务器的etcd实例被注册进了Kubernetes当中,虽然无法直接使用 kubectl 来管理这部分实例,但是监控以及日志搜集组件均可正常工作。在这一模式运行下的etcd可管理性更强。
三是使用CoreOS提出的 self-hosted etcd方案 ,将本应在底层为Kubernetes提供服务的etcd运行在Kubernetes之上。 实现Kubernetes对自身依赖组件的管理。在这一模式下的etcd集群可以直接使用 etcd-operator 来自动化运维,最符合Kubernetes的使用习惯。
这三种思路均可以实现etcd高可用的目标,但是在选择过程中却要根据实际情况做出一些判断。简单来讲预算充足但保守的项目选方案一, 想一步到位并愿意承担一定风险的项目选方案三。折中一点选方案二。各个方案的优劣以及做选择过程中的取舍在这里就不详细展开了,对这块有疑问的朋友可以私下联系交流。
apiserver本身是一个无状态服务,要实现其高可用相对要容易一些,难点在于如何将运行在多台服务器上的apiserver用一个统一的外部入口暴露给所有Node节点。
说是难点,其实对于这种无状态服务的高可用,我们在设计业务系统的高可用方案时已经有了相当多的经验积累。需要注意的是apiserver所使用的SSL证书要包含外部入口的地址,不然Node节点无法正常访问apiserver。
apiserver的高可用也有三种基本思路:
一是使用外部负载均衡器,不管是使用公有云提供的负载均衡器服务或是在私有云中使用 LVS 或者 HaProxy 自建负载均衡器都可以归到这一类。 负载均衡器是非常成熟的方案,在这里略过不做过多介绍。如何保证负载均衡器的高可用,则是选择这一方案需要考虑的新问题。
二是在网络层做负载均衡。比如在Master节点上用 BGP 做 ECMP ,或者在Node节点上用 iptables 做NAT都可以实现。采用这一方案不需要额外的外部服务,但是对网络配置有一定的要求。
三是在Node节点上使用反向代理对多个Master做负载均衡。这一方案同样不需要依赖外部的组件,但是当Master节点有增减时,如何动态配置Node节点上的负载均衡器成为了另外一个需要解决的问题。
从目前各个集群管理工具的选择来看,这三种模式都有被使用,目前还没有明确的推荐方案产生。建议在公有云上的集群多考虑第一种模式,在私有云环境中由于维护额外的负载均衡器也是一项负担,建议考虑第二种或是第三种方案。
这两项服务是Master节点的一部分,他们的高可用相对容易,仅需要运行多份实例即可。这些实例会通过向apiserver中的 Endpoint 加锁的方式来进行leader election, 当目前拿到leader的实例无法正常工作时,别的实例会拿到锁,变为新的leader。
严格来说kube-dns并不算是Master组件的一部分,因为它是可以跑在Node节点上,并用 Service 向集群内部提供服务的。但在实际环境中, 由于默认配置只运行了一份kube-dns实例,在其升级或是所在节点当机时,会出现集群内部dns服务不可用的情况,严重时会影响到线上服务的正常运行。
为了避免故障,请将kube-dns的 replicas 值设为2或者更多,并用 anti-affinity 将他们部署在不同的Node节点上。这项 *** 作比较容易被疏忽,直到出现故障时才发现原来是kube-dns只运行了一份实例导致的故障。
上面介绍了Kubernetes Master各个组件高可用可以采用的策略。其中etcd和kube-apiserver的高可用是整个方案的重点。由于存在多种高可用方案,集群管理员应当根据集群所处环境以及其他限制条件选择适合的方案。
这种没有绝对的通用方案,需要集群建设者根据不同的现状在多个方案中做选择的情况在Kubernetes集群建设过程中频频出现, 也是整个建设过程中最有挑战的一部分。容器网络方案的选型作为Kubernetes建设过程中需要面对的另外一个大问题也属于这种情况,今后有机会再来分享这个话题。
在实际建设过程中,在完成了上述四个组件的高可用之后,最好采取实际关机检验的方式来验证高可用方案的可靠性,并根据检验的结果不断调整和优化整个方案。
此外将高可用方案与系统自动化升级方案结合在一起考虑,实现高可用下的系统自动升级,将大大减轻集群的日常运维负担,值得投入精力去研究。
虽然本篇主要在讲Kubernetes Master高可用的方案,但需要指出的是,高可用也并不是必须的,为了实现高可用所付出的代价并不低, 需要有相应的收益来平衡。对于大量的小规模集群来说,业务系统并没有实现高可用,贸然去做集群的高可用收益有限。这时采用单Master节点的方案,做好etcd的数据备份,不失为理性的选择。
一种方案为Haproxy+etcd+confd,采用松散式的组织结构,但各个组件之间的通讯是非常严密的,且扩展性更强,定制也更加灵活。
一、架构优势
约定由Haproxy+etcd+confd+Docker构建的基础服务平台简称“HECD” 架构,整合了多种开源组件,看似松散的结构,事实上已经是一个有机的整体,它们互相联系、互相作用,是Docker生态圈中最理想的组合之一,具有以下优势:
自动、实时发现及无感知服务刷新;
支持任意多台Docker主宿机;
支持多种APP接入且打散至不分主宿机;
采用Etcd存储信息,集群支持可靠性高;
采用Confd配置引擎,支持各类接入层,如Nginx;
支持负载均衡、故障迁移;
具备资源d性,伸缩自如(通过生成、销毁容器实现);
二、架构说明在HECD架构中,首先管理员 *** 作Docker Client,除了提交容器(Container)启动与停止指令外,还通过REST-API方式向Etcd(K/V)存储组件注册容器信息,包括容器名称、主宿机IP、映射端口等。Confd配置组件会定时查询Etcd组件获取最新的容器信息,根据定义好的配置模板生成Haproxy配置文件Haproxycfg,并且自动reload haproxy服务。用户在访问业务服务时,完全没有感知后端APP的上线、下线、切换及迁移,达到了自动发现、高可用的目的。详细架构图见图1-1。
图1-1 平台架构图
为了方便大家理解各组件间的关系,通过图1-2进行架构流程梳理,首先管理员通过Shell或API *** 作容器,下一步将容器信息注册到Etcd组件,Confd组件会定时查询Etcd,获取已经注册到Etcd中容器信息,最后通过Confd的模板引擎生成Haproxy配置,整个流程结束。
图1-2架构流程图
了解架构流程后,我们逐一对流程中各组件进行详细介绍。
1、Etcd介绍
Etcd是一个高可用的 Key/Value 存储系统,主要用于分享配置和服务发现。
简单:支持 curl 方式的用户 API (>
安全:可选 SSL 客户端证书认证
快速:单实例可达每秒 1000 次写 *** 作
可靠:使用 Raft 实现分布式
2、Confd介绍
Confd是一个轻量级的配置管理工具。通过查询Etcd,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload。
3、Haproxy介绍
HAProxy是提供高可用性、负载均衡以及基于TCP和>
平台环境基于Centos65+Docker12构建,其中Etcd的版本为etcd version 050-alpha,Confd版本为confd 062,Haproxy版本为HA-Proxy version 1424。下面对平台的运行环境、安装部署、组件说明等进行详细说明,环境设备角色表如下:
1、组件安装
11 Docker安装
SSH终端登录192168122服务器,执行以下命令:
# yum -y install docker-io# service docker start
# chkconfig docker on
12 Haproxy、confd安装
SSH终端登录192168120服务器,执行以下命令:
1、haproxy# yum –y install haproxy
2、confd
# wget
# mv confd /usr/local/bin/confd
# chmod +x /usr/local/bin/confd
# /usr/local/bin/confd -version
confd 062
13 Etcd安装
SSH终端登录192168121服务器,执行以下命令:
# mkdir -p /home/install && cd /home/install
# git clone
# cd etcd
# /build
# cp bin/etcd /bin/etcd
# /bin/etcd -version
etcd version 050-alpha 2、组件配置
21 Etcd配置
由于etcd是一个轻量级的K/V存储平台,启动时指定相关参数即可,无需配置。
# /bin/etcd -peer-addr 192168121:7001 -addr 192168121:4001 -data-dir /data/etcd -peer-bind-addr 0000:7001 -bind-addr 0000:4001 &由于etcd具备多机支持,参数“-peer-addr”指定与其它节点通讯的地址;参数“-addr”指定服务监听地址;参数“-data-dir”为指定数据存储目录。
由于etcd是通过REST-API方式进行交互,常见 *** 作如下:
1) 设置(set) key *** 作
{"action":"set","node":{"key":"/mykey","value":"this is awesome","modifiedIndex":28,"createdIndex":28}} 2) 获取(get) key信息# curl -L
{"action":"get","node":{"key":"/mykey","value":"this is awesome","modifiedIndex":28,"createdIndex":28}}
3) 删除key信息
# curl -L 。22 Confd+Haproxy配置
由于Haproxy的配置文件是由Confd组件生成,要求Confd务必要与haproxy安装在同一台主机上,Confd的配置有两种,一种为Confd资源配置文件,默认路径为“/etc/confd/confd”目录,另一种为配置模板文件,默认路径为“/etc/confd/templates”。具体配置如下:
创建配置文件目录
# mkdir -p /etc/confd/{confd,templates}(1)配置资源文件
详细见以下配置文件,其中“src”为指定模板文件名称(默认到路径/etc/confd/templates中查找);“dest”指定生成的Haproxy配置文件路径;“keys”指定关联Etcd中key的URI列表;“reload_cmd”指定服务重载的命令,本例中配置成haproxy的reload命令。
/etc/confd/confd/ haproxytoml
src = "haproxycfgtmpl"
dest = "/etc/haproxy/haproxycfg"
keys = [
"/app/servers",
]
reload_cmd = "/etc/initd/haproxy reload"
(2)配置模板文件
Confd模板引擎采用了Go语言的文本模板,更多见>
/etc/confd/templates/haproxycfgtmpl
log 127001 local3
maxconn 5000
uid 99
gid 99
daemon
defaults
log 127001 local3
mode >首先获取clientv3:
连接etcd:
kv是一个用于 *** 作kv的连接,其实它本质上是用了client的conn,为了更加专注于键值对的 *** 作,关闭client后也会使kv无法用。(kv的 *** 作client也能实现)
设置一个超时的context:
contextWithTimeout()会返回一个timerCtx{},并在这个结构体里注入了超时时间。cancleFunc是一个取消 *** 作的函数。put,get等 *** 作是阻塞型 *** 作,context里有一个用于管理超时的select,当时间一到就会隐式执行cancelFunc,使 *** 作停止并返回错误。如果显式的调用cancelFunc()则会立即停止 *** 作,返回错误。
put *** 作:
由于etcd是有序存储键值对的,还可以附加clientv3WithFromKey(),clientv3WithLimit()来实现分页获取的效果。
监听etcd集群键的改变:
V2版本的key在etcd是按照目录格式来存储的:
对于createdIndex 和 modifiedIndex两个值,基本上是一直相等的,当你-XPUT的时候,会同步更新这两个值,但delete和update的时候这两个值就会不同了,只有modifiedIndex会增加。
etcd的回复里面,包含了简单的消息头,里面的数据也比较重要。
数据读取比较简单,直接读取某个key就可以。
和设置一样,更改的时候用也是PUT *** 作
TTL就是给key设置一个timeout,时间到了之后,key会被自动删除,当然你可以在超时之前删除timeout,这样key就不会有超期了。同样的你也可以不断的去刷新key的timeout,这样可以起到看门狗的作用(可以用来探测etcd的存活)。
需要注意的一点是,timeout只会由leader来触发,如果一个instance(不是leader)因为某种原因退出集群了,那么该instance的超时key就不会删除了,除非它重新加入集群,leader会帮它删掉(个人认为这时候不再是timeout删除,而是raft底层的数据同步,会把删除 *** 作append到节点,节点会删除数据如果leader退出了,那么新的leader会执行timeout *** 作。
上面说过,在超时之前可以用命令重新更新key的ttl。
watch功能是etcd里面一个很重要的功能,现在有v2和v3两个版本。分别对应了不同的设计,可以参照下面的链接:
>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)