You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

  • 一、Kubernetes是什么
    k8s在docker的基础上,为容器化的应用提供部署运行,资源调度,服务发现及动态伸缩等一系列完整功能。kubernetes是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多扩多层次的安全防护及准入机制,多租户应用支撑能力,透明的服务注册和发现机制,内建只能负载均衡器,强大的故障发现和自我修复能力,服务滚动升级和在线扩容能力,可扩展的资源自动调度机制以及多粒度的资源配置配额管理能力。k8s由Master节点和Node节点两部分组成 。

    二、k8s组件
    Master节点
    Master节点负责集群的管理,相关联的组件有ETCD数据库、Controller Manager、Scheduler、kube-apiserver。Master节点协调集群的各个活动,例如资源调度、动态伸缩、维护应用状态以及滚动更新等。

    1. ETCD数据库
    etcd数据是一个高可用的分布式键值数据库,可用于服务发现。etcd采用raft一致性算法,基于GO语言实现。由于raft算法采用多数投票机制,所以建议采用奇数个数节点。

    2. kube-apiserver
    k8s对外唯一的接口,提供http/https RESTfull API,即kubernetes API。所有的请求都通过这个接口进行通信。包括认证授权、数据校验以及集群状态更新。通过apiserver将集群状态信息持久化到ETCD中。默认端口为6443

    3. Controller Manager
    Controller Manager作为集群内部的管理控制中心,负责集群的Node,Pod副本,endpoint,namespace等的管理,当集群中的某个Node宕机,Controller Manager会及时发现此故障并快速修复,将集群恢复成预期的工作状态。
    Controller Manager包括Replication Controller,Node Controller,Namespace Controller,ServiceAccount Controller,Token Controller,Service Controller,endpoint Controller,ResourceQuata Controller

    4. Scheduler
    Scheduler的核心功能是监听apiserver来获取podSpec.NodeName为空的pod,然后为这个pod创建一个binding,指示这个pod创建在哪个节点上。然后把调度结果写到apiserver持久化到ETCD中。
    调度过程:

    首先过滤掉不满足条件的节点,这个过程成为预选(predicate)
    PodFitsResources:节点上剩余的资源是否大于 pod 请求的资源
    PodFitsHost:如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配
    PodFitsHostPorts:节点上已经使用的 port 是否和 pod 申请的 port 冲突
    PodSelectorMatches:过滤掉和 pod 指定的 label 不匹配的节点
    NoDiskConflict:已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读

    然后把节点按照优先级进行排序,这个过程叫优选(priority)
    LeastRequestedPriority:通过计算 CPU 和 Memory 的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点
    BalancedResourceAllocation:节点上 CPU 和 Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用
    ImageLocalityPriority:倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高

    关于调度的亲和性(nodeAffinity)、反亲和性、污点(Taint)、容忍(Toleration)
    调度亲和性等特性

    Node节点
    Node主要为应用程序提供运行环境,并接受Master管理,并按照Master要求进行对容器进行管理。主要组件包括kubelet、kube-proxy、CNI网络插件等。

    1. kubelet
    kubelet是node节点的agent,当Scheduler确定pod运行在某个节点上时,会将pod的具体配置信息(image,network,volume等)发送给节点的kubelet,kubelet会根据配置信息进行创建容器,并将容器运行结果报告给Master。另外,kubelet还会周期性的向Master报告pod以及node节点的运行状态。

    2. kube-proxy
    kube-proxy是k8s工作节点上的一个网络代理组件,它的作用是将发往service的流量负载均衡到正确的后端pod。kube-proxy监听API server中的service和endpoint的变化,并通过iptables或者IPVS创建不同的路由规则,以实现上述目的。

    iptables模式,kube-proxy默认模式,当前模式下,kube-proxy监听service和endpoint的变化,当service创建时,kube-proxy在iptables中追加新的规则,对于service中的每一个endpoint,会在iptables中追加一条DNAT规则,将目的地址设置为真正提供服务的pod地址;再为service追加规则,设定动作为跳转到对应的endpoint规则上

    ipvs模式,ipvs在INPUT阶段也是基于netfilter的hook功能,与iptables类似。但是转发规则是通过工作在内核空间下的hash表作为存储的数据结构。在这种模式下,只需要通过ipset来验证具体的请求是否满足某条规则。当service变化时,只需要更新ipset记录,不需要改变iptables规则链,因此可以保证iptables中的规则不会根据service的创建越来越多。同时,ipvs的性能也高于iptables,因为当service变化时,ipvs只需要对特定的hash表进行更新,而iptables则需要更新整个规则表。

    3. CNI网络插件
    CNI是k8s用于实现pod间相互通信的标准接口。常用的网络插件有flannel和calico
    kubernetes配置CNI网络插件后,其容器网络创建流程为:

    kubernetes先创建pause容器生成对应的netns
    CNI driver根据配置调用具体的网络插件(flannel或者calico)
    CNI插件给pause容器配置具体的网络,pod中的其他容器都使用pause网络
    当容器删除是,回收网络资源
    1. flannel
    flannel一般以daemonset方式运行,主要负责编织跨节点pod通信,启动后会完成以下几件事情:

    创建容器挂载的cni配置文件;
    从api-server中获取本节点的pod-cidr,生成配置文件subnet.env;
    如果是vxlan模式,则创建一个名为flannel.1的vxlan设备,把这个设备的IP地址和MAC地址以及本节点的IP地址记录到节点的注解中;
    启动一个协程,不断检查本地主机的路由信息,如果检查到缺失,则重新创建;
    从api-server订阅资源变化的事件,维护路由表,邻居表以及fdb表。
    当集群中新增一个节点时,CNI的初始化流程如下:
    6. 新增一条到新增节点pod网段的路由,并指定从flannel.1设备走,下一跳为新增节点的vxlan设备的IP;
    7. 新增一条邻居表项,指定新增节点的vxlan设备的MAC地址信息;
    8. 新增一条fdb表项,指定到新增节点vxlan设备的MAC的下一跳为新增节点的主机IP

    2. Calico
    Calico是一个由BGP协议组成的纯三层网络。通过BGP协议实现网络互通,通过iptables实现访问控制。
    Calico网络中,每个node节点都是一个虚拟路由器,运行着一个软件bird,把node设置成为一个BGP speaker,与其他node节点进行路由通告,实现内部网络互通。当集群网络过于庞大时,可以通过BGP router reflector与所有node节点进行路由通告,而node节点只需要与router reflector进行同步路由即可。

    calico工作组件
    felix:运行在每个node节点上的agent,主要负责网络接口的管理、监听,路由,ARP管理、ACL管理和同步,状态上报等;
    BIRD:用于监听Felix注入的路由信息,通过BGP协议广播给其他node节点上的BIRD,使路由保持同步
    etcd:分布式键值数据库,主要用于网络信息的存储,保持与集群网络一致
    router reflector(RR):在大型网络中,仅仅使用BGP Client形成mesh网络会受到规模限制,所以RR与集群中所有的node节点的BGP Client互通,进行路由通告,然后各个节点只需要从RR中获取路由即可,形成星型网络,极大的提高了路由同步效率。

    calico的两种网络模式
    IPIP
    IPIP模式是将一个IP层封装进IP层的一个tunnel,pod网络通过与目标pod网络的主机IP形成一个点对点的tunnel。

    BGP
    BGP模式通过维护集群网络的IP路由信息来保障路由可达性,没有隧道等其他封装开销,完全由主机维护各节点的路由表进行通信。

  • 1、K8S是如何对容器编排?

在K8S集群中,容器并非最小的单位,K8S集群中最小的调度单位是Pod,容器则被封装在Pod之中。由此可知,一个容器或多个容器可以同属于在一个Pod之中。

  • 2、Pod是怎么创建出来的?

Pod并不是无缘无故跑出来的,它是一个抽象的l逻辑概念,那么Pod是如何创建的呢?Pod是由Pod控制器进行管理控制,其代表性的Pod控制器有Deployment、StatefulSet等。这里我们先有这样的一个概念,后面再详细解刨。

  • 3、Pod资源组成的应用如何提供外部访问的?

Pod组成的应用是通过Service这类抽象资源提供内部和外部访问的,但是service的外部访问需要端口的映射,带来的是端口映射的麻烦和操作的繁琐。为此还有一种提供外部访问的资源叫做Ingress。

  • 4、Service又是怎么关联到Pod呢?

在上面说的Pod是由Pod控制器进行管理控制,对Pod资源对象的期望状态进行自动管理。而在Pod控制器是通过一个YAML的文件进行定义Pod资源对象的。在该文件中,还会对Pod资源对象进行打标签,用于Pod的辨识,而Servcie就是通过标签选择器,关联至同一标签类型的Pod资源对象。这样就实现了从service-->pod-->container的一个过程。

  • 5、Pod的怎么创建逻辑流程是怎样的?
  • (1)客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。
  • (2)API Server处理用户请求,存储Pod数据到etcd。
  • (3)调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。
  • (4)过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。
  • (5)主机打分(调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。
  • (6)选择主机:选择打分最高的主机,进行binding操作,结果存储到etcd中。
  • (7)kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。
  • No labels