一、
Kubernetes(K8s)其实是一个集群, 是组合多台主机的资源整合成一个资源池并统一对外提供存储等能力的集群。其实就是找很多台主机,每台主机上都安装有Kubernetes(K8s)的相关应用程序,多台主机之间通过这个应用程序进行协调通信。
二、
Kubernetes(K8s)是masters/nodes节点形式的集群,K8s中有很多个master节点(一般master节点有3个就可以了)和很多个node节点。
三、那用户如何在K8s中运行容器呢?——master和node上的组件
1、用户的启动容器的请求会先交给master节点(用到ApiServer这个组件(该组件在master节点上),该组件用来接收请求,解析请求和处理请求);
2、master节点中有一个调度器(用到Scheduler组件(该组件在master节点上),该组件负责去观测每个node上总共可用的计算,内存和CPU资源,并根据用户所请求的创建的容器所需要的资源量,给该请求分配一个node。此过程包括两步—先做预选,然后再做优选,优选由调度器中的优选算法来决定)去分析每个node现有的可用资源状态,找一个最佳适配运行用户所请求的容器的节点,并把它调度上去,由node本地的docker或其他容器引擎负责把这个容器启动起来。启动容器必然要用到镜像(image),镜像在docker hub上,所以在启动容器时,会先检查本地是否有相应的镜像,如果没有,则还需要先把镜像拉取下来。这里考虑一个问题:如果用户所请求的docker容器或是其他容器运行起来之后,里面有一个运行程序挂掉了,但是用户又需要应用程序始终是运行状态的,那就涉及到了健康监测,其中Kublet组件就是用来做健康监测的。又考虑另外一个问题:如果node节点挂掉了,那么托管运行在该node节点上的所有容器也就都没有了,所以如何保证容器一直是运行着的呢,其中控制器组件就是用来做监控的,一旦发现node节点挂掉了,就会向master节点上的ApiServer组件发请求,让ApiServer组件去告诉Scheduler组件,让Scheduler组件重新分配一个node节点。又考虑另外一个问题:如果控制器挂掉了,那么要怎么办呢,这就涉及到了Controller Manager组件(该组件在master节点上)。又要考虑另外一个问题,如果Controller Manager不健康了呢,那么就需要做冗余(每个master节点上都有Controller Manager组件,即相当于Controller Manager组件做了高可用)。
3、总结:
(1)master节点上有三个核心组件:【1】、ApiServer组件——负责接收请求、解析请求和处理请求的;【2】、Scheduler组件——用来调度容器创建的请求;【3】、Controller Manager组件——确保控制器健康,而控制器用来确保node是健康的。
(2)node节点上有三个核心组件:【1】、kublet组件——用来做健康监测的;【2】、容器引擎,一般就是docker容器;【3】、
四、pod组件
1、Kubernetes(K8s)上的最小运行单元不是容器,而是Pod(Pod可以理解为容器的外壳,给容器做了一层抽象的封装,Pod内部主要就是来放置和运行容器的)。一个pod内可以运行多个容器,这多个容器之间可以共享同一个底层的网络名称空间(net、uts和ipc三个网络名称空间),另外三个互相隔离(user、mnt和pid互相隔离)。同时,同一个pod内的多个容器之间还可以共享存储卷。一般来说,一个pod中只放一个容器,如果特殊情况下放置了多个容器,那么这多个容器中只有一个容器是主容器,剩下的容器都是用来辅助主容器的。
2、一个pod内不管是有1个容器还是多个容器,一旦把某一个pod调度在某一个node上运行后,这一个pod内的所有容器只能运行在该node之上。
五、pod控制器组件
3、在K8s上运行了Pod之后,同一类Pod可能不止一个,那么用户的请求到达时,如何去接入用户请求?到底分配哪一个Pod来负责处理这些请求呢?Pod的管理是要通过控制器,而不是人工。Pod可以分为两大类:【1】、自主式Pod(自我管理的Pod,Pod创建之后,仍然是要交给ApiServer,ApiServer接收之后,借助于调度器调度至指定的node节点,由node启动此pod,之后,如果这个pod中的容器需要重启的话,是交给kublet组件来完成的,那么如果节点发生故障,pod也就消失了。即缺陷就是:没办法做到全局的调度);【2】、控制器管理的pod(有了控制器管理的pod之后,pod就可以被看作是有生命周期的对象,pod创建之后,交给ApiServer,ApiServer接收之后,借助于调度器调度至指定的node节点,由node启动此pod,启动之后,任务一完成,也就停掉了)。pod控制器:第一代版本:Replication Controller(多退少补、滚动更新、回滚操作);第二代版本:ReplicaSet,但是ReplicaSet不直接使用,而是使用Deployment来管理,但是Deployment只能管理那些无状态的应用;需要管理有状态的应用则需要StatefulSet控制器,同时如果需要在每个node上运行一个副本,而不是随意运行,则需要DaemonSet控制器。运行作业的话需要Job控制器,运行有定时任务的作业需要Ctonjob控制器。同时需要注意的是:Deployment控制器还支持二级控制器(HPA—Horizontal Pod Autoscaler),HPA控制器自动监控并增加或减少pod的数量。
六、node组件
1、node是K8s中的工作节点,负责运行由master指派的各种任务,而最核心的任务就是“以pod的形式运行容器”。理论上讲,node可以是任何形式的计算设备,只要能够有传统意义上的东西,eg:CPU、内存、存储空间并且能装上K8s的集群管理程序。
2、pod的分类管理:
为了能够实现pod的分类管理,需要在pod上添加一些元数据,即标签——是一个kv键值对,只有pod的k和v的值都相同,它们才属于同一类。这个删选的机制要靠标签选择器(selector)来实现。
3、总结:
pod上有两个重要的东西:label(标签)和selector(标签选择器)。
七、服务发现机制——service
1、pod是有生命周期的,因此每一个pod都有可能随时被创建,随时被销毁,假如这些pod提供的是固定服务,那么当客户端访问时,无法通过一个固定的地址去访问。因此需要用到service组件。
2、客户端在进行访问时,首先需要访问service组件,service组件一旦创建之后不被删除,就不会重启,且会被分配固定的IP地址和固定的主机名/服务名(从主机名导IP地址需要通过DNS服务),可以提供一个固定的访问入口。然后再由service组件去给pod分发调度相应的请求。
3、service关联pod是通过标签,只要创建的pod的标签与service的标签一致,那这些创建好的pod就会被service发现。
八、K8s的三种网络机制
K8s中有三种网络:1、节点网络;2、service网络(也可称为集群网络);3、pod网络(各个pod运行在一个网络中)
九、K8s的三种通信机制
1、同一pod内的多个容器间怎么进行通信:通过lo回环接口(即本地通信)
2、各个pod间怎么进行通信:可直接进行通信(通过叠加网络—Verlay Network)
3、pod与service之间怎么通信:service的地址只是iptables规则中的地址,pod地址只需要指向网关(一般是docker0桥)。当pod访问service时,pod先去访问网关(一般是docker0桥),然后再由网关去访问service的地址。因此每个pod上都有iptables规则。那么当service随时都有可能变动(service的删除和创建)或者service背后的pod发生了改变,那么如果service发生了改变,pod怎么知道呢,当然是通过标签选择器(通过标签选择器来反映),但是service又是怎么改变所有pod上的iptables规则呢?这需要运行在node上的组件kube-proxy。
十、kube-proxy组件
该组件与master节点上的ApiServer组件进行通信,因为一旦pod发生改变,这个结果是要保存在ApiServer组件当中的,而ApiServer组件中的内容发生改变之后,会生成一个通知事件,这个事件可以被任何关联了ApiServer的组件察觉到,比如kube-proxy组件一旦发现了某一个service背后的pod的地址发生了改变,那么对应的由kube-proxy负责在本地把那个地址反映在iptables或者是ipvs规则中。所以service的管理是通过kube-proxy来实现的。service的创建要靠kube-proxy组件在每个pod上创建iptables或者是ipvs规则中,每个service的变动也要靠kube-proxy反映到规则上。
十一、etcd组件
对于master节点来说,数据并不存放在master本地,而是放在共享存储中(或者可以称为K8s的db数据库),这个共享存储叫做etcd组件。etcd是一个键值存储的数据库系统,etcd本身还拥有各种协调功能,比如rap协议,节点的leader选举等功能。
那如果etcd挂机了,那整个集群也就挂了。所以etcd需要做高可用,一般etcd的高可用有三个节点。三个etcd节点之间的通信通过比较安全的https协议进行通信。etcd的通信有一个特点:9300用于内部进行通信,9200用来向客户端提供服务。
十二、
整个K8s集群有三类节点:1、master节点;2、etcd节点;3、node节点。这三类节点彼此之间都是通过http或https协议进行通信。
K8s中有三种网络:1、节点网络;2、service网络(也可称为集群网络);3、pod网络(各个pod运行在一个网络中)
K8s本身并不提供这些网络,需要有第三方服务商进行提供(第三方服务商必须提供service网络和pod网络,其中节点网络由运营人员在构建K8s集群之前就提供的)。K8s通过CNI(Container Network Interface—容器网络接口)插件体系来接入外部网络服务解决方案。常见的CNI插件有两类:【1】flannel:仅支持网络配置,不支持网络策略;【2】、calico:既支持网络配置,又支持网络策略;【3】、canel:相当于flannel(网络配置比较简单)+calico(网络配置比较复杂),用flannel来提供网络配置,用calico来提供网络策略。