Kubernetes是一个完备的分布式系统支撑平台。Kubernetes具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建的智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时,Kubernetes提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。因此,Kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。(摘自《Kubernetes权威指南》)

我想说的是Kubernetes是现代数据中心操作系统。

为什么只摘录上面这一段话呢?在我看来,Kubernetes(也叫K8s)的出现表面是用来管理Docker的,其实他真正的意义是IT基础设施资源管理系统,是现代数据中心的操作系统。随着云计算的发展,电子产品数据中心化,以后大家购买的都是云资源云服务,而不是大量的单体电子产品;大多数人只需要手机终端显示操控即可。所以数据中心的操作系统(资源调度系统)意义非凡。对这一类技术要引起重视。

名词OCI、CRI、CNI

  1. 先说一下容器发展的历史:一开始是Docker.io公司推出了容器Docker,但其实容器并非只有Docker,这样带来一个问题是很多做容器编排的公司都要去兼容所有的容器类型。于是后来北美的一些大厂就开始讨论联合指定一个统一的规范,以后做容器的公司都要以这个为准,这个标准就是 Open Container Initiative(OCI)。
  2. CRI是OCI标准中的其中一个,“容器运行时标准”,它定义了容器在硬盘上存储的方式,用于描述容器中应用程序的 JSON 文件和如何创建和运行容器。Docker.io贡献了 libcontainer,并且提供了 runc 作为 OCI 运行时规范的默认实现。
  3. CNI是CNCF旗下的一个项目,由一组用于配置Linux容器的网络接口的规范和库组成,同时还包含了一些插件。CNI仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。

K8s的发展历程

2014年	6月正式开源K8s,一个基于Borg、Omega及其他谷歌内部系统实践的开源系统
2015年	7月发布kubernetes 1.0, 加入CNCF
2016年	kubernetes干掉两个对手,docker swarm,mesos
2018年 	k8s从CNCF基金会毕业
2019年   8月发布到1.15
2020年	发布到了1.20

# 名词解释
cncf (cloud native compute foundation)
kubernetes (k8s): 希腊语 舵手,领航。(谷歌15年容器使用经验,borg容器管理平台,使用golang重构)

关于K8s还可以参考阅读:

https://zhuanlan.zhihu.com/p/139965100

K8s核心能力

1.自愈:

重新启动失败的容器,在节点不可用时,替换和重新调度节点上的容器,对用户定义的健康检查不响应的容器会被中止,并且在容器准备好服务之前不会把其向客户端广播。

2.弹性伸缩:

通过监控容器的cpu的负载值,如果这个平均高于80%,增加容器的数量,如果这个平均低于10%,减少容器的数量。

3.服务的自动发现和负载均衡:

不需要修改您的应用程序来使用不熟悉的服务发现机制,K8s为容器提供了自己的 IP 地址和一组容器的单个 DNS 名称,并可以在它们之间进行负载均衡。

4.滚动升级和一键回滚:

K8s逐渐部署对应用程序或其配置的更改,同时监视应用程序运行状况,以确保它不会同时终止所有实例。 如果出现问题,K8s会为您恢复更改,利用日益增长的部署解决方案的生态系统。

K8s核心组件

Kubernetes 主要由以下几个核心组件组成:

  • etcd:保存了整个集群的状态;
  • apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
  • controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • kubelet:负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
  • Container runtime:负责镜像管理以及 Pod 和容器的真正运行(CRI);
  • kube-proxy:负责为 Service 提供 cluster 内部的服务发现和负载均衡

除了核心组件,还有一些推荐的 Add-ons:

  • kube-dns:负责为整个集群提供 DNS 服务
  • Ingress Controller:为服务提供外网入口
  • Heapster:提供资源监控
  • Dashboard:提供 GUI
  • Federation:提供跨可用区的集群
  • Fluentd-elasticsearch:提供集群日志采集、存储与查询

K8s常见概念

Pod

Pod是K8S设计的一个全新的概念,在英文中的原意是表达一群鲸鱼或者是一个豌豆荚的意思。换句话说,一个Pod中可以运行一个或者多个容器。

在一个集群中,K8S会为每个Pod都分配一个集群内唯一的IP地址。因为K8S要求底层网络支持集群内的任意节点之间的两个Pod能够直接通信。这些容器共享当前Pod的文件系统和网络。而这些容器之所以能够共享,是因为Pod中有一个叫Pause的根容器,其余的用户业务容器都是共享这个根容器的IP和Volume。所以这些容器之间都可以通过localhost进行通信。

Service

Service是K8S中最核心的资源对象之一。一旦Service被创建,K8S会为其分配一个集群内唯一的IP,叫做ClusterIP,而且在Service的整个生命周期中,ClusterIP不会发生变更,这样就可以建立一个ClusterIP到服务名的DNS域名映射。

ClusterIP是一个虚拟的IP地址,无法被Ping,仅仅只限于在K8S的集群内使用。

Service对客户端,屏蔽了底层Pod的寻址过程。并且由kube-proxy进程将对Service的请求转发到具体的Pod上,具体到哪一个,由具体的调度算法决定。这样以来,就实现了负载均衡。

而Service是怎么找到Pod的呢?这就需要继续引入另外一个核心概念Label。

Label

Lable本质上是一个键值对,具体的值由用户决定。Lable就是标签,可以打在Pod上,也可以打到Service上。

总结来说,Label与被标记的资源是一个一对多的关系。

比如我们给上面所描述的Pod打上了role=serviceA的标签,那么只需要在Service中的Label Selector中加入刚刚那个标签,这样一来,Service就可以通过Label Selector找到打了同一Label的Pod副本集了。

Labels Selectors

与Name和UID不同,标签不需要有唯一性。一般来说我们期望许多对象具有相同的标签。通过标签选择器(Labels Selectors),客户端/用户 能方便辨识出一组对象。API目前支持两种选择器:equality-based(基于平等)和set-based(基于集合)的。标签选择器可以由逗号分隔的多个requirements 组成。在多重需求的情况下,必须满足所有要求,因此逗号分隔符作为AND逻辑运算符。

  1. 一个为空的标签选择器(即有0个必须条件的选择器)会选择集合中的每一个对象。
  2. 一个null型标签选择器(仅对于可选的选择器字段才可能)不会返回任何对象。

注意:两个控制器的标签选择器不能在命名空间中重叠。

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, ReplicaSet和 deployments 等都是属于某一个 namespace 的(默认是 default),而 node, persistentVolumes 等则不属于任何 namespace。

大多数Kubernetes资源(例如pod、services、ReplicaRet或其他)都在某些Namespace中,但Namespace资源本身并不在Namespace中。而低级别资源(如Node和persistentVolumes)不在任何Namespace中。是一个例外:它们可能有也可能没有Namespace,具体取决于Events的对象。

Deployment

Deployment是一个更高层次的API对象,它管理ReplicaSet和Pod,并提供声明式更新等功能。

官方建议使用Deployment管理ReplicaSet,而不是直接使用ReplicaSet,这就意味着可能永远不需要直接操作ReplicaSet对象,因此Deployment将会是使用最频繁的资源对象。

StatefulSet

StatefuleSet主要用来部署有状态应用,能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。 StatefulSet适合持久性的应用程序,有唯一的网络标识符(IP),持久存储,有序的部署、扩展、删除和滚动更新。

在具有以下特点时使用StatefulSets:

  • 稳定性,唯一的网络标识符。
  • 稳定性,持久化存储。
  • 有序的部署和扩展。
  • 有序的删除和终止。
  • 有序的自动滚动更新。

ReplicaSet

ReplicaSet(RS)是Replication Controller(RC)的升级版本。ReplicaSet 和 Replication Controller之间的唯一区别是对选择器的支持。ReplicaSet支持set-based选择器要求, 而Replication Controller仅支持equality-based的选择器要求。

ReplicaSet定义了一种期望的场景,即让任何时候集群内的Pod副本数量都符合预期的值。

一旦被创建,集群就会定期的检测当前存活的Pod数量,如果多了,集群就会停掉一些Pod。相反,如果少了就会创建一些Pod。这样一来可以避免什么问题呢?假设某个服务有两个实例在运行,其中一个意外挂掉了,如果我们设置了副本数量是2,那么集群就会自动创建一个Pod,以保证集群内始终有两个Pod在运行。

RS常用方式

  • Rescheduling(重新规划)
  • 扩展
  • 滚动更新
  • 多版本跟踪
  • 使用RS与关联的Services

Volume

Volume是pod中能够被多个容器访问的共同目录。也就是被定义在pod上,然后被一个pod中的多个容器挂载到具体的文件目录下,其次,volume与pod生命周期相同,但与容器生命周期不相关,当容器终止或重启,volume中的数据也不会丢失。

Name

Name在一个对象中同一时间只能拥有单个Name,如果对象被删除,也可以使用相同Name创建新的对象,Name用于在资源引用URL中的对象,例如/api/v1/pods/some-name。通常情况,Kubernetes资源的Name能有最长到253个字符(包括数字字符、-.)。

UIDs

UIDs是由Kubernetes生成的,在Kubernetes集群的整个生命周期中创建的每个对象都有不同的UID(即它们在空间和时间上是唯一的)。

Endpoint

一个资源对象,用于记录一个 Service 对应的所有 pod 的访问地址。

CoreDNS

是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中, CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。

K8s整体架构图

image-20240915181947765

参考文章:

http://docs.kubernetes.org.cn/

https://zhuanlan.zhihu.com/p/43266412

https://zhuanlan.zhihu.com/p/100644716

K8s的控制面和数据面

Kubernetes 的架构包括控制平面(Control Plane)和数据平面(Data Plane)。这两个平面各自负责不同的功能,共同协作以管理和运行容器化应用程序。

1. 控制平面(Control Plane):

控制平面是 Kubernetes 管理集群的大脑,负责决策和全局控制。它包含以下主要组件:

  • kube-apiserver:
    • 提供 Kubernetes API 的服务端实现,是控制平面的入口,处理来自用户、其他组件和外部系统的 API 请求。
  • etcd:
    • 分布式键值存储系统,用于存储集群的配置数据、状态和元数据。etcd 提供了持久性存储,确保即使在控制平面组件失败或重启时,集群的状态仍然可恢复。
  • kube-controller-manager:
    • 运行一系列控制器,负责监控集群的状态,并根据所需的状态调整系统。例如,Node 控制器负责管理节点,Replication Controller 负责确保指定数量的 Pod 实例在集群中运行。
  • kube-scheduler:
    • 负责决定在哪个节点上启动新的 Pod 实例。它根据节点资源、Pod 调度策略和其他约束来进行决策。

2. 数据平面(Data Plane):

数据平面是负责运行容器化应用程序的节点,也称为工作节点。它包含以下主要组件:

  • kubelet:
    • 在每个节点上运行的代理,负责维护节点上的容器。它通过与控制平面的 kube-apiserver 交互来获取 Pod 规范,并确保 Pod 中的容器按规范运行。
  • kube-proxy:
    • 负责维护节点上的网络规则,实现 Kubernetes 服务的网络代理。它通过 iptables 或其他实现来确保流量正确路由到集群中的 Pod。
  • Container Runtime:
    • 负责在节点上运行容器。常见的容器运行时包括 Docker、containerd 和 CRI-O。它与 kubelet 交互,通过启动和管理容器来满足 Pod 的规范。

工作原理:

  1. 用户通过 kube-apiserver 与控制平面通信,提交集群操作请求。
  2. 控制平面组件(etcd、kube-controller-manager、kube-scheduler)负责决策、调度和维护集群状态。
  3. kubelet 接收控制平面的指令,负责在节点上创建、更新和删除容器。
  4. kube-proxy 负责维护节点上的网络规则,实现服务代理。
  5. 容器运行时负责在节点上启动和管理容器。

控制平面和数据平面的分离使得 Kubernetes 具有高度的可扩展性和灵活性。通过这种架构,可以在不影响整体系统运行的情况下分别扩展控制平面和数据平面的能力。这也是SDN(软件定义网络)的核心概论。

(完)