Kubernetes 在知乎的应用

本文讲的是Kubernetes 在知乎的应用【编者的话】知乎在 2014 年开始使用容器技术,至今为止几乎所有的业务都运行在容器平台上。知乎最初使用 Mesos 来管理容器集群,现在正处于向 Kubernetes 迁移的过程中。本次分享主要介绍知乎应用 Kubernetes 管理容器集群的一些经验。 

【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

从 Mesos 到 Kubernetes

之前的调度框架是基于 Mesos 自研的。采用的语言是 Python。运行了大概两年多的时间了,也一直比较稳定。但随着业务的增长,现有的框架的问题逐渐暴露。

  1. 调度速度遇到瓶颈,影响大业务的部署速度。
  2. 不能很好的支持有状态服务。

解决上述问题的方案有两个,一个是对现有系统进行改进重构,另一个是迁移到 Kubernetes。我们最终选择迁移到 Kubernetes,主要基于以下考虑。

  1. Kubernetes 的架构设计简单明了,容器管理的抽像做的很好,重易进行复用和二次开发,没有必要造重复的轮子。比较典型的像Pod、Mesos 也已经引进了类似概念。
  2. Kubernetes 已经逐渐成为业界主流。社区很活跃,新的特性不断地被添加进来,这导致 Kubernetes 变的越来越重,但基本的架构和核心功能是一直比较稳定的。
  3. 相对于 Mesos 来讲,基于 Kubernetes 的开发成本是要低一些的,尤其是在熟悉之后。便于 k8s 的推广使用。除了主要的业务运行平台 bay,我们的负载均衡平台、Kafka 平台以及定时任务平台全部都是基本 Kubernetes 的。

整体架构

资源层

这一层主要是集群资源,主要包括内存、CPU、存储、网络等。主要运行的组件有 Docker daemon、kubelet、cAdvisor、CNI 网络插件等,主要为上层提供资源。

控制层(Kubernetes master)

控制层主要包括 Kubernetes 的 master 组件,Scheduler、Controller、API Server。提供对 Kubernetes 集群资源的控制。

接入层(Watch Service、API)

这一层包含的东西比较多,主要包含各个平台用于接入 Kubernetes 集群所开发的组件。主要包含以下组件:

  1. 容器平台 bay 。
    一是用来向部署系统提供容器/容器组的创建、更新、删除、扩容等接口,是对 Kubernetes 原生 API 的一层封装,主要是为了与部署系统对接。二是用来注册服务发现、业务监控报警等所需要的配置。
  2. 负载均衡平台(Load Balance)。
    我们的负载均衡平台采用的主要是 Haproxy。也是跑在容器里的。由于负载均衡系统的特殊性,并没有跑在容器平台 bay 上面,而是单独开发了一个平台对 HAProxy 进行管理。可以方便的创建和管理 HAProxy 集群,并在业务流量发生变化的时候进行自动或者手动扩容。
  3. Kafka 平台(Kafka)。 主要提供在 Kubernetes 上创建管理 Kafka 集群的服务。我们在 Kubernetes 之上开发了一套基于本地磁盘的调度框架,可以使 pod 根据集群中的本地磁盘信息进行调度。没有使用共享存储系统主要是为了性能考虑。最新的 Kubernetes 好像也加入了类似本地磁盘的调度特性,不过在我们开发的时候是还没有支持的。
  4. 定时任务平台。
    这个平台是在 Kubernetes 支持 Cron job 之前开发的。也是最早接入 Kubernetes 的服务。

管理层(Castle Black;Monitor;Auto Scale)

主要是根据接入层提供的一些配置或者信息来完成特定的功能。

  1. Castle Black,这个服务是一个比较关键的服务。这个服务通过 Kubernetes 的 watch API,及时的同步业务容器的信息,根据容器信息进行服务注册和反注册。我们主要是注册 Consul 和 DNS。Kafka 平台和负载均衡平台也依赖于这个服务进行服务注册。同时对外提供查询接口,可以查询业务的实时容器信息。
  2. Monitor,这个主要是业务容器的监控,主要包含该业务总容器数、不正常容器数以及注册信息是否一致等信息,CPU 和内存等资源的监控我们采用 cAdvisor 和我们内部的监控系统来实现。
  3. Auto Scale,我们没有使用 Kubernetes 本身的自动扩容机制,而是单独进行了开发,主要是为了支持更加灵活的扩容策略。

配置层(etcd)

应用层的组件所需要的配置信息全部由接入层的服务写入到 etcd 中。应用层组件通过 watch etcd 来及时获取配置的更新。

下面这张图说明了在我们的容器平台上,上面描述的一些组件是如何结合在一起,使业务可以对外提供服务的。通过 bay 平台向 Kubernetes APIServer发送请求,创建 deployment,pod 创建成功并且健康检查通过后,Castle Black watch 到 pod 信息,将 IP,port 等信息注册到 Consul 上,HAProxy watch 对应的 Consul key,将 pod 加入其后端列表,并对外提供服务。

监控与报警

cAdvisor

我们的监控指标的收集主要是采用 CAvisor。没有采用 Heapster 的主要原因有以下几点:

  1. 针对 CAvisor 我们进行了二次开发,与内部指标系统结合的也比较好,应用的时间也较长。
  2. Heapster 采用 pull 模型,虽然是并行 pull,但在集群规模较大的情况下,有成为性能瓶颈的可能,而且目前无法进行横向扩展。
  3. Heapster 中默认提供的很多聚合指标我们是不需要的。也没有维护两个监控系统的必要。

内部指标与报警系统

指标和报警都是用的我们内部比较成熟的系统。

日志收集

Logspout Kafka ES/HDFS,日志收集我们使用的也是 ELK,但跟通常的 ELK 有所不同。我们这里的 L 用的是 Logspout,一个主要用于收集容器日志的开源软件。我们对其进行了二次开发,使之可以支持动态 topic 收集。我们通过环境变量的形式把 topic 注入到容器中。logspout 会自动发现这个容器并提取出 topic,将该容器的日志发送到 Kafka 对应的 topic 上。因此我们每个业务日志都有自己的 topic,而不是打到一个大的 topic 里面。日志打到 Kafka 里之后,会有相应的 consumer 消费日志,落地 ES 和 HDFS。ES 主要用来作日志查询,HDFS 主要用来做日志备份。 

整个日志收集流程如下图所求:

网络方案

CNI Bridge host-local,网络部分我们做的比较简单。首先我们的每个主机都给分配了一个 C 段的 IP 池,这个地址段里的每个 IP 都是可以跨主机路由的。IP 地址从 X.X.X.2 到 X.X.X.255,容器可以使用的地址是 X.X.X.3 到 X.X.X.224,这个 IP 数量是足够的。然后在主机上创建一个该地址段的 Linux Bridge。容器的 IP 就从 X.X.X.3 到 X.X.X.224 这个地址空间内分配,容器的 veth pair 的一段挂在 Linux Bridge 上,通过 Linux Brigde 进行跨主机通信。性能方面基本没有损耗。 

具体的实现我们采用了 Bridge 和 host-local 这两个 CNI 插件,Bridge 主要用来挂载/卸载容器的 veth pair 到 Linux Bridge 上,host-local 主要利用本地的配置来给容器分配 IP。 

上述流程如下图所示:

IP 池的分配由我们的云服务商提供,我们不需要管具体的 IP 池的分配与路由配置。

上面主要介绍了知乎在容器和 Kubernetes 应用的一些现状,在这个过程中我们也踩了不少坑,在这里与大家分享一下。 

etcdv3 版本问题

Kubernetes 的较新版本默认使用的存储后端是 etcd3。etcd 选用的版本不对,是会有坑的。etcd 3.10 之前的版本,V3 的 delete api 默认是不会返回被删除的 value 的。导致 Kubernetes API server 会收不到 delete event。被占用的资源会得不到释放。最终导致资源耗尽。scheduler 无法再调度任何任务。详细信息可以看这个 issue(https://github.com/coreos/etcd/issues/4620)。

Pod Eviction

这个是 Kubernetes 的一个特性,如果由于网络或者机器原因,node 离线了,变为 unready 状态。Kubernetes 的 node controller 会将该 node 上的 pod 删除,称作 pod eviction。这个特性应该说是合理的,但在大概是 1.5 版本之前,当集群中所有的 node 都变为 unready 状态的时候,所有 node 上的 pod 都会被删除。这个其实是不合理的,因为出现这种情况大概率是 API Server 的机器网络出了问题,所以这个时候不应该把所有 node 上的 pod 全部删除。最新的版本将这个特性进行了改进,集群中 ready 的 node 达到一定数量的情况下,才对 not ready 的 node 进行 pod eviction。这个就比较合理了。另外提醒大家一定要做好 API Server 的高可用。

CNI 插件 Docker daemon 重启 IP 泄露

在使用 CNI 网络插件的时候,如果 Docker daemon 发生了重启,会重新分配新的 IP,但旧的 IP 不会被释放,会导致 IP 地址的泄漏。由于时间和精力问题,我们采取了比较 tricky 的方式,在 Docker dameon 启动之前,我们会默认把本机的 IP 全部释放掉。这个是通过 Supervisor 的启动脚本来实现的。希望后续 Kubernetes 社区可以从根本上解决这个问题。

Docker bug

Docker 使用过程中也遇到了一些 bug。比如 docker ps 会卡住, 使用 portmapping 会遇到端口泄漏的问题等。我们内部自己维护了一个分支,修复了类似的问题。Docker daemon 是基础,它的稳定性一定要有保证,整个系统的稳定性才有保证。

Rate Limit

Kubernetes 的 Controller manager、Scheduler、以及 API Server 都是有默认的 rate limit 的,在集群规模较大的时候,默认的 rate limit 肯定是不够用的,需要自己进行调整。

作者简介:王路,容器开发工程师,主要负责知乎容器平台的开发和运维工作。

原文发布时间为:2017-08-06

本文作者:王路

本文来自合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:Kubernetes 在知乎的应用

时间: 2024-09-12 19:51:54

Kubernetes 在知乎的应用的相关文章

使用Kubernetes,你应该知道的

本文讲的是使用Kubernetes,你应该知道的[编者的话]这是一篇介绍Kubernetes优势.局限性和路线图的文章. [深入浅出学习 etcd]etcd为分布式系统提供可靠.高效的配置管理服务,在Docker.Kubernetes.Mesos等平台中扮演了越来越重要的角色.作为2013年开始的项目,它还很年轻,官方文档中缺乏实现上全面.系统的介绍,本课程深入浅出地介绍了etcd的实现,并为运维和二次开发提供了系统的指导和建议. Kubernetes在容器编排和云原生应用管理上被普遍使用.与其

DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证

本文讲的是DockOne微信分享(一四三):FreeWheel基于Kubernetes容器云构建与实践:应用编排与服务质量保证[编者的话]随着公司业务不断发展以及逐渐向微服务的转变,我们借助于Kubernetes容器化解决方案来标准化和简化应用发布的整个流程,使原来需要大量人工维护和干预的工作变为自动化.本次内容主要是FreeWheel现阶段基于Kubernetes容器化经验和实践的总结,目标是提供一个持续.稳定.高效的容器云平台. 服务健康检查与自我恢复 对线上业务来说,保证服务的正常稳定是重

Java微服务开发指南 -- 使用Docker和Kubernetes构建可伸缩的微服务

使用Docker和Kubernetes构建可伸缩的微服务     从现在开始,我们将从更高的维度讨论微服务,涵盖了组织敏捷性.设计和依赖的思考.领域驱动设计以及Promise理论.当我们深入使用之前介绍的三个流行的微服务框架:Spring Boot.Dropwizard和WildFly Swarm,我们能够使用它们开箱即用的能力去构建一个暴露或者消费REST服务的应用,能够使用外部环境对应用进行配置,可以打包成一个可执行的jar,同时提供Metrics信息,但这些都是围绕着一个微服务实例.当我们

Kubernetes管理Docker集群之部署篇

什么是Kubernetes? Kubernetes是Google开源的容器集群管理系统,实现基于Docker构建容器,利用Kubernetes能很方面管理多台Docker主机中的容器. 主要功能如下: 1)将多台Docker主机抽象为一个资源,以集群方式管理容器,包括任务调度.资源管理.弹性伸缩.滚动升级等功能. 2)使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题 3)自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭

Kubernetes之服务质量保证(QoS)

本文讲的是Kubernetes之服务质量保证(QoS)[编者的话]Kubernetes做为目前主流的容器集群管理平台,需要整体统筹平台资源使用情况.公平合理的将资源分配给相关pod容器使用,并且要保证容器生命周期内有足够的资源来保证其运行. 与此同时,由于资源发放的独占性,即资源已经分配给了某容器,同样的资源不会在分配给其他容器,对于资源利用率相对较低的容器来说,占用资源却没有实际使用(比如CPU.内存)造成了严重的资源浪费,Kubernetes需从优先级与公平性等角度提高资源的利用率.为了实现

Docker Swarm和Kubernetes在大规模集群中的性能比较

本文讲的是Docker Swarm和Kubernetes在大规模集群中的性能比较,[编者的话]本文建立了一套通用测评工具,通过容器启动时延等指标测评Swarm和Kubernetes在大规模部署下的性能表现,分析结果认为Swarm比Kubernetes的性能好.此外还提供了详尽的测试数据, 供应用者参考. 这篇文章主要针对Docker Swarm和Kubernetes在大规模部署的条件下的3个问题展开讨论.在大规模部署下,它们的性能如何?它们是否可以被批量操作?需要采取何种措施来支持他们的大规模部

Kubernetes管理:看看EBay的蜜汁配方

世界最大企业之一的EBay公司计划在下个季度为OpenStack和Kubernetes管理向开源社区提供其方案. 电子商务巨头eBay公司拥有着世界最大OpenStack私有云中的一个.自从2015年以来,公司已经将Kubernetes容器编排与管理推广至拥有六个可用区域22,000个CPU内核的应用场景中,以便支持178个应用程序,其中包括了Elasticsearch搜索引擎.Apache Kafka分布式流量控制与人工智能(AI)平台. 为了逐步实现其计划,eBay公司的工程师们开发了专门的

Google Kubernetes设计文档之安全篇

[编者按]Kubernetes是Google开源的容器集群管理系统.它构建于Docker技术之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台.为帮助国内开发者了解Kubernetes技术,CSDN联合浙江大学SEL实验室共同翻译Kubernetes的系列设计文档,本文为系列的第一篇:安全. 设计目标 本文讲述了Kubernetes的容器.API和基础设施在安全方面的设计原则. 保证容器与其运行的宿主机之间有明确的隔离:

【Container讲师】CoreOS+Kubernetes搭建Docker运行环境

2014年10月18日,CSDN&<程序员>主办的2014 Container技术大会(Container Conference 2014)将在北京召开,国内外Container技术人员和企业实践用户将首次齐聚北京.Docker.Google Kubernetes.VMware.CoreOS.国内互联网企业及初创技术团队的Container技术专家及一线开发者将分享他们在生产环境中的Container项目经验和最佳实践方案. 我们特别邀请到北京数字睿博科技发展有限公司创始人桂阳.他在2