魅族容器云平台自动化运维实践
1、魅族云平台的定位是私有云平台,主要是用于支撑在线业务,用以替换传统的虚拟化方式。目前现状是2017年完成全国三个数据中心的建设,年内完成90%业务的迁移。
我们是以小团队紧跟 k8s 社区步伐,快速迭代、低成本试错的方式来构建我们的平台的。同时,针对一些我们遇到的问题,做一些局部创新,在保证系统核心的随社区稳定升级的前提下,解决好非功能性问题。
2、k8s 集群
对于 k8s 集群构建,将从 k8s 的单一镜像、k8s 集群 master、minion 三个方面分别展开介绍。
k8s 集群的安装部署是利用单一镜像 + docker run 实现一键安装。为此将所有 k8s 相关的描述文件、脚本和二进制全部打包成镜像,目的是实现集群的快速部署和升级。
3、2.2Master
为了能够实现自动加载,k8s 集群核心组件使用了 Static Pod 方式。在自动修复方面,kubelet probe 可以实现 Pod 的自检,配置了自动重启。如果需要对核心组件进行升级,指定统一镜像的版本号即可实现核心组件升级更新。
1、容器网络的方面我们采用的是 calico 的方案。主机通过 BGP 直接和核心路由设备对接,这里也可以用 RouteReflector 替代。
控制层面走 BGP,数据层面走三层路由。网络封包会经过主机的 netfilter框架,最后经由主机 forward chain 进入容器,默认都会被 conntrack。部署方面,Calico 通过 k8s 的 Daemonset 方式,部署非常方便
2、优化主要是针对 conntrack,建议尽量使用 headless service,少产生 iptables rule。同时,对 conntrack 用量进行监控。容错方面,容器会主动去 ping 交换机,确保网络的连通性。当 calico 出现问题的时候,容器是不会加入服务的,由此来保证服务的可靠性。
3、对于我们系统,绝大部分流量来自外部 LVS,其可信任度高,默认的方式会产生大量的 conntrack 记录,所以应当把 LVS 过来的流量直接给 bypass conntrack。
经过生产实践效果验证,no mesh 模式的稳定性要优于 mesh 模式。异常处理主要分为 POD 主动检测网络和 calico 的整体健康监控告警。
1、外部访问4/7层负载均衡
我们做的是对外服务,大部分流量都是从外部打进来的,终端用户都是外部的客户,所以针对外部的访问做了4层和7层的负载均衡。我们做的是对外服务,大部分流量都是从外部打进来的,终端用户都是外部的客户,所以针对外部的访问做了4层和7层的负载均衡。
2、在4层接入上采用了是阿里开源的 Fullnat LVS 方案,看中了它运维方便、水平扩展性好。工作在4层的 LVS 服务既可以支持 TCP 同时也支持 UDP,流量从client 端经过 LVS 做 Fullnat 后到达 minion,应答直接路由回对应的LVS。
对于4层负载均衡的配置,是通过自动化方式来实现的,无需人工配置,可以自动在路由设备宣告 vip,并生成对应的 ECMP 路由。LVS 的 VirtualServer 配置也是自动生成的,VirtualServer 到 EndPoint ip 的自动映射。
我们对 LVS 控制程序做了改造,暴露了一些指标,包括网络和应用服务相关的数据,并以此实现了 Grafana 可视化和监控告警。
3、一方面是对 LVS 整体流量异常告警,另一方面 realserver (Pod) 做高延迟异常检测告警。
七层负载均衡采用的是 POD 里面跑 nginx+ingress controller,它的定位是业务专属的反向代理,能够实现自动扩缩容,面向的 upstream 主要是 Jetty 业务容器。
由于四层负载均衡采用的是 FullnatLVS,真正的终端 ip 地址已经被隐藏起来了,需要从 TCPoption 中获取。realserver 默认取到的是 LVS 的 local ip 地址,需要使用 TOA 模块来获取终端 ip。
4、开源版本的 TOA 一直没有升级,为此我们将其移植到 3.16,对于大多数业务来说,客户端 ip 地址是不可或缺的。
在把 nginx 容器化之后,踩了一些坑,其中一个是延迟过高。从 access.log 看,upstream 的 RT 时间长达几秒,而直接访问 upstream Pod 服务又是很快的,说明是 nginx 的问题。经分析后发现配置不合理,nginx 容器化之后缺少对 worker 数量和亲和性的优化。
按照默认配置,一台24核 CPU 的机器上,对于一个业务的 nginx,自动配置为 24个 worker 进程,而 cpu limit 往往只设置成 5、6个核,worker 没有 cpu 资源导致高延迟。同时,调整 worker 进程的亲和性,防止压力堆积在前几个核上。