网易云容器服务基于Kubernetes的实践探索

Kubernetes的特点

近年来Docker容器作为一种轻量级虚拟化技术革新了整个IT领域软件开发部署流程,如何高效自动管理容器和相关的计算、存储等资源,将容器技术真正落地上线,则需要一套强大容器编排服务,当前大红大紫的Kubernetes已经被公认为这个领域的领导者。Google基于内部Borg十多年大规模集群管理经验在2014年亲自倾心打造了Kubernetes这个开源项目,欲倚之与AWS在云计算2.0时代一争高下,即便如此,Kubernetes的定位主要是面向私有云市场,它最典型的部署模式是在GCE或AWS平台上基于云主机、云网络、云硬盘及负载均衡等技术给用户单独部署一整套Kubernetes容器管理集群,其本质上是卖的IAAS服务,Kubernetes集群还是需要靠用户自己维护,大家知道Kubernetes虽然功能强大但使用、管理、运维门槛也高,出问题了大多数用户会束手无策。

这几年国内容器云领域也是群雄割据,但多数还是以私有云为主,提供公有云容器服务的却很少,主要是公有云要考虑的问题多、挑战大。虽然如此,网易云的还是提供了公有云模式的容器服务。网易云从2015年开始做容器服务时也被Kubernetes强大的功能、插件化思想和背后强大的技术实力说吸引,至今已经跟随Kubernetes一起走过两年多,积累了不少经验。因为我们特别希望以公有云的方式提供一种更易用容器服务,任何对容器感兴趣的用户都能快速上手,为此也遇到了很多私有云下不会出现的问题。

列举几个Kubernetes在公有云容器场景下的需要特别解决的关键问题。一是Kubernetes里没有用户(租户)的概念,只有一个很弱的命名空间来做逻辑隔离。二是Kubernetes和Docker的安全问题很突出,API访问控制较弱且没有用户流控机制,一些资源全局可见。而Docker容器与宿主机共享内核的轻量级隔离从根本上没法做到彻底安全。三是Kubernetes集群所需要IAAS资源(如Node,PV)都要预先准备足够,否则容器随时会创建失败,公有云这样的话会造成严重的资源浪费,产生巨大的成本问题。四是Kubernetes单个集群能支撑的节点总数有限,最大安全规模只有5千个Node,公有云下扩展性将会有问题。

网易云容器如何解决Kubernetes在公有云上的问题

先看下网易云容器服务的架构图(如图1),这里的Kubernetes处于底层IAAS服务和上层容器平台的中间,因为我们的容器服务不仅仅提供Kubernetes本身容器编排管理功能,更是为提供一整套专业的容器解决方案,还包括容器镜像服务,负载均衡服务,通过使用DevOps 工具链高效管理微服务架构。考虑到Kubernetes概念较多、普通用户使用复杂,也为了便于整合其他配套服务,我们并没有直接暴露Kubernetes的API和所有概念给普通用户。

图片描述
公有云租户概念

网易云容器服务基于Kubernetes已有的Namespace的逻辑隔离特性,虚拟出一个租户的概念,并与Namespace进行永久绑定:一个Namespace只能属于一个租户,一个租户则可以有多个Namespace。这样Kubernetes里不同租户之间的Pod、Service、Secret就能自然分割,而且可以直接在原生的Namespace/Resouce级别的认证授权上进行租户级别的安全改造。

图片描述
多租户安全问题

关于Kubernetes的API的安全访问控制,尽管网易云容器没有直接暴露Kubernetes的API给用户,但用户容器所在的Node端也都要访问API,Node本质就是用户的资源。我们在最早基于Kubernetes 1.0开发的时候就专门增加了一套轻量级扩展授权控制插件:基于规则访问控制,比如配置各租户只能Get和Watch属于自己Namespace下的Pod资源,解决对Kubernetes资源API权限控制粒度不够精确且无法动态增减租户的问题。值得欣慰的是几个月前官方发布的1. 6新推出RBAC(基于角色访问控制)功能,使得授权管理机制得以增强,但服务端对用户Node端访问的异常流量控制的缺乏依然是一个隐患,为此,我们也在apiserver端增加请求数来源分类统计和控制模块,避免有不良用户从容器里逃逸到Node上进行恶意攻击。 
原生的kube-proxy提供的内部负载必须要List&Watch集群所有Service和Endpoint,导致就算在多租户场景下Service和Endpoint也要全部暴露,同时导致iptables规则膨胀转发效率极低;为此我们对kube-proxy也做了优化改造:每个租户的Node上只会List&Watch自己的相关Namespace下资源即可,这样既解决了安全问题又优化性能,一箭双雕。

至于Docker的隔离不彻底的问题,我们则选择了最彻底的做法:在容器外加了一层用户看不见的虚拟机,通过IAAS层虚拟机的OS 内核隔离保证容器的安全。

容器的IAAS资源管理

容器云作为新一代的基础设施云服务,资源管理必然也是非常关键的。私有云场景下整个集群资源都属于企业自己,预留的所有资源都可以一起直接使用、释放、重用;而公有云多租户下的所有资源首先是要进行租户划分的,一旦加入kubernetes集群,Node、PV、Network的属主租户便已确定不变,如果给每个租户都预留资源,海量租户累计起来就非常恐怖了,没法接受。当然,可以让公有云用户在创建容器前,提前把所有需要的资源都准备好,但这样又会让用户用起来更复杂,与容器平台易用性的初衷不符,我们更希望能帮用户把精力花在业务本身。

于是我们需要改造kubernetes,以支持按需动态申请、释放资源。既然要按需实时申请资源,那就先理下容器的创建流程,简单起见,我们直接创建Pod来说明这个过程,如图3所示。

图片描述

Pod创建出来后,首先控制器会检查是否有PV(网易云容器为支持网络隔离还增加租户Network资源),PV资源是否匹配,不匹配则等待。如果Pod不需要PV或者PV匹配后调度器才能正常调度Pod,然后scheduler从集群所有Ready的 Node列表找合适Node绑定到Pod上,没有则调度失败,并从1秒开始以2的指数倍回退(backoff)等待并重新加入调度队列,直到调度成功。最后在调度的Node的kubelet上拉镜像并把容器创建并运行起来。

通过分析上述流程可以发现,可以在控制器上匹配PV或Network时实时创建资源,然后在调度器因缺少Node而调度失败时再实时创建Node(虚拟机VM),再等下次失败backoff重新调度。但是仔细分析后会发现还有很多问题,首先是IAAS中间层提供的创建资源接口都是异步的,轮询等待效率会很多,而且PV,Network,Node都串行申请会非常慢,容器本来就是秒级启动,不能到云服务上就变成分钟级别;其次Node从创建VM,初始化安装Docker、kubelet、kube-proxy到启动进程并注册到Kubernetes上时间漫长,调度器backoff重新调度多次也不一定就绪,最后,基于Kubernetes的修改要考虑少侵入,Kubernetes社区极度活跃一直保持3个月发布一个大版本的节奏,要跟上社区发展可能需要不断升级线上版本。

最终,我们通过增加独立的ResourceController,借助watch机制采用全异步非阻塞、全事件驱动模式。资源不足就发起资源异步申请,并接着处理后面流程,而资源一旦就绪立马触发再调度,申请Node时中间层也提前准备虚拟机资源池,并将Node初始化、安装步骤预先在虚拟机镜像中准备好。于是,我们详细的创建流程演变为图4所示。(注:最新Kubernetes 已经通过StorageClass类型支持PV dynamic provisioning) 
图片描述
与原生的Kubernetes相比,我们增加了一个独立的 ResourceController管理所有IAAS资源相关的事情,具体的Pod创建步骤如下:

  • 1、上层client请求apiserver创建一个Pod。
  • 2、ResourceController watch到有新增Pod,检查PV和Network是否已经创建; 
    同时,另一边的scheduler也发现有新Pod尚未调度,也尝试对Pod进行调度。
  • 3、因为资源都没有提前准备,最初ResourceController检查时发现没有与Pod匹配的PV和Network,会向IAAS中间层请求创建云盘和网络资源; 
    scheduler 则也因为找不到可调度的Node也同时向IAAS中间层请求创建对应规格的VM资源(Node),这时Pod也不再重入调度队列,后面一切准备就绪才会重调度。
  • 4、因为IAAS中间层创建资源相对较慢,也只提供异步接口,待底层资源准备完毕,便立即通过apiserver注册PV、Network、Node资源
  • 5~6、ResourceController当发现PV和Network都满足了,就将他们与Pod绑定;当发现Pod申请的Node注册上来,且PV和Network均绑定,会把Pod设置为ResourceReady就绪状态
  • 7、Scheduler再次watch到Pod处于ResourceReady状态,则重新触发调度过程,
  • 8、Pod调度成功与新动态创建Node进行绑定
  • 9~10、对应Node的kubelet watch到新调度的Pod还没有启动,则会先拉取镜像再启动容器。

集群最大规模问题

从正式发布1.0版本至今最新的1.7,Kubernetes共经历了2次大规模的性能优化,从1.0的200个node主要通过增加apiserver cache提升到1000个node,再到1.6通过升级etcdv3和json改protobuf最终提升到5000 node。但是官方称后续不会再考虑继续优化单集群规模了,已有的集群联邦功能又太过简陋。如果公有云场景下随着已有用户规模不断增大,一旦快接近集群最大规模时,就只能将其中一些大用户一批批迁移出去来腾空间给剩余用户。

于是我们自己在社区版本基础上又做了大量定制化的性能优化,目前单集群性能测试最大安全规模已经超过3万,验收测试包括集群高水位下,大并发创建速度deployment和快速重启master端服务和所有node端kubelet等在内的多种极端异常操作,保证创建时间均值<5s,99值<15s,集群中心管控服务最差在3分钟内快速恢复正常。

具体的优化措施包括:

  • 1、 scheduler优化 
    根据租户之间资源完全隔离互补影响的特性,我们将原有的串行调度流程,改造为租户间完全并行的调度模式,再配合协程池来争夺可并行的调度任务。在调度算法上,还采用预先排除资源不足的node、优化过滤函数顺序等策略进行局部优化。
  • 2、 Controller优化 
    熟悉Kubernetes的人都知道,Kubernetes有个核心特点就是事件驱动,实时性很好,但是有个Sync事件却干扰了FIFO的顺序,我们通过将Add、Update、Delete、Sync事件排序并增加多优先级队列的方式解决这种异常干扰。 
    增加Secret本地缓存
  • 3、 apiserver优化 
    apiserver的核心是提供类似CRUD的restful接口,优化方向无外乎降低响应时间,减少cpu、内存消耗以提高吞吐量,我们最主要的一个优化是增加以租户ID为过滤条件的查询索引,这样就能实现在租户内跨Namespace聚合查询的效果。另外apiserver的客户端原生的流控策略太暴力,客户端默认在流控被限制后会反复重试,进一步加剧apiserver的压力,我们增加了一种基于反馈的智能重试的策略抹平这种突发流量。
  • 4、Node端优化 
    kube-proxy本来需要控制整个集群负载转发的,Apiserver有了租户查询索引后,我们就能只watch自己租户内的Service/Endpoint,急剧缩小iptables规则数量,提高查找转发效率。而且我们还精简kubelet和kube-proxy内存占用和连接数。

网易云容器服务的其他实践及总结

容器的网络是非常复杂一块,容器云服务至少要提供稳定、灵活、高效的跨主机网络,虽然开源网络实现很多,但是它们要么不支持多租户、要么性能不好,且直接拿没有经过大规模线上考验的开源软件问题总会很多。幸运的时网易云有自己专业的IAAS云网络团队,他们能提供专业级的VPC网络解决方案,天生就支持多租户、安全策略控制和高性能扩展,已经做到容器与虚拟主机的网络是完全互通且地位对等的。

网易云容器服务还在Kubernetes社区版本基础上结合产品需求新增了很多功能,包括支持特有的有状态容器,及Node故障时容器系统目录也能自动迁移以保持数据不变,多副本Pod可按Node的AvailableZone分布强制均衡调度(社区只尽力均衡)、容器垂直扩容、有状态容器动态挂卸载外网IP等。

相比容器的轻量级虚拟化,虚拟机虽然安全级别更高,但是在cpu、磁盘、网络等方面都存在一定的性能损耗,而有些业务却又对性能要求非常高。针对这些特殊需求,最近我们也在开发基于Kubernetes的高性能裸机容器,绕过虚拟机将网络、存储等虚拟化技术直接对接到Docker容器里,在结合SR-IOV网络技术、网易高性能云盘NBS(netease block storage)等技术将虚拟化的性能损耗降到最低。

最后,分享一些网易云容器服务上线近两年来的遇到的比较典型的坑。

  • 1、Apiserver作为集群hub中心本身是无状态的可水平扩展,但是多apiserver读写会在Apiserver切换时可能会出现写入的数据不能立马读到的问题,原因是etcd的raft协议不是所有节点强一致写的。

  • 2、haproxy连接的问题,多Apiserver前用haproxy做负载均衡,haproxy很容易出现客户端端口不够用和连接数过多的问题,可以通过扩大端口范围、增加源ip地址等方式解决端口问题,通过增加client/service的心跳探活解决异常连接GC的问题。

  • 3、用户覆盖更新已有tag的私有容器镜像问题,强烈建议大家不要覆盖已有tag的镜像,也不要使用latest这样模糊的镜像标签,否则RS多Pod副本或者同一个Node上同镜像容器很容易出现版本不一致的诡异问题。

  • 4、有些容器小文件非常多,很容易把inode用光而磁盘空间却剩余很多的问题,建议把这种类型应用调度到inode配置多的node上,另外原生kubelet也存在不会检查inode过多触发镜像回收的问题。

  • 5、有些Pod删除时销毁过慢的问题,Pod支持graceful删除,但是如果容器镜像启动命令写得不好,可能会导致信号丢失不光没法graceful删除还会导致延迟30s的问题

总之,在公有云场景下,用户来源广泛,使用习惯千变万化没法控制,我们已经碰到过很多纯私有云场景下很难出现的问题,如用户镜像跑起不来,Pod多容器端口冲突,日志直接输出到标准输出,或者日志写太快没有切割,甚至把容器磁盘100%写满等,因为篇幅有限,所以只能挑选几个有代表性的专门说明。因为云上要考虑的问题太多,特别是这种基础设施服务类的,使用场景又非常灵活,线上出现的一些问题之前完全想不到,包括很多还是用户自己使用的问题,但为了要让用户有更好的体验,也只能尽力而为,优先选择一些通用的问题去解决。

作者:娄超,网易云容器编排技术负责人。曾经参与淘宝分布式文件系统tfs和阿里云缓存服务研发,2015年加入网易参与网易云容器服务研发,经历网易云基础服务(蜂巢)v1.0,v2.0的容器编排相关的设计和研发工作,并推动网易云内部Kubernetes版本不断升级。 


本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅《程序员》,给我们投稿请联系邮箱weiwei@csdn.net。(责编/魏伟)

欢迎扫描下方二维码,关注CSDN云计算微信,获取更多干货原创内容。

图片描述

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

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

相关文章

c语言程序设计中三子棋游戏,C语言实现简易版三子棋游戏

本文实例为大家共享了C语言实现三子棋游戏的详细代码&#xff0c;供大家参考&#xff0c;详细内容如下什么是多文件&#xff1f;多数大型的工程的头文件和源文件非常多&#xff0c;我们也不可能把所有的代码都写在同一个文件里&#xff0c;这样也不方便代码的阅读与维护&#x…

Rancher创始人谈Docker,创新愈发困难,未来将何去何从?

导读:本文由Rancher Labs CEO及联合创始人梁胜博士在参加DockerCon之前和之后写的两篇文章综合整理而成。从各家容器编排方案均很不成熟的初期到三足鼎立的编排之战&#xff0c;到如今kubernetes似已全面胜利&#xff0c;梁胜博士作为整个发展历程的参与者与见证者&#xff0c;…

ld 指令c语言实现,C语言符号、指令表.doc

C语言符号、指令表.docC语语语 言言言 符符符 号号号 控控控 制制制 命命命 令令令 表表表 编译指令 编译指令 说明 i n c l u d e 包含另一个文件 d e f i n e 定义一个宏( m a c r o)或是常量 u n d e f 取消一个宏常量的定义 a s m 和 e n d a s m 在程序中加入汇编语言的程…

400位京东技术专家心血之作 《决战618:探秘京东技术取胜之道》重磅发售!

6.18始于京东的店庆日&#xff0c;现在早已演变成为全民参与的网购狂欢节。2017年6月18日24点&#xff0c;当京东总部的指挥中心大屏定格在“当前累计下单金额1199亿元”时&#xff0c;欢呼声、掌声响彻整个作战指挥室。在成绩背后&#xff0c;是京东强大的技术硬实力&#xff…

c语言创建一个顺序表主函数,用C语言来创建一个顺序表(数据结构部分)

顺序表的创建需要用到结构体&#xff0c;构造一个结构体来存储数据&#xff0c;顺序表申请的内存是连续的。创建顺序表的思路按照数据的“增删改查来进行编写”下列是顺序表的创建代码创建头文件&#xff1a;sqlist.h#ifndef SQLIST_H#define SQLIST_H#define N 100#define min…

XSS常见攻击与防御

本文获得作者授权刊发&#xff0c;更多信息请关注作者专栏。 XSS攻击全称跨站脚本攻击&#xff0c;是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS&#xff0c;XSS是一种在web应用中的计算机安全漏洞&#xff0c;它允许恶意…

关于c语言的符号常量以下叙述中正确的是,关于C语言的符号常量,以下叙述中正确的是( )...

关于对起的是下列械布重机置的正确认识。标准运用征税国家公布&#xff0c;符号治权征的家凭借政力开税收是国。常量包括专利权的程序授予。现左膝关痛节肿&#xff0c;下叙化验快R增&#xff0c;性A阴&#xff0c;女性&#xff0c;能的最可诊断是&#xff0c;多发口腔溃疡年来…

创业公司的容器化之路

作者简介&#xff1a; 章烨明&#xff0c;杏仁医生CTO。中年程序员&#xff0c;关注各种技术和团队管理。本文首发杏仁医生技术站 1. 创业公司的技术挑战 托尔斯泰说&#xff1a;“幸福的家庭都是相同的&#xff0c;不幸的家庭各有各的不幸。”互联网创业公司也一样。大部分互…

周围剃光头顶留长发型_发型改变气质,这话放在石原里美身上也通用啊

上周&#xff0c;石原里美的新剧《天国餐馆》开播啦。你们有在追吗&#xff1f;她新剧里的发型争议还蛮大。她在剧里演一个法国餐厅老板黑须假名子&#xff0c;非常多这种大背头造型。很多网友觉得不适合她&#xff0c;有点老气。▼这个大背头发型也是角色需要啦&#xff0c;是…

单片机模数转换实验c语言程序,单片机实验AD转换实验

《单片机实验AD转换实验》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《单片机实验AD转换实验(5页珍藏版)》请在人人文库网上搜索。1、实验报告课程名称&#xff1a; 单片机原理及应用 实验项目&#xff1a; A/D转换实验 专业班级&#xff1a; 姓 名&#xff1a; 学…

ServiceComb中的数据最终一致性方案

本文由华为微服务引擎技术团队&&ServiceComb社区授权发布。 数据一致性是构建业务系统需要考虑的重要问题 &#xff0c; 以往我们是依靠数据库来保证数据的一致性。但是在微服务架构以及分布式环境下实现数据一致性是一个很有挑战的的问题。ServiceComb作为开源的微服务…

Rabbitmq延迟队列和惰性队列

延迟队列 当一个队列中的消息满足下列情况之一&#xff0c;可以成为死信&#xff1a; &#xff08;1&#xff09;消费者使用basic.reject或basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false &#xff08;2&#xff09;消息是一个过期消息&#xff0c;超时…

laydate点击输入框闪一下不见了_爱剪辑:如何制作抖音、苹果风格的快闪视频...

不知道大家有没有看过iPhone的宣传片&#xff0c;视频开头有几十秒的快闪字幕&#xff0c;当时视频一出来就有很多剪刀手求教程&#xff0c;因为这个效果不仅酷炫&#xff0c;用途还很广&#xff0c;可以用于&#xff1a;日常生活介绍、产品介绍、搞笑段子......今天就来教大家…

c语言学习与应用 北京邮电大学出版社,《C语言程序设计与应用》低价购书_计算机与互联网_孔网...

c语言是一种简洁高效的编程语言&#xff0c;目前大多数高等院校把它作为学习程序设计的入门语言。本书针对程序设计的初学者&#xff0c;由浅入深、通俗易懂地介绍c语言。本书主要内容包括c语言概述、数据类型和表达式、程序控制结构、数组、函数、高级变量类型与宏定义、文件共…

C++和Lua交互教程(基于LuaBridge)

作者&#xff1a;查志旺 &#xff0c;向日葵远程控制软件前端开发工程师。 最近公司需要做向日葵远程控制软件跨平台项目&#xff0c;为了代码的可复用性&#xff0c;需嵌入跨平台脚本语言&#xff0c;我们选择了Lua&#xff0c;理由是Lua由标准C编写而成&#xff0c;几乎在所有…

c语言100000阶乘,求10000的阶乘(c语言代码实现)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*程序功能&#xff1a;计算一个正整数n的阶乘&#xff0c;目前最大能运算10000的阶乘&#xff0c;可秒杀。程序意义&#xff1a;加强自己对于大数的处理。说明&#xff1a;此程序对乘法和除法还未做任何优化&#xff0c;如果用上位…

ogg批量配置_最简单OGG配置方式

ogg一般来说有4个进程&#xff0c;Manager进程&#xff0c;Extract进程&#xff0c;Pump进程&#xff0c;Replicat进程Manager进程&#xff1a;是GoldenGate的控制进程&#xff0c;它主要作用有以下几个方面&#xff1a;启动、监控、重启GoldenGate的其他进程&#xff0c;报告错…

与Serverless 的第一次亲密接触

Servrless概念 Serverless 是一个架构上的概念&#xff0c;从字面上理解就是无服务器架构。Serverless最初是用于描述依赖第三方服务实现对逻辑和状态进行管理的应用&#xff0c;典型的例子是单页 Web 和移动 App 这种富客户端应用&#xff0c;他们一般都使用基于云端的数据库…

eclipse把tomcant用到一个项目里_聊一个镜头工艺里容易被忽略,但很重要的项目...

在不改换门庭的情况下&#xff0c;一颗镜头一般都会伴随大家使用很长一段时间&#xff0c;也相信大多数人都遇到过剐蹭镜头前组的情况&#xff0c;这时候最容易引发的担忧就是“伤着镀膜了么&#xff1f;会不会影响成像效果&#xff1f;”其实换个角度来看&#xff0c;这个问题…

c语言中词法分析怎么识别注释,C语言中的词法分析-如何在检测多行注释时使星号被读取并输出?...

我正在研究词法分析程序&#xff0c;检测到一行注释时一切正常。 这是我的单行注释检测代码。//Single Commentif ((Current_Character /) && (fgetc(File_Input) /)){printf("%c", Current_Character);do{printf ("%c", Current_Character);Cur…