网站维护收费标准,焦作建设网站的公司,房子设计图片,网页设计公司简介代码才云科技云开源高级工程师唐继元受邀DBAplus社群#xff0c;在线分享《Kubernetes Master High Availability 高级实践》#xff0c;介绍如何构建Kubernetes Master High Availability环境。 以下是分享实录#xff1a; 大家好#xff0c;我是才云科技的唐继元#xff0c;… 才云科技云开源高级工程师唐继元受邀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环境的搭建。 HA Master整体架构核心技术点和难点实践中的遇到的那些坑社区关于HA Master的未来发展HA Master整体架构 我们已经成功将支持Master High Availability的Kubernetes集群部署到企业私有云平台底层采用的是Ubuntu 14.04操作系统。下面是一个典型的部署环境 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 其中: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-privilegedtrue这里主要体现在kubelet服务和apiserver服务。 1 Kubelet servicekubelet服务需要开启特权模式权限以便允许docker容器向kubelet请求以特权模式运行。 2 Apiserver static podapiserver static pod需要开启特权模式权限以便运行在特权模式下的docker容器能够访问apiserver服务。 2.1.2.运行在特权模式下的docker容器运行在特权模式下的docker容器在yaml文件中需要添加如下字段 securityContext:privileged: true 这里主要体现在kubeproxy服务、flannel服务和keepalived服务。 1 Kubeproxy static podkubeproxy需要通过Iptables设置防火墙规则。 2 Flannel static podflannel需要访问vxlan、openvswitch等路由数据报文。 3 Keepalived static podkeepalived需要访问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_wrr2修改内核参数为了使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?statskeepalived对haproxy的状态检测 vrrp_script check_script {script /etc/keepalived/check_haproxy.py http://caicloud:caicloud127.0.0.1/haproxy?statsinterval 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-http2.3.4.haproxy配置haproxy.cfg 2.3.5.keepalived配置keepalived.conf1 lb-1上keepalived配置 2 lb-2上keepalived配置lb-2跟lb-1的配置差不多除了下面两个字段 state BACKUPpriority 972.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”内容如下: 问题就出在“haproxy-systemd-wrapper”。如果运行命令“haproxy -f/etc/haproxy/haproxy.cfg”, 而实际上运行的是经过“haproxy-systemd-wrapper”包装后的命令 执行命令“haproxy -f /etc/haproxy/haproxy.cfg”时真正执行的是:“/usr/local/sbin/haproxy -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg -Ds”对于“-Ds”选项, 官网是这么描述的 原来“haproxy”经过“haproxy-systemd-wrapper”包装后在后台执行而docker container不允许进程后台执行否则docker容器将该启动命令执行完后就退出了。官网image的这个坑很大。所以当我们用官网“haproxy image”的时候就需要用haproxy的完全路径来执行。比如在yaml文件中 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-servershttp://m1b:8080,http://m1c:8080,http://m2a:8080,http://m2b:8080,http://m2c:8080这看起来似乎已经做到apiserver的高可用配置了但是实际上当第一个apiserver挂掉之后, 不能成功的连接到后面的apiserver也就是说目前仍然只有第一个apiserver起作用。如果上述问题解决之后, 似乎不需要额外的loadbalancer也能实现master的高可用了但是除了kubelet需要配置apiservercontrollermanager和scheduler都需要配置apiserver目前我们还只能通过“--master”配置一个apiserver无法支持多个apiserver。社区后续打算支持multi-master配置实现Kubernetes Master的高可用而且计划在Kubernetes 1.4版本中合入。即使将来社区实现了通过multi-master配置的高可用方式本次分享的MasterHigh Availability仍然非常有意义因为在私有云场景中ExternalLoadbalancer除了实现Master的高可用和负载均衡外还可以针对Worker Node实现Nodeport请求的负载均衡从而不仅实现了应用的高可用访问同时也大大提高了应用的访问速度和性能。参考链接链接链接好了以上是本次分享的所有内容欢迎大家批评指正同时也希望能为大家带来些收益。