k8s-调度

调度

在这里插入图片描述
从上面的架构图我们可以看到,调度是工作在Master,负责调度Pod,为POD分配Node。

调度的工作原理
#查看所有的Node
kubectl get nodes 

在这里插入图片描述
我们可以看到节点有一个Name,这就是调度的关键。
调度的步骤:
1 创建POD的时候每一个POD都会有一个叫NodeName的字段,默认情况下是不进行设置的。
2 调度器开始扫描POD,找到没有设置NodeName的POD,代表这它没有进行调度。
3 调度器通过运行调度算法为pod分配正确的节点。一旦确定节点,调度器会创建一个绑定对象binding,将NodeName设置为分配节点的名称,从而在该节点上调度pod。
如果没有调度器,我们可以在创建Pod的时候进行节点的指定:

apiVersion: v1
kind: Pod
metadata:name: nginx
spec:containers:- image: nginxname: nginxnodeName: node01  
#替换原有的资源,也就是会重新创建
kubectl replace --force -f nginx.yaml

那如果我们POD已经创建了,Kubernetes不允许修改pod的NodeName属性,这个时候我们可以通过下面这个方法进行修改:
1 创建一个Binding绑定对象,并向pod的绑定API发送一个POST请求,从而模仿实际调度程序的做法。

apiVersion: v1
kind: Binding
metadata:name: nginx
target:apiVersion: v1kind: Nodename: ……

2 在绑定对象中,用NodeName指定一个目标节点,然后向pod的绑定API发送一个POST请求,将数据以JSON格式设置到绑定对象中(必须将YAML文件转换为等效的JSON形式)。也是就是说name这个字段需要填一个json数据。

上面这个方式比较复杂,所以工作中一般不使用,而使用下面这个方法,而是结合后面的元信息调度来控制.

元信息调度

Label & Selector
对Kubernetes来说,pod、 service、 replicaset、 deployment都是不同的对象。集群中可能会有成百上千个这样的对象。需要按不同类别筛选和查看对象的方法,例如按对象类型进行分组,或者按应用程序或功能查看,这样的操作都是通过Label来实现的。

apiVersion: apps/v1
kind: ReplicaSet
metadata:name: myapp-rslabels:  #ReplicaSet本身的Labelapp: myapptype: myservice
spec:replicas: 3selector: matchLabels:type: myservice #选择器匹配的Label,通过这个Label取选择对应的Podtemplate:metadata:name: myapp-podlabels: app: myapptype: myservice #模板的label 这个label要和上面选择器的label保持一致这样就可以选择到这个PODspec:containers:- name: nginximage: nginx
#查标签上有type=nginxservice 的pod
kubectl get po --selector type=nginxservice

在这里插入图片描述
我们查询到的结果如下:
在这里插入图片描述

#可以统计数量 看这个标签选中了多少pod
kubectl get po --selector type=nginxservice --no-headers | wc -l
kubectl get po --selector type=nginxservice | wc -l
#这些标签是and的关系
kubectl get po --selector type=nginxservice,app=nginxapp

在这里插入图片描述
Annotation
label与选择器用于编组与选择对象,而注释用于记录其他详细信息以提供信息。例如,如名称、 版本、 构建信息等

apiVersion: apps/v1
kind: ReplicaSet
metadata:name: myapp-rslabels: app: myapptype: myserviceannotations:buildVersion: 1.0
spec:replicas: 3selector: matchLabels:type: myservicetemplate:metadata:name: myapp-podlabels: app: myapptype: myservicespec:containers:- name: nginximage: nginx

Taints污点 & Tolerations容忍度
Taints污点和Tolerations容忍度的概念运用在如何限制将哪些Pod放置在哪些节点上,用于设置节点上可调度的pod的限制。
创建pod后,Kubernetes调度程序会尝试将这些pod放置在可用的工作节点上。一开始调度程序将pod放置在所有节点上,达到负载均衡。
现在,假设我们在node1上为特定用例或应用程序提供了专用资源(比如只有Node1安装了GPU 或者Node1有第三方依赖)。因此,我们希望仅将属于此应用程序的那些pod放置在node1上。
总结一下:
Taints污点 :这个是为Node 打上一个污点,打好了这个污点,如果POD上设置可以容忍这个污点,才能在这个Node上进行调度。
Node污点有三个策略:

  • NoSchedule 无调度,这意味着node上不会调度Pod。
  • PreferNoSchedule,这意味着系统将尝试避免在node上放置Pod,但并不保证。
  • NoExecute不执行,这意味着新的pod将不会在node上调度,并且如果node上的现有pod(如果有的话)不能容忍taint,则将被逐出。
    Tolerations容忍度:设置这个POD可以容忍某个污点,那么这个时候POD依然可以在污点的Node上进行调度。
    实践
    1 污点设置
#这个时候不会影响pod的运行 因为无调度
kubectl taint nodes minikube type=nginxservice:NoSchedule 
#我们指定minikube 节点上 label中有type=nginxservice 的pod不能再这个节点运行
kubectl taint nodes minikube type=nginxservice:NoExecute

NoExecute的时候会发现所有的节点都被挂起了,这里myapp-deployment没有被驱逐使用为这个myapp-deployment是Deployment,它要保证有三个节点,两个策略产生了冲突,所以最终被挂起。
在这里插入图片描述
为了证明上面这一点,我们单独起一个Nginx Pod 并打上标签type=nginxservice
1)创建一个nginx pod

apiVersion: v1
kind: Pod
metadata:name: testTaintlabels:app: myapptype: nginxservice
spec:containers:- name: nginximage: nginx

2)依次执行命令

#创建一个pod
kubectl  apply -f pod-ngix.yml
#打上污点
kubectl taint nodes minikube type=nginxservice:NoExecute
kubectl get pods

我们发现testtaint被驱逐了
在这里插入图片描述
这里要注意单独的pod和deployment不同,单读的pod被驱即使后面这个污点去除了,这个pod也不一定马上就会回来继续运行

#移除这个污点
kubectl taint nodes minikube type=nginxservice:NoExecute-

我们发现这些节点又恢复了运行
在这里插入图片描述
2 容忍度设置

apiVersion: v1
kind: Pod
metadata:name: terapp
spec:containers:- name: nginximage: nginxtolerations:- key: "type"operator: "Equal" #这些字段必须都是双引号value: "nginxservice"effect: "NoSchedule"

在这里插入图片描述
我们可以看到虽然节点上有污点,但是我们设置了可以容忍,所以这个节点仍然部署成功了
在这里插入图片描述
注意:生产中就算设置了这个容忍度也不一定会在这个节点上,因为调度算法不一定会把这个节点调度到这里,如果调度到了这里那么会按照容忍污点部署成功

Node Selector
#给Node 打一个size=Large的标签
kubectl label nodes node1 size=Large

在创建的时候使用NodeSelector进行选择

apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels: app: myapptype: myservice
spec:containers:- name: nginximage: nginxnodeSelector:size: Large
Node Affinity 节点亲和性

在这里插入图片描述
这两种策略都是如果容器在运行中忽略,也就是如果在运行中发生了节点关联性的修改则不会影响这个pod的运行,它会和以前一样继续运行

提供了更灵活的方式,来选择节点。
pod的生命周期中有两种状态:Scheduling调度期和Execution执行期
Scheduling调度期是指pod不存在,且是首次创建的状态。在首次创建pod时,kubernetes会考虑节点亲和规则

  • required:调度程序将强制将pod放置在具有给定关联性规则的节点上。
  • preferred:调度程序将尽力将pod放置在匹配的节点上。如果未找到匹配的节点,则调度程序将忽略节点关联性规则,并将单元放置在任何可用节点上
apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels: app: myapptype: myservice
spec:containers:- name: nginximage: nginxaffinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: size #节点标签operator: In #代表节点标签在 下面这些values里面values:- Large - MoreLarge
key: size
operator: NotIn #和上面等价 假如我们有三种标签 Large  MoreLarge Small
values:
- Small
#针对只存在key 不存在值的标签
key: controlplane
operator: Exists

资源限制

前面我们学过命令空间的资源限制

apiVersion: v1
kind: ResourceQuota
metadata:name: compute-quotanamespace: dev #指定限制的namespace
spec:hard: #这里有两种模式 一种是硬性限制 另一种是软限制(可以超)pods: "10" #限制pod数量最多是10个requests.cpu: "4" #限制cpu申请的时候为4个requests.memory: 5Gi #限制内存limits.cpu: 10 #使用限制limits.memory: 10Gi #使用限制

Pod的资源限制

apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels: app: myapptype: myservice
spec:containers:- name: nginximage: nginxresources:requests:memory: "1Gi"cpu: 1limits:memory: "2Gi"cpu: 2

limit和request是为pod内的每个container设置的。

  • requests:容器要申请的资源,要求Kubernetes在创建Pod的时候必须分配这里列出的资源,否则容器就无法运行。
  • limits:容器使用资源的上限,不能超过设定值,否则就有可能被强制停止运行。

在调度的时候,scheduler 只会按照 requests 的值进行计算。而执行期间,在真正设置 Cgroups 限制的时候,kubelet 则会按照 limits 的值来进行设置。

DaemonSet 守护进程集

Deployment会创建多个POD实例,但是这些实例会被分配到不同的节点,有些Node可能存在多个POD实例。就比如下面图中绿色的节应用。
在这里插入图片描述
那如果现在需要在集群的每个节点部署一个监控或者日志收集器。这个时候就需要用到DaemonSet 。
DaemonSet 很多时候比整个 Kubernetes 集群出现的时机都要早。

apiVersion: apps/v1
kind: DaemonSet
metadata:labels:app: elasticsearchname: elasticsearchnamespace: kube-system
spec:selector:matchLabels:app: elasticsearchtemplate:metadata:labels:app: elasticsearchspec:containers:- image: registry.k8s.io/fluentd-elasticsearch:1.20name: fluentd-elasticsearchtolerations:- key: node-role.kubernetes.io/controlplane effect: NoScheduleoperator: Exists

DaemonSet的设计上是每个节点上部署一个,但是control-plane的设计是控制节点不承担常规工作负载。二者存在冲突,Kubernetes使用了污点(taint)和容忍度(toleration)来避免。也就是这段配置

tolerations:
- key: node-role.kubernetes.io/controlplane effect: NoScheduleoperator: Exists

Static Pod 静态Pod

资料来源
在这里插入图片描述
我们可以看到整个Kubernetes集群架构可以分为Master和Worker Master负责调度管理,Worker负责运行实例。

如果没有API-server,scheduler,controller和etcd集群会怎么样?
单独存在的Kubelet可以独立管理一个节点,并且创建Pod。但是没有API-server来提供pod详细信息。
Kubelet可以从所在服务器上指定用于存储Pod信息的目录中读取Pod定义文件。

静态Pod不受 Kubernetes 系统的管控,不与 apiserver、scheduler 发生关系,所以是static静态。

cat /var/lib/kubelet/config.yaml | grep staticPodPath
# staticPodPath: /etc/kubernetes/manifests

静态Pod的YAML文件默认都存放在节点的 /etc/kubernetes/manifests 目录下,它是 Kubernetes 的专用目录。Kubelet会定期检查此目录中的文件,读取这些文件并在主机上创建Pod。并且保持Pod在线;如果程序崩溃,Kubelet会尝试重新启动它。
也就是说我们可以定义pod的yml文件到这个目录下,这些pod就会被识别和创建
对此目录中的任何文件进行更改,Kubelet将重新创建Pod使更改生效。
如果从该目录中删除文件,则Pod将自动删除。
这些由Kubelet自行创建的pod(无需API服务器或其余Kubernetes集群组件的干预)被称为静态pod。
PS,只能以这种方式创建Pod。不能通过将定义文件放在指定目录中来创建replicaset、deployment或service。它们都是整个Kubernetes架构的概念组成部分,需要replica和deployment controller等其他集群组件。

Kubelet在pod级别工作,只能理解pod,只能够以这种方式创建静态pod。

指定的静态Pod文件夹可以是主机上的任何目录,该目录的位置在运行服务时作为一个选项传递kubelet。

/usr/local/bin/kubelet \
--container-runtime=remote \\
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
--pod-manifest-path=/etc/Kubernetes/manifests \\ #指定静态pod文件所属的目录
--kubeconfig=/var/lib/kubelet/kubeconfig \\
--network-plugin=cni \\
--register-node=true \\
--v=2

另一种配置方法,可以修改config.yaml,并在该文件中将目录路径定义为静态pod路径。

cat /var/lib/kubelet/config.yaml | grep staticPodPath

为什么要使用静态Pod

静态Pod不依赖于Kubernetes控制平面,可以使用静态Pod将控制平面组件本身作为Pod部署在节点上。

在所有主节点上安装kubelet,然后创建pod定义文件,该文件使用各种控制平面组件的Docker镜像。
将定义文件放在指定的manifest文件夹中,Kubelet负责将控制平面组件本身作为pod部署到集群上。

ls -al /etc/kubernetes/manifests/
# -rw------- 1 root root 2376 Feb 19 00:23 etcd.yaml
# -rw------- 1 root root 3854 Feb 19 00:23 kube-apiserver.yaml
# -rw------- 1 root root 3370 Feb 19 00:23 kube-controller-manager.yaml
# -rw------- 1 root root 1440 Feb 19 00:23 kube-scheduler.yaml

Kubernetes 的 4 个核心组件 apiserver、etcd、scheduler、controller-manager 原来都以静态 Pod 的形式存在的,所以能够先于 Kubernetes 集群启动。
如果服务中的任何一个崩溃,kubelet会重新启动它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/650678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

老板为何都对项目经理毕恭毕敬!因为这个职位一念成佛一念成魔

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 老板为何都对项目经理毕恭毕敬!因为这个职位一念成佛一念成魔 曾几何时&am…

Linux:命名管道及其实现原理

文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道,但是匿名管道有一个很严重的问题,它只允许具有血缘关系的进程进行通信,那如果是两个不相关的进程进行通信&#xff0…

《佛法修学概要》009-012集研讨

课程摘要 9、只有走出心中的妄想,才可能接觸彌陀的光明! 佛陀在經典裡講出一個譬喻,說有一座動物園,這座動物園關了很多動物。其中有一隻袋鼠,就是澳洲那種很會跳的袋鼠。動物園的管理員,給牠圈了一個十公尺…

《合成孔径雷达成像算法与实现》Figure5.16

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

【vue oidc-client】invalid_requestRequest Id: 0HN0OOPFRLSF2:00000002

需求:完成统一登录,需要从三方平台跳到我们的平台。 oidc-client报错记录。这个一般是配置信息出错,需要和三方平台进行沟通,一定要把client_id,密钥进行对应; 同时关于此次出错还修改了以下代码&#xff…

主成分分析(PCA)Python

实际问题研究中,常常遇到多变量问题,变量越多,问题往往越复杂,且各个变量之间往往有联系。于是,我们想到能不能用较少的新变量代替原本较多的旧变量,且使这些较少的新变量尽可能多地保留原来变量所反映的信…

按配置数据绘制配置型地图marker的icon,自定义marker

一、需求 需要自定义配置数据的marker&#xff0c;其中图片内容要灵活可配置自动生成。此处项目用的百度地图。 效果图&#xff1a; 二、思路 用背景图canvas绘制数字的方式生成icon的图片资源。 再将icon生成对应地图marker。 三、代码 canvasImg.js <!-- * descrip…

进程地址空间(Linux)

进程地址空间 一、引入概念1. 程序的地址分布2. 线性地址和物理地址 二、进程地址空间1. 初步认识2. 地址空间和物理内存的联系3. 区域划分4. 拓展——关于“线” 三、进一步理解进程地址空间四、页表总结 一、引入概念 1. 程序的地址分布 测试代码&#xff1a; #include &l…

Nginx安装以及具体应用

文章目录 Centos7安装NginxNginx命令Nginx具体应用反向代理 location指令说明负载均衡动静分离 Nginx.conf配置详解 Centos7安装Nginx 下载地址&#xff1a;nginx: download 中间这个就是tar.gz包 Centos7安装Nginx 下载nginx-1.16.1.tar.gz上传到Centos7中的/user/local目…

java8 流到底是什么呢?

引入背景&#xff1a; 1、想像写SQL那样操作集合 2、为了提高性能&#xff0c;需要并行处理&#xff0c;并利用多核架构 流到底是什么呢&#xff1f; 流是Java API的新成员&#xff0c;它允许你 以声明性方式处理数据集合&#xff08;通过查询语句来表达&#xff0c;而不是临时…

springboot+vue3组合,对接支付宝付款第一节:内网穿透

springbootvue3组合,对接支付宝付款第一节:内网穿透&#xff01;接下来会为大家展示&#xff0c;使用java的springboot搭建一个简单的后台。提供业务接口。实现在线下单&#xff0c;支付。支付宝付款的案例。 前端页面布局我们使用vue3element-plus来实现绘制。 今天是第一个…

海康实时监控预览视频流接入web

我们采取的方案是后端获取视频流返回给前端&#xff0c;然后前端播放 海康开放平台海康威视合作生态致力打造一个能力开放体系、两个生态圈&#xff0c;Hikvision AI Cloud开放平台是能力开放体系的核心内容。它是海康威视基于多年在视频及物联网核心技术积累之上&#xff0c;…

Jmeter连接数据库报错Cannot load JDBC driver class‘com.mysql.jdbc.Driver’解决

问题产生: 我在用jmeter连接数据库查询我的接口是否添加数据成功时,结果树响应Cannot load JDBC driver class com.mysql.jdbc.Driver 产生原因: 1、连接数据库的用户密码等信息使用的变量我放在了下面,导致没有取到用户名密码IP等信息,导致连接失败 2、jmeter没有JDB…

CodeGPT--(Visual )

GitCode - 开发者的代码家园 gitcode.com/ inscode.csdn.net/liujiaping/java_1706242128563/edit?openFileMain.java&editTypelite marketplace.visualstudio.com/items?itemNameCSDN.csdn-codegpt&spm1018.2226.3001.9836&extra%5Butm_source%5Dvip_chatgpt_c…

Elasticsearch介绍以及基本操作

目录 一、Elasticsearch介绍 二、关于Elasticsearch的基本操作 &#xff08;1&#xff09;索引操作 &#xff08;2&#xff09;文档操作 三、域的属性 &#xff08;1&#xff09;index &#xff08;2&#xff09;type &#xff08;3&#xff09;store 一、Elasticsearc…

使用Go语言编写安全的HTTP代理服务器

构建一个安全的HTTP代理服务器是至关重要的&#xff0c;因为这可以保护用户的数据和隐私。让我们来看看如何使用Go语言编写一个安全的HTTP代理服务器。 首先&#xff0c;确保你的代理服务器使用HTTPS协议进行通信。HTTPS使用SSL/TLS加密来保护数据传输&#xff0c;可以确保数据…

源聚达科技:抖店的专营店怎么开

在数字化浪潮的推动下&#xff0c;抖音平台不仅为人们提供了丰富的娱乐内容&#xff0c;也成为了电商的新战场。不少创业者和品牌商纷纷选择在抖音上开设自己的专营店&#xff0c;以此抓住流量红利&#xff0c;拓宽销售渠道。那么&#xff0c;如何在抖音平台上成功开设一家专营…

每日一题——LeetCode1346.检查整数及其两倍数是否存在

方法一 循环查找 用indexOf查找每个元素的两倍是否存在在数组中&#xff0c;找到了就直接return true&#xff0c;循环结束还没找到就return false var checkIfExist function(arr) {for(let i0;i<arr.length;i){let index arr.indexOf(arr[i]*2)if(index>0 &&…

听力下降为什么会影响到言语感知?

一、听力障碍对阈值、听觉频率范围和分辨能力的影响 听力障碍使得听障者的听敏度降低&#xff0c;提高了阈值&#xff0c;不利于言语信号的接收。听障者听力阈值的变化在不同频率并不相同&#xff0c;一般而言&#xff0c;高频部分的听力损失往往大于低频部分&#xff0c;而言…

fatal error:require():Failed opening required

今天部署网站遇到了个错误 fatal error:require():Failed opening required 这个错误经常遇到 大多是网站 是开启了 open_basedir 但今天这个错误很神奇 先说解决方法 1. 检测一下是不是真的 不存在这个文件 即使100%确定 也建议你再仔细看一下 这个文件存不存在 今天我遇…