尘埃落定-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节点,它们运行的载体是物理机或者虚拟机,为了方便理解,可以认为一个节点对应一台物理机.
- kubelet组件, 它可以
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系统的设计和经验, 可以说是站在巨人肩膀上, 而且这些特性借助于开源社区的力量,变得越来越好.