Kubernetes Master High Availability 高级实践

才云科技云开源高级工程师唐继元受邀DBAplus社群,在线分享《Kubernetes Master High Availability 高级实践》,介绍如何构建Kubernetes Master High Availability环境。

以下是分享实录:

大家好,我是才云科技的唐继元,今天给大家带来一篇技术分享,本次分享我将为大家介绍如何构建Kubernetes Master High Availability环境。此次分享内容是我在工作中经验总结,如果有不正确的或者需要改进的地方,欢迎各位大神指正。
相信大家对容器、docker和kubernetes这些概念并不陌生。下面进入本次分享的正题。
Kubernetes作为容器编排管理系统,通过Scheduler、ReplicationController等组件实现了应用层的高可用,但是针对Kubernetes集群,还需要实现Master组件的高可用。
本次分享论述的Master高可用方案主要基于社区的高可用方案(链接)的实践,但是社区的高可用方案中采用的GCE的External Loadbalancer,并未论述如何实现External Loadbalancer,而且也并没有将Kubernetes集群组件容器化。所以,我们的高可用方案在社区高可用方案的基础之上进行了如下两个方面的提升:

第一,除了kubelet之外,Kubernetes所有组件容器化;
第二,通过haproxy和keepalived构建Loadbalancer实现Master的高可用。
下面我们分四个章节来详细论述Kubernetes Master High Availability环境的搭建。

  1. HA Master整体架构

  2. 核心技术点和难点

  3. 实践中的遇到的那些坑

  4. 社区关于HA Master的未来发展

HA Master整体架构

我们已经成功将支持Master High Availability的Kubernetes集群部署到企业私有云平台,底层采用的是Ubuntu 14.04操作系统。下面是一个典型的部署环境:

clipboard.png

Static Pods是由其所在节点上的kubelet直接管理,而不需要通过Apiserver来监视它们。Static Pods的资源类型只能是Pod,而且不与任何的Replication Controller相关联,它们完全由kubelet来监视,并且当它们异常停止的时候由该kubelet负责重启它们。

(haproxy, keepalived):这里表示我们将haproxy和keepalived放置在同一个pod中。

1.1.kubelet对static pod高可用的支持

我们需要为kubelet进程配置一个manifests监视目录:

--config=/etc/kubernetes/manifests

如果有新的yaml/manifest文件添加到该目录,kubelet则根据yaml/manifest文件创建一个新的static pod;

如果我们把某个yaml/manifest文件从该目录删除,kubelet则会删除由该yaml/manifest文件所产生的static pod;

如果该目录下的yaml/manifest文件有更新,kubelet则会删除原来的static pod,而根据更新后的yaml/manifest文件重新创建一个新的static pod;

如果manifests目录下的文件没有任何变化,但是其下某个yaml/manifest文件所产生的static pod错误退出或者被误删后,kubelet仍然会根据该yaml/manifest文件重新创建一个新的static pod。

这样,kubelet在一定程度上保证了static pod的高可用。

1.2.kubelet进程的高可用

kubelet通过manifests监视目录保证了staticpod的高可用,但是如果kubelet进程本身错误退出或者被误删后,谁来负责重新启动kubelet进程呢?

在Linux系统中,我们可以通过Monit、Upstart、Systemd、Supervisor等工具实现对服务的监控保证服务的高可用。

在Ubuntu 14.04操作系统中,我们将kubelet做成系统服务,利用Upstart来保证kubelet服务的高可用,下面是kubelet服务基于Upstart的服务启动脚本/etc/init/kubelet.conf:

clipboard.png

其中:
respawn: 该命令设置服务或任务异常停止时将自动启动。除stop命令外的停止都是异常停止。
respawn limit: 该命令设置服务或任务异常停止后重启次数和间隔时间。

1.3.Master High Availability Kubernetes整体架构图

从架构图中我们可以看到:
1) Upstart保证docker服务和kubelet服务的高可用,而Kubernetes的其他组件将以staticpod的方式由kubelet保证高可用。
2)两台lb节点通过haproxy和keepalived构建出一个ExternalLoadbalancer,并提供VIP供客户端访问。
3) Haproxy配置成“SSLTermination”方式,外网client通过HTTPS请求访问集群,而内网client则可以通过HTTPS/HTTP请求访问。
4) Kubernetes高可用集群通过flannelstatic pod构建一个Overlay网络,使集群中的docker容器能够通过Kubernetes Cluster IP进行通信。

核心技术点和难点

2.1.运行在特权模式的组件
Kubernetes集群中的一些组件需要通过内核模块来为集群提供服务,因此这些组件需要运行在特权模式下,以便能访问相应的内核模块。

2.1.1.开启特权模式
为了支持docker容器在特权模式下运行,我们需要开启Kubernetes集群的特权模式权限:

--allow-privileged=true

这里主要体现在kubelet服务和apiserver服务。
1) Kubelet service
kubelet服务需要开启特权模式权限,以便允许docker容器向kubelet请求以特权模式运行。
2) Apiserver static pod
apiserver static pod需要开启特权模式权限,以便运行在特权模式下的docker容器能够访问apiserver服务。

2.1.2.运行在特权模式下的docker容器
运行在特权模式下的docker容器,在yaml文件中需要添加如下字段:

securityContext:privileged: true   

这里主要体现在kubeproxy服务、flannel服务和keepalived服务。
1) Kubeproxy static pod
kubeproxy需要通过Iptables设置防火墙规则。
2) Flannel static pod
flannel需要访问vxlan、openvswitch等路由数据报文。
3) Keepalived static pod
keepalived需要访问IP_VS内核模块来建立VIP。

2.2.Static pod必须运行在主机网络下
如上所述的这些以static pod形式存在的Kubernetes集群组件,必须工作在主机网络下:

hostNetwork: true 

虽然Overlay网络是为了让不同节点间的docker容器进行通信,而上述以staticpod形式存在的组件也都是docker容器,但是它们之间的心跳和信息交流都需要通过主机网络而不是类似于flannel等的Overlay网络。理由如下:
1)这些static pods不同于应用的pods,它们的稳定保障了Kubernetes集群的稳定性,它们之间的心跳和信息交流都是通过它们配置文件中的静态IP地址进行的,而docker/flannel网络是动态的,我们无法保证docker/flannel网络中IP地址的稳定性,同时也无法事先知道IP地址。
2) kubeproxy、flannel、haproxy需要通过主机网络修改路由规则,从而使主机上的服务能被其他主机访问。
3) haproxy需要将外网请求重定向到内网后端服务器上,也必须需要主机网络。

2.3.External Loadbalancer部署要点
对于如何配置haproxy和keepalived,网络上有非常多的资源,所以这里不在论述。下面我们来分析一下部署过程中的一些要点。
External Loadbalancer由至少两台lb node组成,通过haproxy和keepalived pod实现Master的负载均衡,对外提供统一的VIP。
我们可以将haproxy和keepalived分别放置在不同的pod中,也可以将它们放置在同一个pod中。考虑到keepalived需要监测haproxy的状态,我们会把haproxy和keepalived放在一起做成一个loadbalancerpod。

2.3.1.lb node配置
1)使能内核IPVS模块
由于keepalived需要通过IPVS模块实现路由转发,所以我们需要使能内核IPVS模块。
从Linux内核版本2.6起,ip_vs code已经被整合进了内核中,因此,只要在编译内核的时候选择了ipvs的功能,Linux即能支持LVS。因此我们只需要配置操作系统启动时自动加载IPVS模块:

echo "ip_vs" >> /etc/modules
echo "ip_vs_rr" >> /etc/modules
echo "ip_vs_wrr" >> /etc/modules

我们可以通过如下命令查看ip_vs模块是否成功加载:

lsmod | grep ip_vs

如果没有加载,我们可以通过modprobe命令加载该模块:

modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr

2)修改内核参数
为了使keepalived将数据包转发到真实的后端服务器,每一个lb node都需要开启IP转发功能

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

另外,keepalived设置的VIP有可能为非本地IP地址,所以我们还需要使能非本地IP地址绑定功能:

echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf

2.3.2.keepalived监测haproxy状态的方法
对于普通进程来说, keepalived进程可以通过“killall -0 haproxy”命令检测haproxy进程是否正常运行(注: Sending the signal 0 to a given PID just checksif any process with the given PID is running)。
然而在docker容器环境下,各容器都有自己的PidNamespace和NetworkNamespace,我们就需要开启haproxy的健康检查页面,然后keepalived通过健康检查页面的URL来检测haproxy目前是否正常运行。
haproxy健康检查页面配置:

listen  admin_statsbind  0.0.0.0:80log  globalmode  httpmaxconn  10stats  enable#Hide  HAPRoxy version, a necessity for any public-facing sitestats  hide-versionstats  refresh 30sstats  show-nodestats  realm Haproxy\ Statisticsstats  auth caicloud:caicloudstats  uri /haproxy?stats

keepalived对haproxy的状态检测:

vrrp_script check_script {script  "/etc/keepalived/check_haproxy.py  http://caicloud:caicloud@127.0.0.1/haproxy?stats"interval 5 # check every 5 secondsweight 5fall 2 # require 2 fail for KOrise 1 # require 1 successes for OK
}

2.3.3.haproxy SSL配置
haproxy代理ssl配置有两种方式:
1) haproxy本身提供SSL证书,后面的web服务器走正常的http协议;
2) haproxy本身只提供代理,直接转发client端的HTTPS请求到后端的web服务器。注意:这种模式下“mode”必须是“tcp”模式, 即仅支持4层代理。
考虑到:第一,用户亲和性访问需要7层代理的支持;第二,loadbalancer和master走的都是集群内网。所以本实践采用了第一种方式,配置如下:

frontend frontend-apiserver-https#  Haproxy enable SSLbind  *:443 ssl crt /etc/kubernetes/master-loadblancer.pemoption  forwardfordefault_backend  backend-apiserver-http

2.3.4.haproxy配置:haproxy.cfg

clipboard.png
clipboard.png

2.3.5.keepalived配置:keepalived.conf
1) lb-1上keepalived配置

clipboard.png
clipboard.png

2) lb-2上keepalived配置
lb-2跟lb-1的配置差不多,除了下面两个字段:

 state BACKUPpriority 97

2.4.flannel网络设置
2.4.1Master节点flannel网络设置
对于Master节点,需要等待Etcd Pod集群启动完后,先在Master上创建Flannel网络,然后Flannel Pod客户端才可以从Etcd中获取到各个Master节点的IP网段,获取到IP网段后会在主机上产生文件:“/var/run/flannel/subnet.env”,然后根据该文件修改docker启动参数:

.  /var/run/flannel/subnet.env 
DOCKER_OPTS="$DOCKER_OPTS  --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}"

并重启docker服务。

2.4.2非Master节点flannel网络设置
对于非Master节点,待Loadbalancer起来之后,Node节点能够访问Apiserver之后,Flannel Pod客户端才能从Etcd获取到该Node节点的IP网段,并且同样会在主机上产生文件:“/var/run/flannel/subnet.env”。然后修改docker启动参数,并重启docker服务。

3.实践中的遇到的那些坑

3.1.官网“haproxy docker image”的坑
Docker Hub上“haproxy image”的“docker-entrypoint.sh”内容如下:

clipboard.png

问题就出在“haproxy-systemd-wrapper”。如果运行命令:“haproxy -f/etc/haproxy/haproxy.cfg”, 而实际上运行的是经过“haproxy-systemd-wrapper”包装后的命令:

clipboard.png

执行命令“haproxy -f /etc/haproxy/haproxy.cfg”时,真正执行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”,对于“-Ds”选项, 官网是这么描述的:

clipboard.png

原来,“haproxy”经过“haproxy-systemd-wrapper”包装后在后台执行,而docker container不允许进程后台执行,否则docker容器将该启动命令执行完后就退出了。官网image的这个坑很大。
所以,当我们用官网“haproxy image”的时候,就需要用haproxy的完全路径来执行。比如在yaml文件中:

clipboard.png

3.2.haproxy container exited with 137
首先137退出码表示,其他进程向haproxy container发起了“kill”信号,导致haproxy container退出,容器日志如下

[WARNING] 155/053036 (1) : Setting tune.ssl.default-dh-param to 1024 by  default, if your workload permits it you should set it to at least 2048.  Please set a value >= 1024 to make this warning disappear.

其次,当通过“docker run”命令执行haproxy container,使用的命令与yaml文件中的一样,而且照样输出上述的“WARNING”,但是容器却不退出。

然后,无奈之下,我试着先将这个“WARNING”解决:这个错误是由于haproxy.cfg中添加了SSL证书导致的, 可以通过设置参数“default-dh-param”解决:

global...# turn  on stats unix socketstats  socket /run/haproxy.statstune.ssl.default-dh-param  2048
frontend frontend-apiserver-https#  Haproxy enable SSLbind  *:443 ssl crt /etc/kubernetes/master-loadbalancer.pem...

当我解决这个“WARNING”之后,奇迹出现了,haproxy container奇迹般的正常运行了。原来在容器的世界,一个“WARNING”也不能疏忽。

社区关于HA Master的未来发展

熟悉kubelet配置参数的都知道,我们在给kubelet配置apiserver的时候,可以通过“--api-servers”指定多个:

--api-servers=http://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080

这看起来似乎已经做到apiserver的高可用配置了,但是实际上当第一个apiserver挂掉之后, 不能成功的连接到后面的apiserver,也就是说目前仍然只有第一个apiserver起作用。
如果上述问题解决之后, 似乎不需要额外的loadbalancer也能实现master的高可用了,但是,除了kubelet需要配置apiserver,controllermanager和scheduler都需要配置apiserver,目前我们还只能通过“--master”配置一个apiserver,无法支持多个apiserver。
社区后续打算支持multi-master配置,实现Kubernetes Master的高可用,而且计划在Kubernetes 1.4版本中合入。
即使将来社区实现了通过multi-master配置的高可用方式,本次分享的MasterHigh Availability仍然非常有意义,因为在私有云场景中,ExternalLoadbalancer除了实现Master的高可用和负载均衡外,还可以针对Worker Node实现Nodeport请求的负载均衡,从而不仅实现了应用的高可用访问,同时也大大提高了应用的访问速度和性能。
参考链接:
链接
链接
好了,以上是本次分享的所有内容,欢迎大家批评指正,同时也希望能为大家带来些收益。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式系统的唯一ID

2019独角兽企业重金招聘Python工程师标准>>> 需求 为什么需要唯一ID 让分布式系统中的需要辨别的元素,都能有唯一的辨识标志。 几乎所有的业务系统,都有生成一个记录标识的需求,例如: 消息标识:message-id订…

android放微信@功能,Android仿微信语音消息的录制和播放功能

一、简述效果:实现功能:长按Button时改变Button显示文字,弹出Dialog(动态更新音量),动态生成录音文件,开始录音;监听手指动作,规定区域。录音状态下手指划出规定区域取消录音,删除生…

sap中泰国有预扣税设置吗_泰国的绘图标志| Python中的图像处理

sap中泰国有预扣税设置吗A colored image can be represented as a 3 order matrix. The first order is for the rows, the second order is for the columns and the third order is for specifying the color of the corresponding pixel. Here we use the BGR color format…

Attach Volume 操作(Part II) - 每天5分钟玩转 OpenStack(54)

上一节我们讨论了 attach volume 操作中 cinder-api 的工作,本节讨论 cinder-volume 和 nova-compute 如何将 volume attach 到 Instance。 cinder-volume 初始化 volume 的连接 cinder-volume 接收到 initialize_connection 消息后,会通过 tgt 创建 ta…

FMDB的介绍

2019独角兽企业重金招聘Python工程师标准>>> FMDB方法的介绍 1.首先我们需要创建一个FMDatabase实例: (FMDatabase*)DataBaseSigonInstance { //数据库初始化 NSString *homeDir NSHomeDirectory(); //NSLog("%",homeDir); NSString *dbPath …

网络克隆软件_网文生成器,克隆的是骗钱“病毒”

文章克隆器页面。图据北京晚报如今不论男女老少,多半喜欢用手机收集信息、浏览自己关注的话题。有的时候,人们会发现,不少亲朋发来的链接或者公众号推送的文章,长得特别像,但多少有那么些微不同。其实,不是…

使用python 对图片进行水印,保护自己写的文章

1,关于文章被爬 说起来挺桑心的,好不容易写的文章,被爬走。 用个搜索引擎搜索都不是在第一位,写的文章全给这些网站提供流量了。 这种网站还居多广告。 还是抱怨少点吧。csdn对于这些事情也是无所作为啊。 最起码的防盗链也不…

android layout_width 属性,android:layout_weight属性详解

在android开发中LinearLayout很常用,LinearLayout的内控件的android:layout_weight在某些场景显得非常重要,比如我们需要按比例显示。android并没用提供table这样的控件,虽然有TableLayout,但是它并非是我们想象中的像html里面的t…

angular的$http发送post,get请求无法传送参数的问题

2019独角兽企业重金招聘Python工程师标准>>> 用$http进行异步请求的时候发现了一个奇怪的事情,用$http.post(url,data)的方法进行请求,后台死活接收不到data的参数,真是百思不得姐啊..... 折腾了老半天才在stackoverflow上找到答案…

怎样解决Word文档图标无法正常显示的问题?

此类问题是由于 Word 程序相关组件损坏导致,可以通过下面的方案来解决:步骤/方法按键盘上的 Windows 徽标健 R 键,输入 regedit,按回车键。(若弹出用户账户控制窗口,请允许以继续)对于 Word 200…

MathType与Origin是怎么兼容的

MathType作为一款常用的公式编辑器,可以与很多的软件兼容使用。Origin虽然是一款专业绘图与数据分析软件,但是在使用过程中也是可以用到MathType。它可以帮助Origin给图表加上标签,或者在表格中增加公式标签。但是一些用户朋友对这个不能不是…

AutoBookmark Adobe Acrobat快速自动批量添加书签/目录

前言 解决问题:Adobe Acrobat快速自动批量添加书签/目录, 彻底告别手动添加书签的烦恼 AutoBookmark 前言1 功能简介2 实现步骤2.1 下载插件2.2 将插件复制到Acrobat文件夹下2.3 自动生成书签 1 功能简介 我们在查看PDF版本的论文或者其他文件的时候, 虽然相比较于…

Python调用微博API获取微博内容

一:获取app-key 和 app-secret 使用自己的微博账号登录微博开放平台(http://open.weibo.com/),在微博开放中心下“创建应用”创建一个应用,应用信息那些随便填,填写完毕后,不需要提交审核,需要的只是那个ap…

鸿蒙系统hdc,HDC2020有看头:要揭开鸿蒙系统和EMUI11神秘面纱?

IFA2020算是HDC2020的预热吧,一个是9月2日在德国柏林举办的消费电子展,一个是在松山湖举办的华为开发者大会,二者的目的都一样,但也有一丝不同,IFA是为了让老外了解HMS、了解华为的智慧生态,而HDC2020就是要…

Java String 学习笔记 (一)

2019独角兽企业重金招聘Python工程师标准>>> ###String 简介 String 并非java的8大基本数据类型之一。 java中基本数据类型存储在栈内存中。而String不是,新new的String 对象存储在堆内存中。而字符串存储在常量池中。String对象的引用存储中栈内存中。 …

note2 android4.3,玩家们动手吧 Note2安卓4.3固件已泄漏

【PConline 资讯】最近各个牌子的安卓机迎来了升级安卓4.3的大潮,现在三星Galaxy Note2的安卓4.3固件已经泄漏出来了。实际上,此前三星官方已经确认,Galaxy Note3可以获得官方的安卓4.3固件升级,但具体日期没有确定,只…

【JUnit 报错】 method initializationerror not found:JUnit4单元测试报错问题

今天是用JUnit测试一段代码,报错method initializationerror not found::出现如下问题: 双击这个就显示出现如下的错误: 查询网上,说是junit版本的问题: 那我就不使用JUnit这个Libernary了,下载…

将byte数组以html形式输出到页面,java 数组显示到html

java 数组显示到html[2021-02-05 01:08:54] 简介:php去除nbsp的方法:首先创建一个PHP代码示例文件;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐:…

windows 下 git 禁用 CRLF 转换 LF

2019独角兽企业重金招聘Python工程师标准>>> windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行add . 时出现提示,解决办法: 删除根目录 .git 文件夹禁用自动转换 > git config --global core.autocrl…

使用gulp构建前端(三)

为什么80%的码农都做不了架构师?>>> 使用gulp构建前端(三) 紧接着上述文章内容,开始新的插件的使用 插件三 gulp-clean-css,作用减小文件大小,并给引用url添加版本号避免缓存,一个需…