k8s指南-架构
Kubernetes是一个可移植的,可扩展的开源平台,用于管理容器化的工作负载和服务,为声明式配置和自动化带来了巨大便利。它拥有着巨大而快速增长的生态系统,其相关的服务和工具得到了广泛的应用。...........................
目录:
(1)k8s指南-概述
(2)k8s指南-架构
(3)k8s指南-工作负载(1)
(4)k8s指南-工作负载(2)
(5)k8s指南-工作负载(3)
(6)k8s指南-工作负载(4)
(7)k8s指南-Service
(8)k8s指南-Ingress
(9)k8s指南-DNS与服务发现
(10)K8S指南-平滑升级与自动扩缩容
Kubernetes是一个可移植的,可扩展的开源平台,用于管理容器化的工作负载和服务,为声明式配置和自动化带来了巨大便利。它拥有着巨大而快速增长的生态系统,其相关的服务和工具得到了广泛的应用。
节点
一个Kubernete集群由一群被称为节点的机器组成,工作负载组件-也就是pods,托管在集群的工作节点上。每个节点包含运行pods所需的服务。这些节点由控制平面负责管理。
通常集群中会有若干个节点。而在一个学习用或者资源受限的环境中,你的集群中也可能只有一个节点。
节点上的组件包括kubelet、容器运行时以及kube-proxy。Kubernetes组件图在概述中介绍过,这里不再赘述。
节点管理
向API服务器添加节点的方式主要有两种:
- 节点上的kubelet向控制面执行自注册;
- 手动添加一个Node对象
在创建了Node对象或者节点上的kubelet
执行了自注册操作之后,控制面会检查新的Node对象是否合法。例如,如果你尝试使用下面的JSON对象来创建Node:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes会在内部创建一个Node对象作为节点的表示。Kubernetes检查kubelet向API服务器注册节点时使用的metadata.name
字段是否匹配。如果节点是健康的(即所必要的服务都在运行中),则该节点可以用来运行pod。否则,所有的集群活动都会忽略该节点直到它变成健康状态为止。
注意:Kubernetes会一直保存着不健康节点对应的对象,并持续检查该节点是否已经变得健康。只有当显式地删除该Node对象时,k8s才会停止健康检查操作。
Node对象的名称必须是符合的DNS子域名。
节点名称唯一性
节点的名称用来标识Node对象。没有两个Node可以同时使用相同的名称。Kubernetes还假定名字相同的资源是同一个对象。就Node而言,隐式地假定使用相同名称的实例会具有相同的状态(如网络配置、根磁盘内容)和类似节点标签这类属性。这可能在节点被变更但其名称未变时导致系统状态不一致。如果某个Node需要被替换或者大量变更,需要从API服务器移除现有的Node对象,之后再在更新之后重新将其加入。
节点自注册
当kubelet标志--register-node
为true(默认)时,它会尝试向API服务注册自己。这是首选模式,被绝大多数发行版选用。对于自注册模式,kubelet使用下列参数启动:
--kubeconfig
: 用于向API服务器执行身份认证所用的凭据的路径,换句话说,就是身份认证配置文件路径。--cloud-provider
: 与云服务进行通信以读取与自身相关的元数据的方式。--register-node
: 自动向API服务注册。--register-with-taints
: 使用所给的污点列表(逗号分隔的<key>=<value>:<effect>
)注册节点。当register-node为false时无效。--node-ip
: 节点IP地址。--node-labels
:在集群中注册节点时所要添加的标签。--node-status-update-frequency
: 指定kubelet向控制面发送状态的频率。
启用Node鉴权模式和NodeRestriction准入插件时,仅授权kubelet创建或修改自己的节点资源。
正如上文所述,当Node的配置需要被更新时,一种好的做法是重新向API服务器注册该节点。例如,当kubelet重启并且其
--node-labels
指定了新的值,而节点名称不变时,则所做变更不会起作用,因为节点标签是在Node注册时就已经完成了的。
如果在kubelet重启期间Node配置发生了变化,已经被调度到某Node上的pod可能会出现行为不正常或者出现其他问题。
手动节点管理
你可以使用kubectl来创建和修改Node对象。
如果你希望手动创建节点对象时,需要设置kubelet标志--register-node=false
。
你也可以修改Node对象(忽略register-node
设置)。例如,修改节点上的标签或标记其为不可调度。
如果标记节点为不可调度(unschedulable),将阻止新的pod调度到该Node之上,但不会影响任何已存在的pod。这是重启节点或执行其他维护操作之前的一个有用的准备步骤。
要标记一个Node为不可调度,可通过以下命令:
kubectl cordon $NODENAME
节点状态
一个节点的状态包含:地址,状况(Condition),容量(Capacity),信息。
你可以使用kubectl来查看节点状态和其他细节信息:
kubectl describe node <节点名称>
地址
地址字段的用法取决于你的云服务商或者物理机配置。
- HostName: 由节点的内核报告。可以被kubelet的
--hostname-override
参数覆盖。 - ExternalIP:外部路由地址(可以从集群外面访问)。
- InternalIP:内部路由地址。
执行describe node命令后,得到的地址示例如下:
Addresses:
InternalIP: 192.168.65.4
Hostname: docker-desktop
状况
conditions字段描述了所有Running节点的状况。主要信息包括:
节点状况 | 描述 |
---|---|
Ready | 如节点是健康的并已经准备好接收 Pod 则为 True;False 表示节点不健康而且不能接收 Pod;Unknown 表示节点控制器在最近 node-monitor-grace-period 期间(默认 40 秒)没有收到节点的消息 |
DiskPressure | True 表示节点存在磁盘空间压力,即磁盘可用量低,否则为False |
MemoryPressure | True 表示节点存在内存压力,即节点内存可用量低,否则为False |
PIDPressure | True 表示存在进程压力,即节点上进程过多,否则为False |
NetworkUnavailable | True 表示节点网络配置不正确,否则为False |
执行describe node命令后,得到的节点状况示例如下:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Mon, 18 Jul 2022 09:27:23 +0800 Fri, 15 Jul 2022 16:30:29 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Mon, 18 Jul 2022 09:27:23 +0800 Fri, 15 Jul 2022 16:30:29 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Mon, 18 Jul 2022 09:27:23 +0800 Fri, 15 Jul 2022 16:30:29 +0800 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Mon, 18 Jul 2022 09:27:23 +0800 Fri, 15 Jul 2022 16:31:01 +0800 KubeletReady kubelet is posting ready status
如果使用命令行工具来打印不可调度节点的信息,其中的Condition字段可能包括
SchedulingDisabled
,该字段并不是Kubernetes API中定义的Condition。被保护的节点在其spec中被标记为Unschedulable
在Kubernetes API中,.status
也可用来描述节点的部分状况。如下表示一个健康节点:
"conditions": [
{
"type": "Ready",
"status": "True",
"reason": "KubeletReady",
"message": "kubelet is posting ready status",
"lastHeartbeatTime": "2019-06-05T18:38:35Z",
"lastTransitionTime": "2019-06-05T11:41:27Z"
}
]
如果节点状况类型为Ready
,而status
处于Unknown
或者False
状态,且时间超过了pod-eviction-timeout
的值(一个传递给kube-controller-manager的参数),则节点控制器会认为该节点不可用,从而对节点上的所有pod发起驱逐,默认的驱逐超时时间为5分钟。
如果节点通信不可达,驱逐命令无法被接收到到,则该节点上的pod会继续运行,直到该节点重新建立和API Server的连接为止。
节点控制器在确认pod在停止运行前,是不会强制删除它们的。因此在无法通信的节点上,你可能看到处于Terminating
或者 Unknown
状态的pod。在这种情况下,k8s无法主动删除该节点对象,可能需要管理员来手动删除。从k8s删除节点对象将导致API服务器删除节点上的所有运行的pod对象并释放它们的名称。
容量(Capacity)与可分配(Allocatable)
Capacity和Allocatable描述了节点上的可用资源:CPU、内存和可以调度到节点上的Pod的个数上限。
capacity
标识节点拥有的资源总量,allocatable
标识节点上可供普通pod消耗的资源量。
信息(Info)
Info指的是节点的一般信息,如内核版本、Kubernetes版本、容器运行时的详细信息,以及节点使用的操作系统。kubelet
从节点收集这些信息并将其发布到 Kubernetes API。
心跳
为了检测集群中节点的可用性,每个节点都会定期发送心跳。有两种形式的心跳:
- 更新节点的
.status
kube-node-lease
名字空间中的Least(租约)对象。每个节点都有一个关联的Lease对象。
与Node的.status
更新相比,Lease是一种轻量级资源。使用Lease来表达心跳在大型集群中可以减少这些更新对性能的影响。
kubelet负责创建和更新节点的.status
的Lease。更新机制如下:
- 当节点状态发生变化或者在配置的时间间隔内没有更新事件时,kubelet就会更新
.status
。.status
更新的默认间隔为5分钟(比节点不可达事件的40s默认超时时间长很多)。 - kubelet会创建并默认每10s更新Lease对象。Lease对象的更新与Node的
.status
更新是独立的。如果Lease的更新操作失败,kubelet会采用指数回退机制,从200ms开始重试,最长重试间隔时间为7s。
节点控制器
节点控制器是Kubernetes的控制面组件,管理节点的方方面面。
节点控制器在节点的生命周期中扮演了多个角色。
第一个是当节点注册时,为它分配一个CIDR区段。
第二个是保持节点控制器内的节点列表与云服务商提供的可用机器列表同步。如果在云环境下运行,只要某个节点不健康,节点控制器就会询问云服务是否节点的虚拟机仍可用,如果不可用,节点控制器会将该节点从节点列表删除。
第三个是监控节点的健康状况。负责:
- 在节点不可达时,在Node的
.status
中更新Ready
状况为Unknown
。 - 如果节点在
pod-eviction-timeout
,也就是节点驱逐超时时间之后仍然状态异常,则认为该节点确实是不可达的,从而对该节点上的所有pod触发由API发起的驱逐操作。默认节点驱逐超时时间为5分钟。
默认情况下,节点控制器每5s检查一次节点状态,可以用kube-controller-manager
组件上的--node-monitor-perioed
参数来配置检查周期。
逐出速率限制
大部分情况下,节点控制器会把逐出速率限制在每秒--node-eviction-rate
个(默认为0.1)。这表示它每10秒钟内至多从一个节点驱逐pod。
当一个可用区域中的节点变为不健康时,节点的驱逐行为将发生改变。节点控制器会同时检查可用区域中不健康的节点的百分比:
- 如果不健康节点的比例超过
--unhealthy-zone-threshold
(默认为0.55),驱逐速率会降低。 - 如果集群较小(小于等于
--large-cluster-size-threshold
个节点,默认50),驱逐操作将会停止。 - 否则,驱逐速率将降低为
--secondary-node-eviction-rate
(默认0.01)每秒。
注意,以上这些数据的统计维度是针对可用区域来说的,而一个集群通常会跨多个可用区域。当某个可用区域整体出现故障时,工作负载可以转移到健康的可用区域。因此,如果一个可用区域中的所有节点都不健康时,节点控制器会以正常的速率--node-eviction-rate
进行驱逐操作。在搜有的可用区域都不健康时的极端情况下,节点控制器将假设控制面与节点间的连接出现了某些问题,它将停止所有驱逐动作。
节点控制器还负责驱逐运行在拥有NoExecute
污点的节点上的pod,除非这些pod能够容忍此污点。
资源容量跟踪
Node对象会跟踪节点上资源的容量(例如可用内存和CPU数量)。通过自注册机制生成的Node对象会在注册期间报告自身容量。如果你手动添加了Node,你就需要在添加节点时手动设置节点容量。
Kubernetes调度器保证节点上有足够的资源供其上的所有pod使用。它会检查节点上所有容器的请求的综合不会超过节点的容量。总的请求包括由kubelet启动的所有容器,但不包括由容器运行时直接启动的容器,也不包括不受kubelet控制的其他进程。
节点优雅关闭
特性版本:Kubernetes v1.21 [beta]。节点优雅关闭特性受GracefulNodeShutdown
开关控制,在1.21版本中是默认开启的。
kubelet会尝试检测节点系统关闭事件并终止在节点上运行的pods。在节点终止期间,kubelet保证pod遵从常规的pod终止流程。
节点优雅关闭特性依赖于systemd,因为它要利用systemd抑制器锁机制,在给定的期限内延迟节点关闭。
除了开关参数之外,还有两个参数shutdownGracePeriod
和shutdownGracePeriodCriticalPods
需要配置。在节点优雅关闭过程中,其实是分成两个阶段的,首先是终止常规pod,然后终止关键pod。第一个参数表示终止常规pod和终止关键pod的总的持续时间,而第二个参数则表示终止关键pod的持续时间。默认情况下这两个参数值为0,表示优雅关闭功能未开启。只有当配置了这两个值并且开关打开的情况下,节点优雅关闭才生效。
例如,如果开关打开,且设置了shutdownGracePeriod=30s
和 shutdownGracePeriodCriticalPods=10s
,当发出节点关闭指令后,kubelet将延迟30秒关闭节点:前20秒用于终止常规pod,后10秒用于终止关键pod。所有pod终止后才会关闭节点。
节点非优雅关闭
特性版本:Kubernetes v1.24 [alpha]。
节点关闭的操作可能无法被kubelet的节点关闭管理器检测到(比如shutdownGracePeriod
和shutdownGracePeriodCriticalPods
配置错误),此时该节点上的pod将不能被移动到新的正常节点上。这是因为已关闭节点上的kubelet已经不存在了,没办法终止pod,因此StatefulSet无法创建同名的新pod。如果pod使用了卷,则VolumnAttachments不会从原来的已关闭节点上删除,因此这些卷也无法挂载到新的正常节点上。
为了避免这种情况,用户可以手动将具有NoExecute
或NoSchedule
效果的node kubernetes.io/out-of-service
污点添加到节点上,标记其无法提供服务。如果在kube-controller-manager
上启用了NodeOutOfServiceVolumnDetach
开关,并且节点通过污点方式标记为无法提供服务,同时节点pod上没有设置对应的污点容忍度,那么这样的pod将被强制删除,关联的卷也会被分离。系统就可以在正常节点上重新恢复pod。
节点与控制面间的通信
下文将介绍控制面(准确地说是API服务器)和Kubernetes集群之间的通信路径。
节点到控制面
Kubernetes采用的是中心辐射型(Hub-and-Spoke)API模式。所有从节点(或运行于其上的pod)发出的API调用都终止于API服务器。其他的控制面组件都没有被设计为对外暴露的服务。
API服务器被配置在一个安全的HTTPS端口(通常为443)上监听远程连接请求,并启用一种或多种形式的客户端身份认证机制。
想要连接到API服务器的pod可以使用服务账号安全地进行连接。当pod被实例化时,Kubernetes自动把公共根证书和一个有效的持有者令牌注入到pod里。kubernetes服务(位于deafault名字空间中)配置了一个虚拟ip,用于(通过kube-proxy)转发请求到API服务器的HTTPS端口。
控制面组件也通过安全端口与集群的API服务器通信。
这样,从集群节点和节点上运行的 Pod 到控制面的连接的缺省操作模式即是安全的, 能够在不可信的网络或公网上运行。
控制面到节点
从控制面(API Server)到节点有两种主要的通信路径。第一种是从API服务器到集群中每个节点上运行的kubelet进程。第二种是从API服务器通过它的代理功能连接到任何节点、pod或服务。
API服务器到kubelet
从API服务器到kubelet的连接用于:
- 获取pod日志
- 连接(通过kubectl)到运行中的pod
- 提供kubelet的端口转发功能
这些连接终止于kubelet的HTTPS终端。默认情况下,API服务器不检查kubelet的服务证书。这使得此类连接容易受到中间人攻击,在非受信网络或公开网络上运行也是不安全的。
为了对这个连接进行认证,使用--kubelet-certificate-authority
标志给API服务器提供一个根证书,用作kubelet的服务证书。
如果无法实现这点,又要求避免在非受信网络或公共网络上进行连接,可在API服务器和kubelet之间使用SSH隧道。
最后,应该启用kubelet用户认证或鉴权来保护kubelet API。
API服务器到节点、pod和服务
从API服务器到节点、pod或服务的连接方式默认为纯HTTP方式,因此既没有认证,也没有加密。这些连接可通过给API URL中的节点、pod或服务名称添加前缀https:
来运行在安全的HTTPS连接上。不过这些连接既不会验证HTTPS末端提供的证书,也不会提供客户端证书。因此,虽然连接是加密的,仍无法提供任何完整性保证。这些连接目前还不能安全地在非受信网络或公共网络上运行。
Konnectivity服务
在之前的版本中,Kubernetes支持使用SSH隧道来保护从控制面到节点的通信路径。在这种配置下,API服务器建立一个集群中各节点的SSH隧道并通过这个隧道传输所有到kubelet、节点、pod或服务的请求。这一隧道保证通信不会被暴露到集群节点锁运行的网络之外。但目前此方式已被废弃,Konnectivity称为了替代服务。
Konnectivity是在Kubernetes v1.18 [beta] 版中引入的。作为SSH隧道的替代方案,Konnectivity服务提供了TCP层的代理,以便支持从控制面到集群的通信。Konnectivity服务包含两个部分:Konnectivity服务器和代理,分别运行在控制面网络和节点网络中。Konnectivity代理建立并维持到Konnectivity服务器的网络连接。启用Konnectivity服务之后,所有控制面到节点的通信都通过这些连接传输。
控制器
在自动化领域,控制回路是一个非终止回路,用于调节系统状态。
在kubernetes中,控制器通过监控集群的公共状态来将当前状态转变为期望的状态。
Kubernetes内置了一组控制器,运行在kube-controller-manager
内。这些内置的控制器提供了重要的核心功能。
Deployment控制器和Job控制器是Kubernetes内置控制器的典型例子。Kubernetes允许你运行一个稳定的控制平面,这样即使某些内置控制器失败了,控制平面的其他部分也会接替它们的工作。
你会发现某些控制器运行在控制面之外,它们是用来扩展kubernetes的。如果你愿意,你也可以自己编写新控制器,运行在pod中或者运行在kubernetes之外,具体方式取决于控制器的功能。
控制器模式
一个控制器至少追踪一种类型的Kubernetes资源。这些对象有一个代表期望状态的spec
字段。该资源的控制器负责确保其当前状态接近期望状态。
通过API服务器来控制
Job控制器是一个Kubernetes内置控制器的例子。内置控制器通过和集群API服务器交互来管理状态。
Job是一种Kubernetes资源,它运行一个或多个pod,来执行一个任务然后停止。
在集群中,当Job控制器拿到新任务时,它会保证一组Node节点上的kubelet可以运行正确数量的pod来完成任务。Job控制器不会自己运行pod或者容器,而是通知API服务器来创建或者移除pod。
直接控制
相比于Job控制器,有些控制器需要对集群外的一些东西进行修改。
例如,如果你使用一个控制回路来保证集群中有足够的节点,那么控制器就需要当前集群外的一些服务在需要时创建新节点。
和外部状态交互的控制器从API服务器获取到它想要的状态,然后直接和外部系统进行通信,并使当前状态更接近期望状态。
云控制管理器
使用云基础设施技术,你可以在公有云、私有云或者混合云环境中运行kubernetes。
首先回顾一下kubernetes的架构图:
在控制平面中,ccm(cloud-controller-manager)就是指云控制管理器,它允许你将集群连接到云提供商的API之上,并隔离云平台组件和集群内部的组件。
ccm组件是基于插件机制来构造的,这种机制使得不同的云厂商都能将其平台与kubernetes集成。
ccm以一组多副本的进程集合的形式运行在控制面中,通常表现为pod中的容器。每个ccm在同一进程中实现多个控制器。
云控制管理器的功能
云控制管理器中的控制器包括:节点控制器,路由控制器和服务控制器等。
节点控制器
节点控制器负责在云基础设施中创建了新服务器时为之更新Node对象。节点控制器从云服务商获取当前租户中主机的信息。
节点控制器执行以下功能:
- 使用从云平台API获取的对应服务器的唯一标识符更新Node对象
- 利用特定云平台的信息为Node对象添加注解和标签,例如节点所在的Region和所具有的资源(CPU、内存等)
- 获取节点的网络地址和主机名
- 检查节点的健康状况。如果节点无响应,控制器通过云平台API查看该节点是否已经从云中禁用、删除或终止。如果节点已经从云中删除,则控制器从Kubernetes集群中删除Node对象。
某些云驱动实现中,这些任务被划分到一个节点控制器和一个节点生命周期控制器中。
路由控制器
Route控制器负责适当地配置云平台中的路由,以便Kubernetes集群中不同节点上的容器之间可以互相通信。
具体实现取决于云驱动本身,路由控制器可能也会负责为pod网络分配IP地址块。
服务控制器
服务与受控的负责均衡器、IP地址、网络包过滤、目标健康检查等云基础设施组件集成。服务控制器与云驱动的API交互,以配置负载均衡器和其他基础设施组件。你所创建的Service资源会需要这些组件服务。
鉴权
本节介绍云控制器为了完成自身的工作而产生的对各类API对象的访问需求。
节点控制器
节点控制器只操作Node对象。它需要读取和修改Node对象的完全访问权限。包括:
GET/LIST/Create/Update/Patch/Watch/Delete
路由控制器
路由控制器会监听Node对象的创建事件,并据此配置路由设施。它需要读取Node对象的Get权限。
服务控制器
服务控制器监测Service对象的Create、Update和Delete事件,并配置对应服务的Endpoints对象。
为了访问Service对象,它需要List和Watch访问权限。为了更新Service对象,它需要Patch和Update访问权限。
为了能够配置Service对应的Endpoints资源,它需要Create、List、Get、Watch和Update等访问资源。
其他
在云控制管理器的实现中,其核心部分需要创建Event对象的访问权限,包括Create、Patch和Update,还需要ServiceAccount的Create权限。
垃圾收集
垃圾收集是Kubernetes用于清理集群资源的各种机制的统称。垃圾收集允许系统清理如下资源:
- 失败的Pod
- 已完成的Job
- 不再存在属主引用的对象
- 未使用的容器和容器镜像
- 动态制备的、StorageClass回收策略为Delete的PV卷
- 阻滞或过期的CertificateSingingRequest(CSRs)
- 在以下情形中删除了的节点对象:(1)当集群使用云控制管理器运行于云端时;(2)当集群使用类似云控制管理器的插件运行于本地环境中时。
- 节点租约对象
属主和依赖
Kubernetes中很多对象通过属主引用链接到彼此。属主引用(Owner Reference)可以告诉控制面哪些对象依赖于其他对象。
Kubernetes使用属主引用来为控制面以及其他API客户端在删除某对象时提供一个清理关联资源的机会。在大多数场合,Kubernetes都是自动管理属主引用的。
属主关系与某些资源所使用的标签和选择算符不同。例如,考虑一个创建EndpointSlice
对象的Service对象。控制面可以通过标签来确定哪些EndpointSlice
对象被该Service使用。
除了标签,每个被Service托管的EndpointSlice
对象还有一个属主引用属性。属主引用可以帮助Kubernetes中的不同组件避免干预不属于它们控制的对象。
级联删除
Kubernetes会检查并删除那些不再拥有属主引用的对象,例如在你删除了ReplicaSet之后留下来的pod。当你删除某个对象时,你可以控制Kubernetes是否会自动删除该对象的依赖对象,这个过程称为级联删除(Cascading Deletion)。级联删除有两种类型,分别是前台级联删除和后台级联删除。
前台级联删除
在前台级联删除中,正在被你删除的属主对象首先进入deletion in progress状态。在这种状态下,针对属主对象会发生以下事情:
- Kubernetes API服务器将对象的
metadata.deletionTimestamp
字段设置为对象被标记要删除的时间点。 - Kubernetes API服务器也会将对象的
metadata.finalizers
字段设置为foregrounDeletion
。 - 在删除过程完成之前,通过Kubernetes API仍然可以看到该对象。
当属主对象进入删除过程中状态后,控制器删除其依赖对象。控制器在删除完所有依赖对象之后,删除属主对象。此时通过Kubernetes API就无法再看到该对象了。
在前台级联删除过程中,唯一可能阻止属主对象被删除的是那些带有ownerReference.blockOwnerDeletion=true
字段的依赖对象。
后台级联删除
在后台级联删除过程中,Kubernetes服务器立即删除属主对象,控制器在后台清理所有依赖对象。默认情况下,Kubernetes使用后台级联删除方案,除非手动设置了使用前台级联删除或者选择遗弃依赖对象。
被遗弃的依赖对象
当Kubernetes删除某个属主对象时,被留下来的依赖对象被称作遗弃的(Orphaned)对象。默认情况下,依赖对象会通过后台级联删除方式来删除,除非进行了显式的设置。
未使用的容器和镜像回收
kubelet会每5分钟对未使用的镜像执行一次垃圾收集,每分钟对未使用的容器执行一次垃圾收集。你应该避免使用外部的垃圾收集工具,因为外部工具可能会破外kubelet的行为,移除应该保留的容器。
要配置对未使用容器和镜像的垃圾收集选项,可以使用配置文件,基于KubeletConfiguration
资源类型来调整与垃圾搜集相关的kubelet行为。
容器镜像生命期
Kubernetes通过其镜像管理器来管理所有镜像的生命周期,该管理器是kubelet的一部分,工作时与cadvisor
协同。kubelet在做出垃圾收集决策时会考虑如下磁盘用量约束:
- HighThresholdPercent
- LowThresholdPercent
磁盘容量超出所配置HighThresholdPercent
值时会触发垃圾收集,垃圾收集器会基于镜像上次被使用的时间来按顺序删除它们。首先删除的是最老的镜像。kubelet会持续删除镜像,直到磁盘用量达到LowThresholdPercent
为止。
容器垃圾收集
kubelet会基于如下变量对所有未使用的容器执行垃圾收集操作,这些变量都是可以自定义的:
- MinAge: kubelet可以垃圾回收某个容器时该容器的最小年龄。设置为0表示禁用此规则。
- MaxPerPodContainer:每个Pod可以包含的已死亡的容器个数上限。设置为0表示禁用此规则。
- MaxContainers:集群中可以存在的已死亡的容器个数上限。设置为小于0的值表示禁用此规则。
除了受以上变量控制外,kubelet还会回收无标识的和已删除的容器,通常从最老的容器开始。
参考资料
[1]. https://kubernetes.io/zh/docs/concepts/overview/
[2]. https://blog.csdn.net/weichuangxxb/article/details/103754021
更多推荐
所有评论(0)