尘埃落定-k8s

K8s已经成为了容器编排的事实标准。k8s一路走来也有些曲折,但最终笑傲群雄。它这一路走来发生了哪些恩怨情仇呢?

  • 背景
  • 什么是k8s?
  • 为什么是它?
  • k8s底层是如何实现的?
  • k8s生态及相关

背景


想起多年前在上家公司,如果要发布一个功能,得是运维人员先停止服务,然后手动拷贝文件到服务器上,再启动服务,这个过程是纯手工操作,在那时看起来也很自然。在那个时候流行的是在aws或者Openstack上租一台虚拟机,然后通过手动或者脚本的方式来部署程序,这里会遇到一些问题,比如云上的环境和本地环境的不一致,所以云服务厂商比拼的就是谁的环境更能模拟本地环境。

Cloud Foundry

随着Cloud Foundry的出现,部署的方式稍微有点变化,对于用户来说,只需要将程序打包成它规定的格式,上传上去就好了,Cloud Foundry会调度一个虚拟机来执行这个程序。这个时候会遇到一种情况,如果这个虚拟机执行很多程序会不会导致程序之间会有冲突?不会,Cloud Foundry会为每个应用创建隔离环境. 这一切听起来不错.

Docker

再后来Docker出现了,现在我们知道,Docker也是为应用创建隔离环境,看上去Docker不必Cloud Foundry高明多少啊。但Docker杀手锏是镜像,镜像意味着无论什么应用都遵循统一的格式和规范, 更关键的是镜像包含了应用所有的依赖,而Cloud Foundry则需要为不同的应用生产不同格式的包,比较繁琐. 在这个时候, Cloud Foundry并没有拥抱Docker作为自己打包的标准,失去了一次战略先机.
Docker虽然可以提供标准格式的包,但它没有部署复杂应用的能力,因为Docker本质还是一个工具.于是在2014年底, Docker公司推出了自己的容器集群管理工具Swarm,打造一套以容器为核心的Paas, 并形成Docker自己的生态.

Mesos

Docker此时有个竞争对手叫Mesos, Mesos有个独特的杀手锏就是超大规模的集群管理能力,有超过10000个节点成功案例,而且支持Docker容器部署。
现在看起来,两强相争似乎成了基本盘。

Kubernetes

但在2014年出现了一个叫Kubernetes的东西. Google, RedHat等基础设施大佬们成立一个名为CNCF的基金会,专门来对抗以Docker为核心的生态的。
所以现在是生态和生态之间的对抗,而不是工具和工具之间的小打小闹。那么K8s是如何破局的呢?

k8s面临的困境

  • 对于Docker生态来说, Swarm和它的配合可以说是如丝滑般的顺畅
  • 对于Mesos来说,它的特长是大规模集群调度.

k8s的突围之道

很明显,如果模仿Docker或者Mesos,任意一条路都是走不通的. 那么k8s只有两个方向了

  • 融合Docker和Mesos的优点
  • 单独开创一个局面
    K8s选择的是单独开创一个局面:容器编排,并且要在这个领域取得压倒性的优势,并形成降维打击.

什么是k8s?

k8s是什么?

正如背景里面所描述的,k8s是一个容器编排的工具. 所以

  • 它本质是个工具
  • 它处理的实体的是容器,这个容器不一定是Docker,说不定将来出来了一个Eocker.
  • 它的重心是编排,有点类似于NBA里面教练对球员的排兵布阵.它提供了一种通用的方式来定义任务之间的关系,并为未来可能存在的新的任务关系提供可扩展性。直白一点,这个世界上所有的任务关系都应该在k8s的掌握之中.
    • 从抽象的角度来说,一个集合里面由很多元素,编排意味着,要将这些集合分组,可以定义组和组之间的关系,可以定义组内元素之间的关系,可以定义跨组元素之间的关系。
    • 从实践的角度来看,编排意味着
      • 如果一个服务的访问量过大,如何扩展服务的实例
      • 如何限流
      • 如何保证服务只被合法的用户访问
      • 如何合理分配流量到不同的服务实例
      • 如何知道服务之间的调用链
      • 如何实现服务之间的启动顺序?

切入k8s的一种角度

从宏观的角度来看,K8s有两种角色

  • Master节点 - k8s的大脑,类似于球队的管理层和决策层.
    • kube-apiserver
    • kube-scheduler
    • kube-controller-manager
  • Node节点 - k8s任务的执行者。
    • kubelet组件, 它可以
      • 通过CRI同容器运行时打交道,CRI请求会被转换成Linux系统调用
      • 和设备插件打交道,比如GPU
      • 和网络插件和存储插件打交道
        不管是Master节点还是Node节点,它们运行的载体是物理机或者虚拟机,为了方便理解,可以认为一个节点对应一台物理机.

k8s的核心概念

  • Pod - 对于K8s来说, Pod是最小的执行单元,是对容器的抽象和封装.正如研究动植物一样,细胞是最小的单元。一个最小的Pod就是只包含一个容器镜像。也可以认为Pod是k8s的一等公民
    • 必要性 - 有些应用之间需要通过本地文件交互信息,或者交互很频繁,需要通过LocalHost来通信。在正常情况下,这些应用(进程或者进程组)会被部署在同一台机器上. 容器本身没有管理多个进程的能力, 回到k8s身上, k8s也需要解决这些问题,所以Pod这个概念应运而生,最复杂的Pod应该是很多应用在一起, 所以Pod可以看作是一个逻辑实体.
    • 临时性 - Pod的地址是临时的,但在相应的的物理机或者虚拟上的网卡可以找到这个地址.
  • Deployment - 一个应用看作是一个实例,那么Deployment可以让Pod有多个实例.
    • Deployment和Pod从设计的角度是一种API对象,Depoyment用来管理Pod。一种API对象来管理另外一种API对象,在K8s里称之为控制器模式.
    • Deployment是让Pod活跃起来的一个API对象,其他对象没有这个功能.
    • Deployment隐含里水平扩展和收缩的功能.
    • 正常Deployment的定义包含两部分
      • Pod副本的数量 - spec.replicas
      • Pod的描述 - spec.template
    • 对于一些特殊的应用比如Sticky Session, 需要自定义Deployment
  • ReplicaSet - Deployment是通过ReplicaSet来控制Pod的.
    • ReplicaSet定义了Pod的数量
    • Deployment控制了ReplicaSet的个数
  • Service - 由于Pod每次启动之后,IP地址都会变化,这样就导致了Pod之间相互通信很困难,必须有一个东西来解决这个问题,Service这个概念应用而生,它代表的是稳定的地址和端口.
    • 一个Service可以对应多个Pod,所以Service需要有负载均衡的能力.
  • Ingress - Service在默认情况下,只能在k8s集群内被访问,如果想要让外网可以访问service,就需要做有些额外的事情, Ingress就是干这个的.
  • Secret - PodA 访问 PodB 需要带上用户名和密码,那么这些用户名和密码就放在Secret对象里,这个对象本质上ETCD里的一条记录.

为什么是它?

K8s能成为容器编排领域的事实标准,与它的正确的战略定位分不开,也与它本身自带“贵族气质”有关.
K8s每一个核心特性的推出,都来自于Borg/Omega系统的设计和经验, 可以说是站在巨人肩膀上, 而且这些特性借助于开源社区的力量,变得越来越好.

k8s底层是如何实现的?

k8s生态及相关