Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为 kube-scheduler 的组件执行。调度程序的决定,无论是否可以或不能调度容器,都由其可配置策略指导,该策略包括一组规则,称为 谓词 和 优先级 。调度程序的决定受到其在第一次调度时出现新pod时的Kubernetes集群视图的影响。由于Kubernetes集群非常动态且状态随时间而变化,因此可能需要将已经运行的pod重新调试到其它节点上,已达到节点使用资源平衡。
kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群 控制面 的一部分。
对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler 会选择一个最优的 Node 去运行这个 Pod。然而,Pod 内的每一个容器对资源都有不同的需求,而且 Pod 本身也有不同的资源需求。因此,Pod 在被调度到 Node 上之前,根据这些特定的资源调度需求,需要对集群中的 Node 进行一次过滤。
在一个集群中,满足一个 Pod 调度请求的所有 Node 称之为 可调度节点 。如果没有任何一个 Node 能满足 Pod 的资源请求,那么这个 Pod 将一直停留在未调度状态直到调度器能够找到合适的 Node。
调度器先在集群中找到一个 Pod 的所有可调度节点,然后根据一系列函数对这些可调度节点打分,然后选出其中得分最高的 Node 来运行 Pod。之后,调度器将这个调度决定通知给 kube-apiserver,这个过程叫做 绑定 。
在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。
kube-scheduler 给一个 pod 做调度选择包含两个步骤:
因此,可能会在群集中不太理想的节点上安排多个pod。 Descheduler 根据其政策,发现可以移动并移除它们的pod。请注意,在当前的实现中,Descheduler 不会安排更换被驱逐的pod,而是依赖于默认的调度程序。
这就是本文想讲的 Descheduler 项目,根据该项目二次调度策略来解决上面所说的问题。具体策略说明如下:
该策略确保只有一个Pod与在同一节点上运行的副本集(RS),Replication Controller(RC),Deployment或Job相关联。如果还有更多,则将这些重复的容器逐出,以更好地在群集中扩展容器。如果某些节点由于任何原因而崩溃,并且它们上的Pod移至其他节点,导致多个与RS或RC关联的Pod(例如在同一节点上运行),则可能发生此问题。一旦出现故障的节点再次准备就绪,便可以启用此策略以驱逐这些重复的Pod。当前,没有与该策略关联的参数。要禁用此策略,策略应如下所示:
该策略发现未充分利用的节点,并且如果可能的话,从其他节点驱逐pod,希望在这些未充分利用的节点上安排被驱逐的pod的重新创建。此策略的参数配置在 nodeResourceUtilizationThresholds 。
节点的利用率低是由可配置的阈值决定的 thresholds 。 thresholds 可以按百分比为cpu,内存和pod数量配置阈值 。如果节点的使用率低于所有(cpu,内存和pod数)的阈值,则该节点被视为未充分利用。目前,pods的请求资源需求被考虑用于计算节点资源利用率。
还有另一个可配置的阈值, targetThresholds 用于计算可以驱逐pod的潜在节点。任何节点,所述阈值之间, thresholds 并且 targetThresholds 被视为适当地利用,并且不考虑驱逐。阈值 targetThresholds 也可以按百分比配置为cpu,内存和pod数量。
这些阈值 thresholds 和 targetThresholds 可以根据您的集群要求进行调整。这是此策略的策略示例:
与该 LowNodeUtilization 策略相关的另一个参数称为 numberOfNodes 。仅当未充分利用的节点数大于配置的值时,才可以配置此参数以激活策略。这在大型群集中很有用,其中一些节点可能会频繁使用或短期使用不足。默认情况下, numberOfNodes 设置为0。
该策略可确保从节点中删除违反Interpod反亲和关系的pod。例如,如果某个节点上有 podA ,并且 podB 和 podC (在同一节点上运行)具有禁止它们在同一节点上运行的反亲和规则,则 podA 将被从该节点逐出,以便 podB 和 podC 正常运行。当 podB 和 podC 已经运行在节点上后,反亲和性规则被创建就会发送这样的问题。目前,没有与该策略关联的参数。要禁用此策略,策略应如下所示:
此策略可确保从节点中删除违反节点关联的pod。例如,在nodeA上调度了podA,它在调度时满足节点关联性规则 requiredDuringSchedulingIgnoredDuringExecution ,但随着时间的推移,nodeA不再满足该规则,那么如果另一个节点nodeB可用,它满足节点关联性规则,那么podA将被逐出nodeA。策略文件如下所示:
该策略可以确保从节点中删除违反 NoSchedule 污点的 Pod 。例如,有一个名为 podA 的 Pod ,通过配置容忍 key=value:NoSchedule 允许被调度到有该污点配置的节点上,如果节点的污点随后被更新或者删除了,则污点将不再被 Pod 的容忍满足,然后将被驱逐,策略文件如下所示:
当 Descheduler 程序决定从节点驱逐 Pod 时,它采用以下常规机制:
Descheduler 可以在k8s集群中作为 Job 或 CronJob 运行。它的优点是可以多次运行而无需用户干预。该调度程序容器在 kube-system 命名空间中作为关键容器运行,以避免被自身或kubelet逐出。
例如:
可以停止POD的申请,你可以进行关闭。
因为Pod作为在集群的节点上运行的进程,所以在不再需要的时候能够优雅的终止掉是十分必要的(比起使用发送KILL信号这种暴力的方式)。用户需要能够放松删除请求,并且知道它们何时会被终止,是否被正确的删除。用户想终止程序时发送删除pod的请求,在pod可以被强制删除前会有一个宽限期,会发送一个TERM请求到每个容器的主进程。一旦超时,将向主进程发送KILL信号并从API server中删除。如果kubelet或者container manager在等待进程终止的过程中重启,在重启后仍然会重试完整的宽限期。
示例流程如下:
用户发送删除pod的命令,默认宽限期是30秒;
在Pod超过该宽限期后API server就会更新Pod的状态为“dead”;
在客户端命令行上显示的Pod状态为“terminating”;
跟第三步同时,当kubelet发现pod被标记为“terminating”状态时,开始停止pod进程:
如果在pod中定义了preStop hook,在停止pod前会被调用。如果在宽限期过后,preStop hook依然在运行,第二步会再增加2秒的宽限期;
向Pod中的进程发送TERM信号;
跟第三步同时,该Pod将从该service的端点列表中删除,不再是replication controller的一部分。关闭的慢的pod将继续处理load balancer转发的流量;
过了宽限期后,将向Pod中依然运行的进程发送SIGKILL信号而杀掉进程。
Kublete会在API server中完成Pod的的删除,通过将优雅周期设置为0(立即删除)。Pod在API中消失,并且在客户端也不可见。
尼尔机械纪元dlcpod皮肤可以在Steam商店上购买。Steam是一个数字娱乐平台,提供了大量的游戏,包括尼尔机械纪元dlcpod皮肤。您可以在Steam上购买尼尔机械纪元dlcpod皮肤,并且可以获得更多的游戏特权和优惠。
众所周知,Pod是Kubernetes 中创建和管理的、最小的可部署的计算单元。已经有了容器概念,为什么要抽象一个pod组件来增加认知的成本?k8s 抽象出Pod主要是为解决以下两类问题:
Pod可以分成动态Pod和静态Pod,动态Pod又可以分为自主式的Pod和控制器管理的Pod
Pod中容器按功能特点可以分为以下四类:
Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行,通过 specinitContainers 指定。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本,用于在Pod应用容器启动之前做一些额外工作。
ctr -n k8sio c ls 发现一些名为pause的容器,为什么会有这么多pause容器呢?
k8s 创建pod是,都会为每个pod创建一个特殊的pause容器,该pause容器作pod中所有容器的父容器,用于实现共享命名空间,对pod中的容器的进程的管理
一种特殊的容器,该容器在现有Pod中临时运行,以便完成用户发起的 *** 作,例如故障排查。 你会使用临时容器来检查服务,而不是用它来构建应用程序。
当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用
1在 Kubernetes 的各个组件中开启特性。
也可以创建Pod的拷贝方式,会产生一个Pod=my-debugger-pod
查看临时容器
实际跑业务的容器,包含sidecar容器,sidecar代理本身也是业务;当然也有人把sidecar容器和应用容器区分开,但是不影响我们对Pod容器的理解
k8s中的最小部署单元,不是一个程序/进程,而是一个环境(包括容器、存储、网络ip:port、容器配置)。其中可以运行1个或多个container(docker或其他容器),在一个pod内部的container共享所有资源,包括共享pod的ip:port和磁盘。
pod是临时性的,用完即丢弃的,当pod中的进程结束、node故障,或者资源短缺时,pod会被干掉。基于此,用户很少直接创建一个独立的pods,而会通过k8s中的controller来对pod进行管理。
controller通过pod templates来创建pod,pod template是一个静态模板,创建出来之后的pod就跟模板没有关系了,模板的修改也不会影响现有的pod。
由于pod是临时性的,pod的ip:port也是动态变化的。这种动态变化在k8s集群中就涉及到一个问题:如果一组后端pod作为服务提供方,供一组前端的pod所调用,那服务调用方怎么自动感知服务提供方。这就引入了k8s中的另外一个核心概念,services
service是通过apiserver创建出来的对象实例
pod 与 service 关系:
Service定义了pods的逻辑集合和访问这个集合的策略。 Pods集合是通过定义Service时提供的Label选择器完成的
Service的引入旨在保证pod的动态变化对访问端透明,访问端只需要知道service的地址,由service来提供代理
Service的抽象使得前端客户和后端Pods进行了解耦
支持ClusterIP, NodePort以及LoadBalancer三种类型
Service的底层实现有userspace、 iptables和ipvs三种模式
pod 跟service可以通过label来筛选。
Label其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够标示对象的特殊特点,Labels的值对系统本身并没有什么含义,只是对用户才有意义。同一个资源对象的labels属性的key必须唯一,label可以附加到各种资源对象上,如Node,Pod,Service,RC等。一个资源拥有多个标签,可以实现不同维度的管理。标签(Label)的组成: key=value。Label可以在创建对象时就附加到对象上,也可以在对象创建后通过API进行额外添加或修改。
如果想知道某个service关联哪些pods是,
可以先: helm -l
kubectl get svc xxx -nyyy --show-labels
得到label, 然后通过
kubectl get pod -nxx -l {labelname}
反过来也一样。
先看pod的,再查svc
服务发现
服务使用方如何找到我们定义的Service 在k8s中用了两个方案,环境变量 && DNS。
1、环境变量:每当有service被创建出来之后,各个node(宿主机)上的kubelet,就会把service name加到自己宿主机的环境变量中,供所有Pod使用。环境变量的命名规则是{SERVICE_NAME}_SERVICE_HOST, ${SERVICE_NAME}SERVICE_PORT,其中SERVICE_NAME是新serviceName的大写形式,serviceName中的横杠-会被替换成下划线
使用环境变量有一个隐含的创建顺序,即服务使用方在通过环境变量访问一个service的时候,这个service必须已经存在了。
这么简单粗暴的方案这样做有个好处,就是省的自己搞名字解析服务,相当于本地的agent做了“域名劫持”。serviceName对应到上文提到的,由kube-proxy提供的vip:port上
Pod是一个或一个以上的 容器(例如Docker容器)组成的,且具有共享存储/网络/UTS/PID的能力,以及运行容器的规范。并且在kubernetes中,Pod是最小的可被调度的原子单位。
通俗来讲,Pod就是一组容器的集合,在Pod里面的容器共享网络/存储(kubernetes实现共享一组的namespace去替代每个container各自的NS,来实现这种能力),所以它们可以通过localhost进行内部的通信。虽然网络存储都是共享的,但是cpu和memory就不是。多容器之间可以有属于自己的cgroup,也就是说我们可以单独的对Pod中的容器做资源(MEM/CPU)使用的限制。
Pod就像是我们的一个”专有主机”,上面除了运行我们的主应用程序之外,还可以运行一个与该应用紧密相关的进程。如日志收集工具、git文件拉取器、配置文件更新重启器等。因为在kubernetes中,一个Pod里的所有container都只会被分配到同一台主机上运行。
以上就是关于Descheduler 实现 K8S Pod 二次调度全部的内容,包括:Descheduler 实现 K8S Pod 二次调度、是否允许pod的停止申请、尼尔机械纪元dlcpod皮肤在哪等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)