InfoQ 编辑部出品——2021年度技术盘点与展望 了解详情
写点什么

携程混合云之 kubernetes@AWS 揭秘

  • 2020 年 2 月 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 年 2 月 15 日 17:37349

评论

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

ShutdownHook原理

捉虫大师

Java

40 图|硬核解析用 Mac M1 玩转 SpringCloud

悟空聊架构

开源 Mac SpringCloud m1 passjava

基于NIO高性能、可扩展网络应用库:xSocket

风翱

4月日更 xSocket

Golang 反射

escray

学习 极客时间 Go 语言 4月日更

噱头or契机:多端协同游戏的草蛇灰线

脑极体

世界读书日,爱奇艺ers的技术产品书单

爱奇艺技术产品团队

读书

当区块链遇到工业互联网,浪潮云洲链正在那里

浪潮云

云计算

Git 常用命令速查

箭上有毒

4月日更

深入汇编指令理解Java关键字volatile

AI乔治

Java 架构 volatile Java内存模型

千人万面奇妙自见:爱奇艺短视频推荐技术中多兴趣召回技术的演变

爱奇艺技术产品团队

推荐 短视频 模型 召回

欢迎 ProForma 的制造商 ThinkTilt 加入 Atlassian 的大家庭!

Atlassian

敏捷 esm ITSM Atlssian JiraServiceManagement

Flink的Checkpoint持久化存储方案

五分钟学大数据

flink 4月日更

读书有用吗

孙苏勇

读书

大学生调研:在选择工作时,最看重什么?

石云升

28天写作 4月日更 1 周年盛典

HZFE 快报002 / 比特币7年来首次跌破50天均线

HZFEStudio

大前端 金融科技 科技互联网 资讯

如何利用 Google 开源工具 Ko 在 kubernetes 建并部署 Go 应用

公众号:云原生Serverless

Kubernetes 云原生

太厉害了,终于有人能把Ansible讲的明明白白了,建议收藏

互联网老辛

ansible

马丁策略倍投软件开发,量化倍投系统

13823153121

苹果(Apple Watch)手表使用必知必会19条

Flychen

苹果手表 IWatch Apple Watch

掉坑了!GROUP_CONCAT函数引发的线上问题

AI乔治

Java MySQL 架构 GROUPING运算符

浅析 Linux 中的 I/O 管理

赖猫

Linux

关于读书的随想

小天同学

读书 4月日更

【得物技术】得物分布式UI自动化实践

得物技术

测试 UI 质量 自动化测试 得物技术

一次用户故事拆分分享

Bruce Talk

敏捷 Agile 用户故事 User Story

大数据-数据处理分类篇

进击的梦清

大数据 批处理 流式计算框架

产品训练营第三周作业

innovator琳

产品

内容平台与热点挖掘思考

程序员架构进阶

28天写作 4月日更 领域思考 内容平台

自动源代码质量度量(ISO/IEC 5055)

Tom(⊙o⊙)

软件质量 静态分析

网络协议学习笔记 Day2

穿过生命散发芬芳

网络协议 4月日更

Java最前沿技术——ZGC

AI乔治

Java 架构 jdk ZGC JVM

打通本地部署和公有云,混合云架构让“鱼”和“熊掌”兼得(一)

UCloud技术

混合云

携程混合云之kubernetes@AWS揭秘-InfoQ