go语言
k8s的源码托管在GitHub上
Pass 云计算的平台级服务
红帽内部平台级服务产品叫openshift,而openshitf的核心就是k8s
K8s可以:
1、自动装箱
2、自我修复
3、水平扩展
4、服务发现和负载均衡
5、自动发布和回滚
6、密钥和配置管理
7、存储编排
8、批量处理执行
当一个容器出现问题的时候,直接kill掉,重新创建,这样实现修复
======================================
K8s从运维角度来讲其实就是一个集群,组合多台主机的资源整合成一个大的资源池,并统一对外提供计算、存储等能力的集群
这个就是把多个主机当一个主机来使用,前提是分别在多个主机上安装k8s的相关的应用程序,让大家在这个级别上完成通信从而完成彼此之间的协调
但是在k8s中主机是分角色的,大家知道集群有常用的两种模型:
1、p2p 没有中心节点,每一个节点本身都可以接受服务请求,能路由请求的那种模型
2、有中心节点的集群,像mysql的主从复制,有一个是主节点,其它都跟着同步
k8s就是一个有中心节点架构的集群
K8s架构的特点:
Master:
一般两三个就可以了,因为他们彼此之间需要做高可用,Master是整个集群的唯一路口
各nodes:
每个都是来贡献一部分计算能力,说白了他们就是用来运行容器的节点
用户怎么在这个集群中运行容器呢?
客户端请求要先发给Master,把创建、启动容器的请求交给Master,Master当中有一个调度器,去分析现有的各nodes的资源状态,找一个最佳适配运行用户请求的容器的节点,并把它调度上去,由这个node本地的或其他容器引擎负责把这个容器启动起来
要启动容器是不是需要用到镜像?镜像在何处?DockerHub或者私有仓库当中,如果用户请求在本地中找不到镜像就会从DockerHub和私有仓库中拖下来并创建运行
镜像本身可以是在容器中,所以我们完全可以吧仓库托管在k8s自身上了
接收请求的刚才讲到是k8s Cluster,大家知道,提供服务能让客户端远程访问到,需要一个套接字向外提供,而套接字对外提供服务一般都是API接口,所以我们客户端要么通过编程访问要么通过专门编好的客户端程序
k8s的的确确就把Master上的组件称为叫做API Server
Master负责接收、解析、处理请求
K8s中的调度器叫做scheduler,他负责去观测每一个node之上总共可用的资源量,cpu、mem、
===============
K8S通过两级的方式调度:
第一步:先做预选 看看节点中有多少个容器是符合需求的,比如共有十个,筛选后发现只有三个符合要求
第二步:优选 取决于优先的算法来决定
在node上装有keepalived应用程序,负责检查容器的健康运行状态的,问题来了,万一我们在某个node上运行起来了,万一此容器挂了,那么托管在本容器的其他容器就没了,但是K8S有自愈能力,它会在其他节点上创建出一模一样的容器,那么问题是如何确保该容器是健康的,怎么才能知道它是故障的,是不是需要持续监控着它们,所以K8S上实现了一大堆叫控制器的应用程序,让你负责去监控它所管理的每一个容器是否是健康的,一旦发现不健康,控制器就负责想MasterAPI Server发送请求,说我的容器挂了一个,然后调度重新启动一个,因此Master有个组件叫控制器,这个控制器要在本地不停地loop(循环),周期性探测
如果负责健康检查的控制器出问题了那么怎么办?答:在master上做第三个组件,非常重要的组件叫 负责检查每个控制器是否健康,那么有人想到了,如果控制器管理器也挂了呢?答:在控制器管理级别做冗余?怎么做?别忘了Master可以有很多个节点,它们之间是冗余关系,每个Master节点上都有控制器管理器,万一哪个Master挂了其它Master节点可以顶替上来的
总结:K8S有三个重要的组件:
1、API Server 负责响应客户端(接收和处理请求)
2、Scheduler 调度容器容器创建的请求
3、控制器管理器,确保控制器是否健康,而控制器确保创建的容器处于健康运行状态
补充:K8S支持众多的控制器,控制容器健康的只是其中一种,它还有很多其它的控制器
另外:我们以后在K8S之上就不能再这么称呼容器了,因为在K8S上最小运行的单元是不是容器,而是pod,K8S调度的目标是pod,可以把它理解为容器的外壳,给容器作为一种抽象的封装,pod便成了K8S系统之上最小的调度的逻辑单元,pod内部主要是用来存放容器的,但是pod有个工作特点:
大家记不记得:可以将多个容器联和起来,加入到同一个网络名称空间中去,所以这是pod的工作特点
一个pod可以包含多个容器,这些容器可以共享同一个底层的网络名称空间(NET、UTS、IPC) 而user MNT pad是相互隔离的
并且pod里面的容器还可以共享同一个存储卷,并且,存储卷不在容器内,它属于pod,相当于是pod的虚拟磁盘
各node主要是运行pod的
各位要注意的是一般一个pod内只放一个容器,除非容器之间有特别紧密的关系需要放在同一pod当中
如果pod中有多个容器那么满足:
假如我们这个容器中跑的是nginx,它会生成很多日志,我们要收集日志通常需要在目标服务器上部署一个日志收集的agent---,那么就部署在辅助容器上,非主容器叫做 编车(set car)主要是辅助主容器的某些功能而设置的
所以我们的调度器调度的也是pod,我们的node也是运行pod,pod是k8s的原子单元,也就是一个pod无论有一个容器还是多个容器,一旦我们把某个pod调度到某个node上运行后,这一个pod上的所有容器只能运行在同一个node上,这个要注意
node概念:
node是k8s集群的工作节点 ,负责运行Master指派的各种任务,最核心的任务是一pod的形式去运行容器,理论上node可以是任何形式上的设备,只要能够有传统意义上的cpu、内存、存储空间,还能够装上k8s相关的套件,都可以当做集群的一份子来工作,k8s执行的效果可以是如下:
当用户请求Master创建资源时,那么我们还有没有那么多cpu、内存源啊等我们做一个统一资源调度评估,那么终端用户就无需关心我们的资源到底是运行在哪个节点上,就实现了云里雾里的计算了
那么这么多pod运行在一个集群当中,那么将来分类管理怎么办?比如我们要删除某一类的pod,那么怎么删除呢?我只想让某一部分控制器控制管理某一类pod,那么怎么管理?怎么能识别,能挑拣出这一类pod呢?
我们不可能用名称来识别,毕竟随时都会创建出一个来,名称假如是一个独有标识符的话,一个pod因为故障而被删除以后重新建立一个新的pod,那么新pod跟原pod可能不一样只不过他内容和应用程序是一样的,我们不能靠名称来识别,同时我们可能需要将一类pod归组,如创建了四个nginx需要归为一类pod,并同一管理,如果我们把控制器删了,就把四个nginx容器同步删了,控制器还需要确保这四个nginx还在的,缺一个,他需要补一个,多一个,它需要多杀一个,精确符合我们期望的四个才行,控制器要完成这个功能
所以为了能够实现pod能够被识别,我们需要在pod上附加一些元数据
用标签来识别pod,也就是你创建玩pod的时候可以直接给pod打上标签,让控制器或人能够基于标签的这个值来识别标签了,换句话来说来识别pod了
k8s标签类的组件:标签选择器:Lable select