简介:本文经过一个业务发展的故事,分享 K8s 出现的缘由以及它的运做方式。适合全部技术开发人员,尤为是前端开发者。前端
去年下半年,我作了一次转岗,开始接触到 kubernetes,虽然对 K8s 的认识还很是的不全面,可是很是想分享一下本身的一些收获,但愿经过本文可以帮助你们对 K8s 有一个入门的了解。文中有不对的地方,还请各位老司机们帮助指点纠正。linux
其实介绍 K8s 的文章,网上一搜一大把,并且 kubernetes 官方文档也写的很是友好,因此直接上来说 K8s,我以为我是远远不如网上的一些文章讲的好的,因此我想换一个角度,经过一个业务发展的故事,来说一下 K8s 是怎么出现的,它又是如何运做的。web
本文适合全部搞技术的同窗,特别是前端的同窗,由于前端工程化近几年发展的很是迅猛,K8s 目前解决的问题和发展的形式,我相信假以时日也会出如今前端领域,毕竟不一样领域的工程化发展实际上是异曲同工的。docker
随着中国老百姓生活水平的不断提升,家家户户都有了小汽车,小王预计 5 年后,汽车报废业务将会迅速发展,并且国家在 19 年也出台了新政策《报废机动车回收管理办法》,取消了汽车报废回收的“特种行业”属性,将开放市场化的竞争。前端工程化
小王以为这是一个创业的好机会,因而找到了我和几个志同道合的小伙伴开始了创业,决定作一个叫“淘车网”的平台。api
淘车网一开始是一个 all in one 的 Java 应用,部署在一台物理机上(小王同窗,如今都啥时候了,你须要了解一下阿里云),随着业务的发展,发现机器已经快扛不住了,就赶忙对服务器的规格作了升级,从 64C256G 一路升到了 160C1920G,虽然成本高了点,可是系统至少没出问题。服务器
业务发展了一年后,160C1920G 也扛不住了,不得不进行服务化拆分、分布式改造了。为了解决分布式改造过程当中的各类问题,引入了一系列的中间件,相似 hsf、tddl、tair、diamond、metaq 这些,在艰难的业务架构改造后,咱们成功的把 all in one 的 Java 应用拆分红了多个小应用,重走了一遍阿里当年中间件发展和去 IOE 的道路。网络
分布式改完了后,咱们管理的服务器又多起来了,不一样批次的服务器,硬件规格、操做系统版本等等都不尽相同,因而应用运行和运维的各类问题就出来了。架构
还好有虚拟机技术,把底层各类硬件和软件的差别,经过虚拟化技术都给屏蔽掉啦,虽然硬件不一样,可是对于应用来讲,看到的都是同样的啦,可是虚拟化又产生了很大的性能开销。less
恩,不如咱们使用 docker 吧,由于 docker 基于 cgroup 等 linux 的原生技术,在屏蔽底层差别的同时,也没有明显的性能影响,真是一个好东西。并且基于 docker 镜像的业务交付,使得咱们 CI/CD 的运做也很是的容易啦。
不过随着 docker 容器数量的增加,咱们又不得不面对新的难题,就是大量的 docker 如何调度、通讯呢?毕竟随着业务发展,淘车网已经不是一个小公司了,咱们运行着几千个 docker 容器,而且按照如今的业务发展趋势,立刻就要破万了。
不行,咱们必定要作一个系统,这个系统可以自动的管理服务器(好比是否是健康啊,剩下多少内存和 CPU 可使用啊等等)、而后根据容器声明所需的 CPU 和 memory 选择最优的服务器进行容器的建立,而且还要可以控制容器和容器之间的通讯(好比说某个部门的内部服务,固然不但愿其余部门的容器也可以访问)。
咱们给这个系统取一个名字,就叫作容器编排系统吧。
那么问题来了,面对一堆的服务器,咱们要怎么实现一个容器编排系统呢?
先假设咱们已经实现了这个编排系统,那么咱们的服务器就会有一部分会用来运行这个编排系统,剩下的服务器用来运行咱们的业务容器,咱们把运行编排系统的服务器叫作 master 节点,把运行业务容器的服务器叫作 worker 节点。
既然 master 节点负责管理服务器集群,那它就必需要提供出相关的管理接口,一个是方便运维管理员对集群进行相关的操做,另外一个就是负责和 worker 节点进行交互,好比进行资源的分配、网络的管理等。
咱们把 master 上提供管理接口的组件称为 kube apiserver,对应的还须要两个用于和 api server 交互的客户端,一个是提供给集群的运维管理员使用的,咱们称为 kubectl;一个是提供给 worker 节点使用的,咱们称为 kubelet。
如今集群的运维管理员、master 节点、worker 节点已经能够彼此间进行交互了,好比说运维管理员经过 kubectl 向 master 下发一个命令,“用淘车网用户中心 2.0 版本的镜像建立 1000个 容器”,master 收到了这个请求以后,就要根据集群里面 worker 节点的资源信息进行一个计算调度,算出来这 1000 个容器应该在哪些 worker 上进行建立,而后把建立指令下发到相应的 worker 上。咱们把这个负责调度的组件称为 kube scheduler。
那 master 又是怎么知道各个 worker 上的资源消耗和容器的运行状况的呢?这个简单,咱们能够经过 worker 上的 kubelet 周期性的主动上报节点资源和容器运行的状况,而后 master 把这个数据存储下来,后面就能够用来作调度和容器的管理使用了。至于数据怎么存储,咱们能够写文件、写 db 等等,不过有一个开源的存储系统叫 etcd,知足咱们对于数据一致性和高可用的要求,同时安装简单、性能又好,咱们就选 etcd 吧。
如今咱们已经有了全部 worker 节点和容器运行的数据,咱们能够作的事情就很是多了。好比前面所说的,咱们使用淘车网用户中心 2.0 版本的镜像建立了 1000 个容器,其中有5个容器都是运行在 A 这个 worker 节点上,那若是 A 这个节点忽然出现了硬件故障,致使节点不可用了,这个时候 master 就要把 A 从可用 worker 节点中摘除掉,而且还须要把原先运行在这个节点上的 5 个用户中心 2.0 的容器从新调度到其余可用的 worker 节点上,使得咱们用户中心 2.0 的容器数量可以从新恢复到 1000 个,而且还须要对相关的容器进行网络通讯配置的调整,使得容器间的通讯仍是正常的。咱们把这一系列的组件称为控制器,好比节点控制器、副本控制器、端点控制器等等,而且为这些控制器提供一个统一的运行组件,称为控制器管理器(kube-controller-manager)。
那 master 又该如何实现和管理容器间的网络通讯呢?首先每一个容器确定须要有一个惟一的 ip 地址,经过这个 ip 地址就能够互相通讯了,可是彼此通讯的容器有可能运行在不一样的 worker 节点上,这就涉及到 worker 节点间的网络通讯,所以每一个 worker 节点还须要有一个惟一的 ip 地址,可是容器间通讯都是经过容器 ip 进行的,容器并不感知 worker 节点的 ip 地址,所以在 worker 节点上须要有容器 ip 的路由转发信息,咱们能够经过 iptables、ipvs 等技术来实现。那若是容器 ip 变化了,或者容器数量变化了,这个时候相关的 iptables、ipvs 的配置就须要跟着进行调整,因此在 worker 节点上咱们须要一个专门负责监听并调整路由转发配置的组件,咱们把这个组件称为 kube proxy(此处为了便于理解,就不展开引入 Service 的内容了)。
咱们已经解决了容器间的网络通讯,可是在咱们编码的时候,咱们但愿的是经过域名或者 vip 等方式来调用一个服务,而不是经过一个可能随时会变化的容器 ip。所以咱们须要在容器 ip 之上在封装出一个 Service 的概念,这个 Service 能够是一个集群的 vip,也能够是一个集群的域名,为此咱们还须要一个集群内部的 DNS 域名解析服务。
另外虽然咱们已经有了 kubectl,能够很愉快的和 master 进行交互了,可是若是有一个 web 的管理界面,这确定是一个更好的事情。此处以外,咱们可能还但愿看到容器的资源信息、整个集群相关组件的运行日志等等。
像 DNS、web 管理界面、容器资源信息、集群日志,这些能够改善咱们使用体验的组件,咱们统称为插件。
至此,咱们已经成功构建了一个容器编排系统,咱们来简单总结下上面提到的各个组成部分:
这些也正是 K8s 中的重要组成部分。固然 K8s 做为一个生产级别的容器编排系统,这里提到的每个组件均可以拿出来单独讲上不少内容,本文只是一个简单入门,再也不展开讲解。
虽然咱们已经成功实现了一个容器编排系统,而且也用的很舒服,可是淘车网的王总裁(已经不是当年的小王了)以为公司花在这个编排系统上的研发和运维成本实在是过高了,想要缩减这方面的成本。王总想着有没有一个编排系统,可以让员工专一到业务开发上,而不须要关注到集群的运维管理上,王总和技术圈的同窗了解了一下,发现 Serverless 的理念和他的想法不谋而合,因而就在想啥时候出一个 Serverless 的容器编排系统就好啦。
Serverless 的容器编排系统须要怎么实现呢?欢迎你们在评论区给王总出谋划策~