K8S的基础概念
1. 概述
Kubernetes,又称为 k8s(首字母为 k、首字母与尾字母之间有 8 个字符、尾字母为 s,所以简称 k8s)或者简称为 “kube” ,是一种可自动实施 Linux 容器 操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。也就是说,您可以将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助您轻松高效地管理这些集群。而且,这些集群可跨 公共云、私有云或混合云部署主机。因此,对于要求快速扩展的云原生应用而言,Kubernetes 是理想的托管平台。
Kubernetes特点:
轻量级:消耗资源小
开源
弹性伸缩
负载均衡:IPVS
2. 架构
2.1 全局架构
Etcd: 保存整个集群的状态
API Server: 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制
Controller Manager: 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
Scheduler: 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
Kubelet: 负责维护容器的生命周期、Volume(CVI) 和网络(CNI)的管理
Container Runtime: 负责镜像管理以及 Pod 和容器的真正运行(CRI)
Kube-proxy: 负责为Service提供cluster内部的服务发现和负载均衡 (四层)
iptables
ipvs
2.2 功能架构
CRI (Container Runtime Interface):容器运行时接口,该接口定义了容器运行时的标准操作,比如创建容器、删除容器等。目前主流的实现有 CRI-O 和 Containerd
OCI (Open Container Initiative):开放容器标准,即容器运行时标准和容器镜像标准,主流实现有 runc 等
CNI (Container Network Interface):容器网络接口,容器创建分配网络资源、容器删除释放网络资源
CSI (Container Storage Interface):容器存储接口
关系:
kubelet 通过轮询 kube-apiserver 来判定是否要在当前节点启动 Pod
当需要创建 Pod 时,kubelet 会通过调用 CNI 接口获取网络资源,然后调用 CRI 接口去创建容器,并把网络资源设进容器中
CRI 服务 Containerd 或 CRI-O 会去调用 OCI 标准运行时 runc 等来创建容器。
3. 组件
3.1 kube-apiserver
只有 API Server 能与 etcd 进行通信,其它模块都必须通过 API Server 访问集群状态。
API Server 是资源对象操作的唯一入口,其它所有组件都必须通过它提供的 API 来操作资源数据。它以 RESTFul 接口方式提供给外部客户端和内部组件调用,API Server 再对相关的资源数据(全量查询 + 变化监听)进行操作,以达到实时完成相关的业务功能。
3.2 kube-controller-manager
Controller Manager 用于 实现 Kubernetes 集群故障检测和恢复的自动化工作。主要负责执行各种控制器:
Replica Set:关联 RS 和 Pod,以保证集群中一个 RS 所关联的 Pod 副本数始终保持为与预设值一致
Node Controller:Kubelet 在启动时会通过 API Server 注册自身的节点信息,并定时向 API Server 汇报状态信息。API Server 在接收到信息后将信息更新到 Etcd 中。Node Controller 通过 API Server 实时获取 Node 的相关信息,实现管理和监控集群中的各个 Node 节点的相关控制功能
ResourceQuota Controller:资源配额管理控制器用于确保指定的资源对象在任何时候都不会超量占用系统上物理资源
Namespace Controller:用户通过 API Server 可以创建新的 Namespace 并保存在 Etcd 中,Namespace Controller 定时通过 API Server 读取这些 Namespace 信息来操作 Namespace。比如:Namespace 被 API 标记为优雅删除,则将该 Namespace 状态设置为 Terminating 并保存到 Etcd 中。同时 Namespace Controller 删除该 Namespace 下的 ServiceAccount、Deployment、Pod 等资源对象
Service Account Controller:服务账号控制器主要在命名空间内管理 ServiceAccount,以保证名为 default 的 ServiceAccount 在每个命名空间中存在
Token Controller:令牌控制器作为 Controller Manager 的一部分,主要用作:监听 serviceAccount 的创建和删除动作以及监听 secret 的添加、删除动作
Service Controller:服务控制器主要用作监听 Service 的变化。比如:创建的是一个 LoadBalancer 类型的 Service,Service Controller 则要确保外部的云平台上对该 Service 对应的 LoadBalancer 实例被创建、删除以及相应的路由转发表被更新
Endpoint Controller:Endpoints 表示了一个 Service 对应的所有 Pod 副本的访问地址,而 Endpoints Controller 是负责生成和维护所有 Endpoints 对象的控制器。Endpoint Controller 负责监听 Service 和对应的 Pod 副本的变化。定期关联 Service 和 Pod (关联信息由 Endpoint 对象维护),以保证 Service 到 Pod 的映射总是最新的
3.3 kube-scheduler
Scheduler 是负责整个集群的资源调度:
收集和分析当前 Kubernetes 集群中所有 Node 节点的资源 (包括内存、CPU 等) 负载情况,然后依据资源占用情况分发新建的 Pod 到 Kubernetes 集群中可用的节点
实时监测 Kubernetes 集群中未分发和已分发的所有运行的 Pod
实时监测 Node 节点信息,由于会频繁查找 Node 节点,所以 Scheduler 同时会缓存一份最新的信息在本地
在分发 Pod 到指定的 Node 节点后,会把 Pod 相关的 Binding 信息写回 API Server,以方便其它组件使用
3.4 kubelet
kubelet 是负责容器真正运行的核心组件:
负责 Node 节点上 Pod 的创建、修改、监控、删除等全生命周期的管理
定时上报本地 Node 的状态信息给 API Server
kubelet 是 Master 和 Node 之间的桥梁,接收 API Server 分配给它的任务并执行
kubelet 通过 API Server 间接与 Etcd 集群交互来读取集群配置信息
kubelet 在 Node 上的具体工作:
设置容器的环境变量、给容器绑定 Volume、给容器绑定 Port、根据指定的 Pod 运行一个单一容器、给指定的 Pod 创建 Network 容器
同步 Pod 的状态
在容器中运行命令、杀死容器、删除 Pod 的所有容器
3.5 kube-proxy
kube-proxy 是为了解决外部网络能够访问集群中容器提供的应用服务而设计的,Proxy 运行在每个Node 上。
每创建一个 Service,kube-proxy 就会从 API Server 获取 Services 和 Endpoints 的配置信息,然后根据其配置信息在 Node 上启动一个 Proxy 的进程并监听相应的服务端口。
当接收到外部请求时,kube-proxy 会根据 Load Balancer 将请求分发到后端正确的容器处理。
kube-proxy 不但解决了同一宿主机相同服务端口冲突的问题,还提供了 Service 转发服务端口对外提供服务的能力。
kube-proxy 后端使用随机、轮循等负载均衡算法进行调度。
4. 核心资源对象
4.1 Pod
Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
Pod 是K8S最小的调度单位。
用户通过 REST API 创建一个 Pod
apiserver 将其写入 etcd
scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定
kubelet 检测到有新的 Pod 调度过来,通过 container runtime 运行该 Pod
kubelet 通过 container runtime 取到 Pod 状态,并更新到 apiserver 中
4.2 Label
标签(Label)是将资源进行分类的标识符。资源标签具体化的就是一个键值型(key/values)数据,使用标签是为了对指定对象进行辨识,比如Pod对象。标签可以在对象创建时进行附加,也可以创建后进行添加或修改。要知道的是一个对象可以有多个标签,一个标签页可以附加到多个对象。
Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标志具体的应用。
Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。Label Selector 支持以下几种方式:
等式,如 app=nginx 和 env!=production
集合,如 env in (production, qa)
多个 label( AND 关系),如 app=nginx,env=test
4.3 Annotations
Annotation是另一种附加在对象上的一种键值类型的数据,常用于将各种非标识型元数据(metadata)附加到对象上,但它并不能用于标识和选择对象。其作用是方便工具或用户阅读及查找。比如用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。 deployment 使用 annotations 来记录 rolling update 的状态。
4.4 Namespace
Namespace 是对一组资源和对象的抽象集合,可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, replication controllers 和 deployments 等都是属于某一个 namespace 的(默认是 default),而 node, persistentVolumes 等则不属于任何 namespace。
名称空间通常用于实现租户或项目的资源隔离,从而形成逻辑分组。
4.5 Deployment
Deployment 确保任意时间都有指定数量的 Pod“副本”在运行。如果为某个 Pod 创建了 Deployment 并且指定3个副本,它会创建3个 Pod,并且持续监控它们。如果某个 Pod 不响应,那么 Deployment 会替换它,始终保持总数为3。
如果之前不响应的 Pod 恢复了,现在就有4个 Pod 了,那么 Deployment 会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Deployment 会立刻启动2个新 Pod,保证总数为5。持回滚和滚动升级。
当创建 Deployment 时,需要指定两个东西:
Pod 模板:用来创建 Pod 副本的模板
Label 标签:Deployment 需要监控的 Pod 的标签。
4.6 Service
Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。
每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。