NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

携程混合云之 kubernetes@AWS 揭秘

  • 2020-02-15
  • 本文字数:4033 字

    阅读完需:约 13 分钟

携程混合云之kubernetes@AWS揭秘

一、引言

随着携程国际化战略的实施和业务海外的部署,混合云已经达到了一定的规模。为了支持容器,我们在 AWS 上部署了 kubernetes。主要是弹性发布的考量。


应用交付效率上,初始化一台虚拟机在分钟级别,涉及操作庞杂,除了启动虚拟机,还需要进行应用环境的安装,而拉起一台容器的时间可以控制在秒级。


运维管理效率上,虚拟机的维护比容器要复杂得多,特别是在目前有着多个公有云合作厂商的情况下,工作量和复杂程度爆增。以镜像为例,自定义的镜像无法在不同公有云厂商之间进行统一,比如 AWS 的 C5 等系列要求我们安装 ENA(Elastic Network Adapter)增强联网的驱动。目前我们在几家公有云上的自定义镜像是也是保持着异构的状态。


所以,引入了混合云的容器发布。借助着业务在 AWS 的应用部署,有了 Kubernetes@AWS 的主题。

二、为什么在 AWS 上自己搭建 kubernetes

首先是网络上的重要考量,目前适配携程的技术体系需要满足两个网络适配的要求。


IP 直连:存在应用互访是通过 IP 进行访问的情况,而且携程的应用并非全是跑在 kubernetes 集群中,所以为了保证全局应用的可用性,就需要容器的 IP 是 kubernetes 集群外可见的 IP。


IP 固定:假设应用在重新发布时 IP 发生变化,那必须有良好的机制通知各个相关的系统。但是目前存在有运维等系统的架构是基于 IP 固定这一前提条件。要完善这种架构不是一时之力,所以我们在这期项目的折中方案是适应当前的技术架构,保证容器应用在发布新版本、宿主机故障重新拉起容器时,IP 保持不变。


这两个需求都不是 kubernetes 可以原生支持的,kubernetes 提供了 Service、Ingress 等服务暴露的方法,但是不能完全满足我们上述的网络需求,社区现成的 flannel、calico 等容器网络方案不能采用,需要进行定制化。


同时,我们也针对 kubernetes 做了调度等层面的自定义开发。虽然 AWS 也发布了 kubernetes 产品——EKS,是一套打通公有云的方案,但也意味着失去了自定义开发及控制平面运维管控的能力。所以,我们也没有采用公有云的原生 kubernetes 产品。


出于对定制化能力和控制平面管控的需求,也为了与私有云 IDC 的技术栈保持一致,尽量减少运维成本,进行过一系列的调研之后,我们最终选择自己在云上搭建 kubernetes 集群。

三、如何在 AWS 上自己搭建 kubernetes

主要从网络、镜像、日志监控这几个组件讲讲我们的方案选型及设计。

3.1 网络

容器网络的方案我们是基于 VPC(Virtual Private Cloud)和弹性网络接口(Elastic Network Interface,ENI)进行实现的。


VPC 是一个用户在公有云上自建的隔离的虚拟网络,可以自定义地址空间段。我们以一个地域(Region)为例,一个 VPC 在其中一个可用区内的架构大致如下:



每个可用区内有一个公有子网和一个私有子网。


公有子网:想对 internet 直接暴露的服务一般部署在公有子网,给实例绑定一个弹性 IP(公有 IP),Internet 即可通过这个公网 IP 进行访问。公有子网里的缺省路由是 Internet 网关,由 Internet 网关实现 VPC 与 Internet 之间的通信。其中公有子网里有个 NAT 网关,有对应的私有 IP 和公有 IP。NAT 网关的作用是允许私有子网中的实例连接到 Internet 或其他 AWS 服务的能力,但能避免 Internet 直接连接这些实例。


私有子网:一般用于供内部调用的服务,如数据库、应用后端等。私有子网里的实例如果要访问 Internet 上的服务,与私有 IDC 里通过代理实现的方式不一样,会通过描述私有子网的缺省路由为公有子网里的 NAT 网关,实现与 Internet 的通信。


图上子网里实例的私有 IP 地址,其实是和弹性网络接口(Elastic Network Interface,ENI)相关的。它是 VPC 中的一个逻辑网络组件,特性如下:


1 个弹性网络接口具有:


  • 1 个 Mac 地址

  • 1 个主要私有 IP 地址

  • 多个辅助私有 IP 地址

  • 1 个或多个安全组,需要注意的是:ENI 上的 IP 地址的安全组是跟随着对应网卡的安全组而决定出入控制的。


其中每个私有 IP 地址都可以绑定一个弹性 IP。


一个实例可以有多个弹性网络接口:


  • 1 个主要弹性网络接口,不可插拔,如 ifconfig 中 eth0

  • 多个辅助网络接口,可动态插拔,如 ifconfig 中 eth1~n



实例可以容纳的最大弹性网络接口数和每个接口的最大 IP 地址个数是有限制的,一般来说,与实例类型相关,总体来说与配置成正比。


利用弹性网络接口,我们衍生出了两种容器网络的子方案:


  • 单网卡多 IP

  • 单网卡单 IP


单网卡多 IP 容器网络方案



该方案的网络要点在于:一个弹性网络接口绑定多个 IP,其中第一个 IP(主要私有 IP)作为宿主机对外通信的 IP,后面的 IP(辅助私有 IP)是容器的 IP。容器和宿主机之间通过 veth pair 进行连接,同时通过路由表进行容器出入流量的控制。


单网卡单 IP 容器网络方案



虽然一个弹性网络接口可以绑定多个 IP,但是也提高了复杂性。该单网卡单 IP 子方案中,把一个弹性网络接口作为一个调度的单元,每个弹性网络接口只使用一个 IP,其中第一个弹性网络接口(eth0)留给宿主机继续使用,在实例上添加新的辅助弹性网络接口(eth1-N),并把弹性网络接口移入容器的网络命名空间,直接给容器使用。对比如下:


网络子方案优势劣势
单网卡多IP可部署的Pod个数较多,资源利用率高调度层要选择可容纳新IP的网卡
IP的出入访问由网卡的安全组决定,调度还需选择对应安全组的网卡
单网卡单IP独占网卡设备,便于隔离
无新增的虚拟化层,性能是网卡的性能
只利用了网卡上的第一个IP,可容纳的Pod个数较少,资源利用率相对较少


我们最终选择了单网卡单 IP 的子方案,原因在于,比较简单,同时,承载的主要是 Java 应用,对应的配置一般不会太低,不会有很明显的资源浪费。


可以看到,如上的网络方案,由于容器的 IP 其实是 VPC 范畴地址空间段的 IP 地址,所以可以达到 kubernetes 集群外 IP 可见的需求,还有 IP 固定的需求,是这么实现的。



有一个全局的 IP 地址管理模块,简称 GIPAM,它存储了 pod name(我们使用的是 Statefulset)与 IP 的一对一关系,并负责与公有云进行 API 的交互。Node 上的 cni 插件,在设置网络前,先去 GIPAM 上查询一下 IP 的信息。应用重新发布,故障迁移,重新拉起一个容器时,不管是不是在同个 node,由于 cni 插件会以 GIPAM 作为 IP 的数据源,这样就保证了 IP 的固定和漂移。


举个创建容器网络的图例:


3.2 镜像

我们在私有云的每个 IDC 都部署了一套 Harbor,组成了 Harbor 集群联邦,并且跨越测试环境和生产环境。并使用了 DNS 劫持的技术,推送 docker 镜像时,是往各自 IDC 的 Harbor 进行推送,后台自动异步地同步到其他 IDC。保证应用在部署时优先从同 IDC 的 Harbor 进行镜像的拉取,如果失败,再跨 IDC 拉取镜像,减少应用拉起的时间。


在 AWS 上我们选择了自己搭建 Harbor,后端的存储采用 S3。由于目前我们在公有云 IDC 上的应用相对较少,暂时未加入联邦,未开启自动同步,在发布流程上保证在应用在部署时预先推送镜像到 AWS IDC 的 Harbor。同样也使用了 DNS 劫持技术,保证使用同样的镜像域名。


3.3 日志监控

网络解决了,镜像可以拉取了,可以正式拉起一台容器了。那监控和日志是如何解决的呢?



在公有云我们部署了一套与私有云一致的日志监控系统,hickwall、grafana 等,采用了 Prometheus+Telegraf+InfluxDB+Grafana 等与私有云一致的技术栈。在云上采集,云上处理,只送回必要的告警数据,并对接了 NOC 体系,进行 7*24 的监控。

四、同步私有云数据到公有云及疑难杂症

4.1 同步私有云数据到公有云

涉及到 IDC 之间大量数据的同步,我们是采用公网传输的方式,毕竟专线带宽有限而且昂贵。有关 AWS 数据的流量费用,可以总结为:


如果服务部署在私有子网,与 Internet 的通信会经过 NAT 网关。经过 NAT 网关的流量不管出入,一律收取数据处理费用。


如果服务部署在公有子网,通过公网 IP 与 Internet 通信。而公网 IP 的收费模式是只收出流量,进流量不收费。


所以我们通用的把数据从私有 IDC 同步到公有云的部署架构是:把数据收集服务部署在公有子网,实例带有公有 IP,私有云 IDC 的推送服务通过 Internet 进行数据的推送。



同样,如果公有云上的服务需要从外部供应商拉取的数据量比较大,我们也是采用服务部署在公有子网的模式。如此节省了经过 NAT 网关的数据处理费用。

4.2 AWS ELB 负载均衡不支持回环路由

我们通过 AWS ELB(Elastic Load Balancing)把 kubernetes api server 组成一个高可用的集群,但是上线后,发现在 master 节点上使用 kubectl 命令经常会超时,集群中也有比较多的访问 api-server 的 i/o timeout 日志。


这个问题在于通过实例 id 进行注册的 ELB 不支持回环路由。即通过实例 id 注册到 ELB 的目标时,客户端的源 IP 地址会保留,ELB 在路由后发现源地址和目的地址相同,会丢弃这些包,连接仅在请求路由到不同的实例时才会成功。Kubernetes 在部署架构中,通常采用混合部署的模式,在同一台主机上同时启用 kube-scheduler、kube-api 等组件。


该问题可以通过改用通过 IP 地址注册目标到 ELB 负载均衡进行解决。为了支持这种应用混布场景,AWS 推出了通过 IP 地址进行注册的 ELB 负载均衡,即可避免不支持回环路由而导致连接超时的问题。


4.3 kubelet 进程 max-pods 设置

由于我们的网络方案受限于实例上弹性网络接口的最大个数,要注意在 kubernetes node 上对 kubelet 进程的 max-pods 参数进行设置以限制 Pod 的最大数量。


五、总结


本文首先介绍了在携程混合云平台上支持容器发布的背景,并引出了自搭 kubernetes 的初衷,要适配的网络需求,再详细从网络、镜像、日志监控等组件介绍了携程在 AWS 自己搭建 kubernetes 的方案选型及设计,接着给出了从私有云 IDC 同步数据到公有云的通用部署架构,并从几个示例介绍了探索过程中碰到过的注意事项。


我们在混合云上的广大探索还在持续中


作者介绍


陈丹双,携程高级工程师,毕业于复旦大学,积累多家公有云对接经验,持续探索混合云,关注 kubernetes、docker 等容器技术。


本文转载自公众号携程技术(ID:ctriptech)。


原文链接


https://mp.weixin.qq.com/s/r7HeP6FCr6ZbHIRsOt0kcg


2020-02-15 17:37742

评论

发布
暂无评论
发现更多内容

工赋开发者社区 | 精益思想与数字化技术难融合?

工赋开发者社区

docker学习笔记(一)

Studying_swz

10月月更

基础结构:链表 回文链表

智趣匠

Python 10月月更 回文数

一文搞懂CAN和CAN FD总线协议

不脱发的程序猿

汽车电子 通信协议 CAN总线 CAN和CAN FD总线协议 CAN FD总线

Centos7 搭建单机Spark分布式集群

Yeats_Liao

后端 虚拟机 10月月更

工赋开发者社区 | 最小可行架构注意事项:必须考虑分布式处理和数据的位置

工赋开发者社区

ZooKeeper基本架构

穿过生命散发芬芳

zookeeper 10月月更

nginx快速入门

Studying_swz

10月月更

docker学习笔记(二)

Studying_swz

Docker 10月月更

cstdio的源码学习分析11-格式化输入输出函数fprintf---format解析跳转表逻辑分析

桑榆

c++ 源码刨析 10月月更

工赋开发者社区 | 即使是程序员也会喜欢这8种无代码/低代码工具

工赋开发者社区

C/C++的类型转换

雪芙花

c c++ 10月月更

2022-10-19:一个数组如果满足 : 升降升降升降... 或者 降升降升...都是满足的 给定一个数组, 1,看有几种方法能够剔除一个元素,达成上述的要求 2,数组天然符合要求返回0 3,剔

福大大架构师每日一题

算法 rust 福大大

深入理解java中的自动装箱与拆箱

乌龟哥哥

10月月更

【愚公系列】2022年10月 Go教学课程 033-结构体方法重写、方法值、方法表达式

愚公搬代码

10月月更

你一定要看的:Go slice切片详解和实战

王中阳Go

Go golang 高效工作 学习方法 10月月更

工赋开发者社区 | Gartner发布2023年十大战略技术趋势

工赋开发者社区

什么是IP路由?思科与华为在IP路由配置上有啥区别?

wljslmz

路由器 动态路由 静态路由 10月月更 IP 路由

CAN与CAN FD通信之间存在的问题

不脱发的程序猿

汽车电子 CAN总线 CAN FD总线 CAN与CAN FD通信问题 CAN与CAN FD通信

牛客刷题系列(完全数计算,扑克牌大小)

雪芙花

c c++ 10月月更

运维服务体系架构

阿泽🧸

10月月更 运维服务

【内网渗透】一次简单内网靶场渗透

网络安全学海

黑客 网络安全 安全 信息安全 渗透测试

如何进行项目管理?

老张

项目管理

如何监测MySQL是否命中索引?

乌龟哥哥

10月月更

Centos7 搭建Jupyter NoteBook教程

Yeats_Liao

后端 虚拟机 10月月更

C++11智能指针(auto_ptr,unique_ptr,shared_ptr,weak_ptr的详解与模拟实现)

雪芙花

c c++ 10月月更

Pixel系列还能打,靠的是什么?

脑极体

人工智能

聊聊 K8S:K8S集群搭建实战

老周聊架构

k8s 10月月更

Spring Boot「09」Property 高级特性

Samson

Java 学习笔记 Spirng spring-boot 10月月更

一份经过时间检验的 Laravel PHPUnit 测试经验分享

乌龟哥哥

10月月更

【资损】资损防控的系统规范之服务接口类设计

小明Java问道之路

架构 微服务 金融 10月月更 资损

携程混合云之kubernetes@AWS揭秘_技术管理_陈丹双_InfoQ精选文章