当前位置:首页 » 网络管理 » k8s如何删除节点的污点
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

k8s如何删除节点的污点

发布时间: 2022-10-06 15:05:07

⑴ K8S安装和创建集群终极教程(单master多worker)

本文会以 最简单 最直接 最完整 的方式记录kubernetes(下面统称K8S)单master多工作节点(worker nodes)的集群步骤

首先要简单了解一下本文的3个核心概念:

内存建议至少4G

问:如何查看主机名?

答:执行命令hostname

问:如何修改主机名?

答:永久生效的做法:执行命令vi /etc/hostname,把第一行去掉(不能注释掉,要去掉),然后重新写上自定义的主机名(注意命名规范),保存并重启后生效;

临时生效的做法:执行以下命令

问:如何查看MAC地址?

答:执行命令ip link,然后看你的第一网卡

问:如何查看proct_uuid?

答:执行命令sudo cat /sys/class/dmi/id/proct_uuid

注意:30000-32767这个端口范围是我们创建服务的端口必须要设置的一个范围(如果设置范围以外的会有限制提示并创建失败),这是K8S规定的。

另外,如果你要直接关闭防火墙可以执行

⑥必须禁用Swap

Swap total大于0,说明Swap分区是开启的

问:如何关闭Swap?

答:编辑文件/etc/fstab,在swap行前面加上#号注释, 保存并重启服务器

再次查看分区状态,已生效

常见的容器引擎(Container runtime,简称runtime):

本文使用的容器引擎是Docker

安装完成后查看版本:

当出现可能跟Docker引擎相关的奇怪异常时可以尝试把Docker卸载干净并重新安装,但一定要注意镜像、容器、卷或配置文件这些是否需要备份。

下面记录卸载Docker引擎的步骤:

①卸载 Docker Engine、CLI 和 Containerd 包:

②主机上的映像、容器、卷或自定义配置文件不会自动删除。删除所有镜像、容器和卷:

③配置文件如果有不合法的字符时会导致启动失败,我们需要将其删除然后重建

此时Docker引擎已卸载干净

官网用的是谷歌的yum源,因为国内是连不上的,所以这里替换成阿里提供的yum源

①安装

从安装信息中可以看到版本号是1.22

Installing:

kubeadm x86_64 1.22.4-0 kubernetes 9.3 M

kubectl x86_64 1.22.4-0 kubernetes 9.7 M

kubelet x86_64 1.22.4-0 kubernetes 20 M

②启动



这就是一个驱动程序,注意cgroup和cgroupfs不要混淆了

引用官方的一段话

“由于 kubeadm 把 kubelet 视为一个系统服务来管理,所以对基于 kubeadm 的安装, 我们推荐使用 systemd 驱动,不推荐 cgroupfs 驱动。”

kubeadm默认是使用systemd 驱动,而我们的Docker默认驱动是cgroupfs(docker info可以查看),所以需要将Docker的驱动改成systemd

①编辑Docker配置文件

②重启Docker服务

再次docker info查看驱动信息已变成了systemd

工作节点(worker nodes)的最小配置就到这里了

①镜像源参数说明

默认情况下, kubeadm 会从 k8s.gcr.io 仓库拉取镜像,国内是拉不了的。官方文档明确表示允许你使用其他的 imageRepository 来代替 k8s.gcr.io。

--image-repository 你的镜像仓库地址

接下来我找了一些国内的镜像源,并简单做了下分析

综合上述统计,我选择阿里云的镜像源

②ip地址范围参数说明

--pod-network-cidr =192.168.0.0/16

注意:如果192.168.0.0/16已经在您的网络中使用,您必须选择一个不同的pod网络CIDR,在上面的命令中替换192.168.0.0/16。

集群初始化命令:

因为我用的是演示机器,所以这里把完整的执行信息都贴出来方便查阅,平时工作中一定要注意保护好敏感的信息(我的ip地址范围是自定义的便于下面的功能演示,另外初次init需要下载镜像文件,一般需要等几分钟)

如上所示,集群初始化成功,此时一定要注意看上面执行结果最后的那部分操作提示,我已用标明了初始化成功后还需要执行的3个步骤

注意:如果init成功后发现参数需要调整,可以执行kubeadm reset,它的作用是尽最大努力恢复kubeadm init 或者 kubeadm join所做的更改。

To start using your cluster, you need to run the following as a regular user:

翻译:开始使用集群前,如果你是普通用户(非root),你需要执行以下的命令:

Alternatively, if you are the root user, you can run:

翻译:或者,如果你使用的是root,你可以执行以下命令:

(注意:export只是临时生效,意味着每次登录你都需要执行一次)

网络配置配的就是Pod的网络,我的网络插件选用calico

cidr就是ip地址范围,如果您使用 pod CIDR 192.168.0.0/16,请跳到下一步。

但本文中使用的pod CIDR是192.100.0.0/16,所以我需要取消对清单中的 CALICO_IPV4POOL_CIDR 变量的注释,并将其设置为与我选择的 pod CIDR 相同的值。(注意一定要注意好格式,注意对齐)

可根据需求自定义清单,一般不需要的就直接跳过这步

在所有的工作节点上执行join命令(复制之前初始化成功后返回的加入集群命令到所有的工作节点执行即可)

master上查看所有节点的状态

到这里集群已经创建完成

最后我再安装K8S的可视化界面kubernetes-dashboard,方便我们日常使用

①下载yaml文件

②修改yaml文件,新增type和nodePort,使服务能够被外部访问

③安装并查看运行情况

④新建用户

文件创建完成后保存并apply

⑤获取Token,用于界面登录

⑥登录dashboard

192.168.189.128是我的master服务器ip,另外要注意必须使用https,并且不能使用ie内核模式

复制⑤生成的token到输入框,点击登录

dashboard安装配置完成

问:如何在查看资源情况?

答:在master上执行以下命令可查看资源情况(-o wide是显示更详细的信息),

①查看所有节点

②查看所有命名空间

③查看命名空间下的pod

④查看所有命名空间的pod

⑤实时查看查看命名空间下的pod运行情况

问:kubeadm join 出现异常[ERROR Port-10250]: Port 10250 is in use,如何解决?

答:这是因为你之前join失败过了,需要先执行kubeadm reset再重新join

问:虚拟机上测试时网卡突然消失如何解决(题外问题记录)?

答:

①确认丢失的网卡信息,ens开头(可选步骤)

ifconfig -a

②执行以下命令解决

问:如何查看K8S版本?

答:kubectl version

问:join命令忘记或者过期了怎么办?

答:

生成永不过期的

生成时效24小时的

问:Pod不断重启并且无其它报错信息时怎么办?

答:这种情况通常是因为你的集群中只有master,没有worker节点,master的创建默认是有污点的,即不允许调度新的Pod,如果你需要(当然这并不推荐),就需要删除 master 上的污点。删除污点可以执行以下命令,

它应该返回以下内容。

⑵ Descheler 实现 K8S Pod 二次调度

Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为 kube-scheler 的组件执行。调度程序的决定,无论是否可以或不能调度容器,都由其可配置策略指导,该策略包括一组规则,称为 谓词 和 优先级 。调度程序的决定受到其在第一次调度时出现新pod时的Kubernetes集群视图的影响。由于Kubernetes集群非常动态且状态随时间而变化,因此可能需要将已经运行的pod重新调试到其它节点上,已达到节点使用资源平衡。

kube-scheler 是 Kubernetes 集群的默认调度器,并且是集群 控制面 的一部分。

对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheler 会选择一个最优的 Node 去运行这个 Pod。然而,Pod 内的每一个容器对资源都有不同的需求,而且 Pod 本身也有不同的资源需求。因此,Pod 在被调度到 Node 上之前,根据这些特定的资源调度需求,需要对集群中的 Node 进行一次过滤。

在一个集群中,满足一个 Pod 调度请求的所有 Node 称之为 可调度节点 。如果没有任何一个 Node 能满足 Pod 的资源请求,那么这个 Pod 将一直停留在未调度状态直到调度器能够找到合适的 Node。

调度器先在集群中找到一个 Pod 的所有可调度节点,然后根据一系列函数对这些可调度节点打分,然后选出其中得分最高的 Node 来运行 Pod。之后,调度器将这个调度决定通知给 kube-apiserver,这个过程叫做 绑定 。

在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。

kube-scheler 给一个 pod 做调度选择包含两个步骤:

因此,可能会在群集中不太理想的节点上安排多个pod。 Descheler 根据其政策,发现可以移动并移除它们的pod。请注意,在当前的实现中,Descheler 不会安排更换被驱逐的pod,而是依赖于默认的调度程序。

这就是本文想讲的 Descheler 项目,根据该项目二次调度策略来解决上面所说的问题。具体策略说明如下:

该策略确保只有一个Pod与在同一节点上运行的副本集(RS),Replication Controller(RC),Deployment或Job相关联。如果还有更多,则将这些重复的容器逐出,以更好地在群集中扩展容器。如果某些节点由于任何原因而崩溃,并且它们上的Pod移至其他节点,导致多个与RS或RC关联的Pod(例如在同一节点上运行),则可能发生此问题。一旦出现故障的节点再次准备就绪,便可以启用此策略以驱逐这些重复的Pod。当前,没有与该策略关联的参数。要禁用此策略,策略应如下所示:

该策略发现未充分利用的节点,并且如果可能的话,从其他节点驱逐pod,希望在这些未充分利用的节点上安排被驱逐的pod的重新创建。此策略的参数配置在 。

节点的利用率低是由可配置的阈值决定的 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,它在调度时满足节点关联性规则 ,但随着时间的推移,nodeA不再满足该规则,那么如果另一个节点nodeB可用,它满足节点关联性规则,那么podA将被逐出nodeA。策略文件如下所示:

该策略可以确保从节点中删除违反 NoSchele 污点的 Pod 。例如,有一个名为 podA 的 Pod ,通过配置容忍 key=value:NoSchele 允许被调度到有该污点配置的节点上,如果节点的污点随后被更新或者删除了,则污点将不再被 Pod 的容忍满足,然后将被驱逐,策略文件如下所示:

当 Descheler 程序决定从节点驱逐 Pod 时,它采用以下常规机制:

Descheler 可以在k8s集群中作为 Job 或 CronJob 运行。它的优点是可以多次运行而无需用户干预。该调度程序容器在 kube-system 命名空间中作为关键容器运行,以避免被自身或kubelet逐出。

例如:

⑶ k8s 基本使用(上)

本文将介绍 k8s 中的一些最基本的命令,并辅以解释一些基本概念来方便理解,也就是说,本文是一篇偏向实用性而非学术性的文章,如果你想提前了解一下 k8s 相关的知识的话,可以通过以下链接进行学习:

k8s 是经典的一对多模型,有一个主要的管理节点 master 和许多的工作节点 slaver 。当然,k8s 也可以配置多个管理节点,拥有两个以上的管理节点被称为 高可用 。k8s 包括了许多的组件,每个组件都是单运行在一个 docker 容器中,然后通过自己规划的虚拟网络相互访问。你可以通过 kubectl get pod -n kube-system 查看所有节点上的组件容器。

在管理节点中会比工作节点运行更多的 k8s 组件,我们就是靠着这些多出来的组件来对工作节点发号施令。他们都叫什么这里就不详细提了。反正对于”基本使用“来说,这些名字并不重要。

要想理解一个东西就要先明白它的内在理念。通俗点就是,k8s 做了什么?为了提供更加可靠的服务,就要增加服务器的数量,减少每个服务器的体量来平摊负载,而越来越多的虚拟机就会带来越来越高的运维成本。如何让少量的运维人员就可以管理数量众多的服务器及其上的服务呢?这就是 k8s 做的工作。

k8s 把数量众多的服务器重新抽象为一个统一的资源池 ,对于运维人员来说,他们面前没有服务器1、服务器2的概念,而是一个统一的资源池,增加新的服务器对运维人员来说,只是增加自资源池的可用量。不仅如此,k8s 把所有能用的东西都抽象成了资源的概念,从而提供了一套更统一,更简洁的管理方式。

接下来,我会把每个基本命令当做一节来进行介绍,并辅以介绍一些基本概念。本文介绍的命令涵盖了增删改查四方面,可参加下面表格,因为篇幅较长,我们将 create 及之后的不那么常用的命令放在下一篇文章 k8s 基本使用(下) 里讲:

接下来进入正题,首先来了解一下 k8s 中最最最常用的命令 kubectl get ,要记住,k8s 把所有的东西都抽象成了资源,而 kubectl get 就是用来查看这些资源的。最常见的资源就是 pod 。

不仅我们自己的服务是要包装成 pod 的,就连 k8s 自己也是运行在一堆 pod 上。接下来就让我们查看一下 k8s 的 pod :

-n 参数指定了要查看哪个命名空间下的 pod 。 k8s 所有的 pod 都被放置在 kube-system 命名空间下。

执行了 kubectl get pod -n kube-system 命令后,你就可以看到如下内容:

其中每一行就是一个资源,这里我们看到的资源是 pod 。你看到的 pod 数量可能和我的不一致,因为这个列表里包含了 k8s 在所有节点上运行的 pod ,你加入的节点越多,那么显示的 pod 也就越多。我们来一列一列的看:

kubectl get 可以列出 k8s 中所有资源

这里只介绍了如何用 kubectl 获取 pod 的列表。但是不要把 get 和 pod 绑定在一起,pod 只是 k8s 中的一种服务,你不仅可以 get pod ,还可以 get svc ( 查看服务 )、 get rs ( 查看副本控制器 )、 get deploy ( 查看部署 )等等等等,虽然说 kubectl get pod 是最常用的一个,但是如果想查看某个资源而又不知道命令是什么, kbuectl get <资源名> 就对了。

如果你想看更多的信息,就可以指定 -o wide 参数,如下:

加上这个参数之后就可以看到资源的所在 ip 和所在节点 node 了。

记得加上 -n

-n 可以说是 kubectl get 命令使用最频繁的参数了,在正式使用中,我们永远不会把资源发布在默认命名空间。所以,永远不要忘记在 get 命令后面加上 -n 。

kubectl get 命令可以列出 k8s 中的资源,而 kubectl get pod 是非常常用的查看 pod 的命令。而 -n 参数则可以指定 pod 所在的命名空间。

kubectl describe 命令可以用来查看某一资源的具体信息,他同样可以查看所有资源的详情, 不过最常用的还是查看 pod 的详情 。他也同样可以使用 -n 参数指定资源所在的命名空间。

举个例子,我们可以用下面命令来查看刚才 pod 列表中的某个 pod,注意不要忘记把 pod 名称修改成自己的:

然后你就可以看到很多的信息,咱们分开说,首先是基本属性,你可以在详细信息的开头找到它:

基本属性

其中几个比较常用的,例如 Node 、 labels 和 Controlled By 。通过 Node 你可以快速定位到 pod 所处的机器,从而检查该机器是否出现问题或宕机等。通过 labels 你可以检索到该 pod 的大致用途及定位。而通过 Controlled By ,你可以知道该 pod 是由那种 k8s 资源创建的,然后就可以使用 kubectl get <资源名> 来继续查找问题。例如上文 DaemonSet/kube-flannel-ds-amd64 ,就可以通过 kubectl get DaemonSet -n kube-system 来获取上一节资源的信息。

内部镜像信息

在中间部分你可以找到像下面一样的 Containers 段落。该段落详细的描述了 pod 中每个 docker 容器的信息,常用的比如 Image 字段,当 pod 出现 ImagePullBackOff 错误的时候就可以查看该字段确认拉取的什么镜像。其他的字段名都很通俗,直接翻译即可。

事件

在 describe 查看详情的时候,最常用的信息获取处就是这个 Event 段落了,你可以在介绍内容的末尾找到它,如下:

是的,如果你看到上面这样,没有任何 Events 的话,就说明该 pod 一切正常。当 pod 的状态不是 Running 时,这里一定会有或多或少的问题,长得像下面一样,然后你就可以通过其中的信息分析 pod 出现问题的详细原因了:

kubectl describe <资源名> <实例名> 可以查看一个资源的详细信息,最常用的还是比如 kubectl describe pod <pod名> -n <命名空间> 来获取一个 pod 的基本信息。如果出现问题的话,可以在获取到的信息的末尾看到 Event 段落,其中记录着导致 pod 故障的原因。

如果你想查看一个 pod 的具体日志,就可以通过 kubectl logs <pod名> 来查看。注意,这个只能查看 pod 的日志。通过添加 -f 参数可以持续查看日志。例如,查看 kube-system 命名空间中某个 flannel pod 的日志,注意修改 pod 名称:

然后就可以看到如下输出:

如果你发现某个 pod 的服务有问题,但是状态还是显示 Running ,就可以使用 kubectl logs 来查看其详细日志。

在本篇文章里,我们了解了 k8s 的宗旨和一些基本概念,并知道了最为常用的 get 、 descibe 及 logs 命令,知道了这三条命令之后就几乎可以从 k8s 中获取所有常用信息了。接下来的 k8s 基本使用(下) 里,我们会更深一步,来了解 k8s 中如何创建、修改及删除资源。

⑷ K8S-[二]Deployment控制器

工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。
常用工作负载控制器:
• Deployment : 无状态应用部署
• StatefulSet : 有状态应用部署
• DaemonSet : 确保所有Node运行同一个Pod
• Job : 一次性任务
• Cronjob : 定时任务

控制器的作用:
• 管理Pod对象
• 使用标签与Pod关联
• 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等。

• 管理Pod和ReplicaSet(副本数量设定)
• 具有上线部署、副本设定、滚动升级、回滚等功能
• 提供声明式更新,例如只更新一个新的Image

应用场景:网站、API、微服务

第一次写deploy的yaml可以用命令导出的方式获取模板,在进行删减。

最终版deployment的yaml:
deploy就是管理Pod的,所以关于对Pod管理的配置都可以放在这个配置文件,如资源配额(resource),污点容忍(tolrations),健康检查(linvenessProbe)等

部署:

查看:

暴露到外部访问:

输入 http://NodeIP:32149 访问

应用的升级其实就是换个镜像,更新镜像的三种方式
• kubectl apply -f xxx.yaml
• kubectl set image deployment/web nginx=nginx:1.16 (这个好处是这样回滚的时候可看到版本记录)
• kubectl edit deployment/web

滚动升级:K8s对Pod升级的默认策略,通过使用新版本Pod逐步更新旧版本Pod,实现零停机发布,用户无感知。

原理: 对Pod的升级,是先启动一个新的pod ,并启动。如果配了健康检查会在健康检查后完全没问题,出现running状态,才删掉一个旧pod。在启动一个新的,在删掉一个旧的。反复下去,这一切也都是deployment控制的。滚动升级在k8s中,也是由1个deployment 和 2个 replicaset 实现的。2个replicaset分别控制 增加新启动Pod副本数量;减少原pod的副本数量。 加一减一的原则。达到用户无感知。

集群内部访问一下service的集群IP,看下nginx此时版本是1.15

编辑delpoy.yaml,修改镜像版本为1.18

图中可看到,k8s先启动了2个新pod, 在新pod成功运行后,再删除一个旧的。直到最后成功更新2个Pod。

• maxSurge:滚动更新过程中最大Pod副本数,确保在更新时启动的Pod数量比期望(replicas)Pod数量最大多出25%

• maxUnavailable:滚动更新过程中最大不可用Pod副本数,确保在更新时最大25% Pod数量不可用,即确保75% Pod数量是可用状态。

deployment中replicas参数控制Pod副本数量

ReplicaSet控制器用途:
• Pod副本数量管理,不断对比当前Pod数量与期望Pod数量,一直循环这个过程。
• Deployment每次发布都会创建一个RS作为记录,用于实现回滚

所以刚才实现扩容都是ReplicaSet控制器做的。
可以查看ReplicaSet(RS)的信息

项目的下线很简单。删除对应的deploy控制器,svc 即可。
如果是用deploy创建的pod,那么直接删除Pod 是不起作用的,还会被拉起来,反复循环。这都是因为上面说的deployment控制器中的replicaset 一直在循环一个动作 : 对比当前pod数量是否和期望的一样,不一样就拉起。所以不能直接删除pod。

CronJob用于实现定时任务,像Linux的Crontab一样。
• 定时任务
应用场景:通知,备份
cronjob.yaml

每过一分钟会启动这个pod,执行定义的命令

⑸ 关闭k8s集群正确顺序

先增删后改查。
关闭集群顺序先打开增加的入口,再检查入口进程,点击关闭,最后退出控制节点。
k8s集群管理和控制节点,主要通过4个组件实现集群资源调度,负载均衡,资源增删改查操作的唯一入口。
Server用来接收和处理其他组件发来的请求,是集群控制的入口进程。
k8s里所有资源的增删改查,操作请求的唯一接收和处理。

⑹ K8s污点容忍度横向主节点

污点是K8s高级调度的特性,用于限制哪些Pod可以被调度到某一个节点。在普通节点横向时我们可以使用污点容忍度创建恶意pod来对主节点进行横向控制。

kube-scheler 是 Kubernetes 集群的默认调度器,并且是集群控制面(master)的一部分。对每一个新创建的Pod或者是未被调度的Pod, kube-scheler 会选择一个最优的Node去运行这个Pod。

然而, Pod 内的每一个容器对资源都有不同的需求,而且Pod本身也有不同的资源需求。因此,Pod在被调度到Node上之前,根据这些特定的资源调度需求,需要对集群中的Node进行一次过滤。

当创建pod时候,会首先把创建的命令请求提交给apiserver,通过一系列认证授权,apiserver把pod数据存储到etcd,创建deployment资源并初始化。然后再是scheler通过进行list-watch机制进行监测,经过 调度算法 把pod调度到某个node节点上,最后信息更新到etcd,再后面就是kubelet接受信息到创建容器。

当前调度器选择适当的节点时,调度程序会检查每个节点是否有足够的资源满足 Pod 调度,比如查看CPU和内存限制是否满足:

通过资源限制调度程序可确保由于过多 Pod 竞争消耗节点所有可用资源,从而导致节点资源耗尽引起其他系统异常。

在创建pod的时候,节点选择器可以约束pod在特定节点上运行。

nodeSelector 也是节点选择约束的最简单推荐形式, nodeSelector 字段添加到 Pod 的规约中设置希望目标节点所具有的 节点标签 。 K8s 只会将 Pod 调度到拥有你所指定的每个标签的节点上。

例子, 比如多个节点需要调度时候,通过给1,2节点打上标签,创建pod时候使用节点选择器,那么pod会被按照节点选择器希望的目标在相应节点调度。

为节点打上标签:

kubectl label node nodename env_role=env

查看节点的标签:

kubectl get nodes nodename --show-labels

节点亲和性概念上类似于 nodeSelector , 它使可以根据节点上的标签来约束 Pod 可以调度到哪些节点上,这种方法比上面的 nodeSelector 更加灵活,它可以进行一些简单的逻辑组合了,不只是简单的相等匹配。

节点亲和性和节点选择器相比功能更强大,比如还是刚才的图,如果我使用节点选择器 env_role:dev1 的话是找不到相应的节点的,就没有办法调度,会一直是一个等待的状态:

但我如果使用节点亲和性,就算当前没有这个节点,我还是可以根据调度调度策略进行调度,不只是简单的相等匹配。

调度可以分成软策略( 软亲和性 )和硬策略( 硬亲和性 )两种方式:

如图可以看到软亲和性和硬亲和性的字段其实差不多,软亲和性多了一个 weight 字段,表权重:

如上亲和性还有一个字段是 operator 表匹配的逻辑操作符,可以使用 descirbe 命令查看具体的调度情况是否满足我们的要求, K8s 提供的操作符有下面的几种:

如果 nodeSelectorTerms 下面有多个选项的话,满足任何一个条件就可以了;如果 matchExpressions 有多个选项的话,则必须同时满足这些条件才能正常调度 POD。

容忍度( Toleration )是应用于 Pod 上的,允许(但并不要求)Pod 调度到带有与之匹配的污点的节点上。污点说白了就是不做普通的调度。

对于节点亲和性无论是软亲和性和硬亲和性,都是调度 POD 到预期节点上,而污点( Taints )恰好与之相反,如果一个节点标记为 Taints , 除非 POD 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度pod

查看污点情况:

kubectl describe node nodename | grep Taint

可以看到,默认污点也只有master有。

污点里的值有三种:

NoSchele 就是字面意思,不会被调度, PreferNoSchele 说白了是尽量不被调度, NoExecute 是不会调度并且还会驱逐 node 已有的 pod 。

创建一个pod:

如果不加污点,可以看到这个pod会随机调度到节点1或者节点2:

这时候把pod删除了,重新创建pod并且给node加上污点:

给节点打污点:

kubectl taint node nodename key=value:NoSchele

重新创建pod并且deployment多个:

可以发现全部被调度在节点2上,节点1的污点 NoSchele 起了作用。

删除污点:

容忍度 tolerations 是定义在 Pod 对象上的键值型属性数据,用于配置其可容忍的节点污点,而且调度器仅能将 Pod 对象调度至其能够容忍该节点污点的节点之上。

污点定义在节点的 node Spec 中,而容忍度则定义在 Pod 的 podSpec 中,它们都是键值型数据。

在 Pod 对象上定义容忍度时,它支持两种操作符:一种是等值比较 Equal ,表示容忍度与污点必须在 key 、 value 和 effect 三者之上完全匹配;另一种是存在性判断 Exists ,表示二者的 key 和 effect 必须完全匹配,而容忍度中的 value 字段要使用空值。

这里的key和value对应的值都是你自己设置的key和value:

说白了就是:

而污点容忍的作用举个例子,如果像上面污点一样设置了 NoSchele 污点的节点,那么创建pod的时候是必不被调度到的,但是如果我使用污点容忍,那这个节点可以在设置 NoSchele 污点的情况下可能又被调度,类似于亲和性那种作用。

污点和污点容忍度的作用也就是获取 主节点的shell ,因为像常见或者节点shell的流程是创建pod--》分配到正常node---》通过常规挂载目录拿到节点的shell,而默认主节点是不被调度的,所以只有使用污点容忍度,创建一个能够被调度到master节点的pod,然后通过挂载之类的手法来拿到主节点的shell。

通过创建一个具有 node-role.kubernetes.io/master:NoSchele 的容忍度让Pod被Kubernetes Master所调度。

如上的Pod中将宿主机的根目录挂载到容器中(volumes与volumeMounts)即可逃逸至Kubernetes Master中接管集群。

查看节点,当前是在普通节点:

多次创建可以发现在master节点上了:

可以通过挂载操作master节点母机shell:

⑺ Kubectl 常用命令大全

create 命令 :根据文件或者输入来创建资源

delete 命令 :删除资源

get 命令 :获得资源信息

run 命令 :在集群中创建并运行一个或多个容器镜像。

更详细用法参见 : http://docs.kubernetes.org.cn/468.html

expose 命令 :创建一个service服务,并且暴露端口让外部可以访问

更多expose详细用法参见 : http://docs.kubernetes.org.cn/475.html

set 命令 :配置应用的一些特定资源,也可以修改应用已有的资源

set 命令详情参见 : http://docs.kubernetes.org.cn/669.html

这个命令用于设置资源的一些范围限制。

资源对象中的 Pod 可以指定计算资源需求(CPU-单位m、内存-单位Mi),即使用的最小资源请求(Requests),限制(Limits)的最大资源需求,Pod将保证使用在设置的资源数量范围。

对于每个Pod资源,如果指定了 Limits (限制)值,并省略了 Requests (请求),则 Requests 默认为 Limits 的值。

可用资源对象包括(支持大小写) : replicationcontroller 、 deployment 、 daemonset 、 job 、 replicaset 。

例如 :

设置资源的 selector (选择器)。如果在调用"set selector"命令之前已经存在选择器,则新创建的选择器将覆盖原来的选择器。

selector 必须以字母或数字开头,最多包含63个字符,可使用:字母、数字、连字符" - " 、点"."和下划线" _ "。如果指定了--resource-version,则更新将使用此资源版本,否则将使用现有的资源版本。

注意 :目前 selector 命令只能用于 Service 对象。

​用于更新现有资源的容器镜像。

可用资源对象包括: pod (po) 、 replicationcontroller (rc) 、 deployment (deploy) 、 daemonset (ds) 、 job 、 replicaset (rs) 。

explain 命令 :用于显示资源文档信息

edit 命令 : 用于编辑资源信息

label命令 : 用于更新(增加、修改或删除)资源上的 label(标签)

例 :

annotate命令 :更新一个或多个资源的Annotations信息。也就是注解信息,可以方便的查看做了哪些操作。

例子 :

completion命令 :用于设置 kubectl 命令自动补全

BASH

ZSH

rollout 命令 : 用于对资源进行管理

可用资源包括: deployments , daemonsets 。

子命令 :

rolling-update命令 : 执行指定ReplicationController的滚动更新。

该命令创建了一个新的 RC , 然后一次更新一个 pod 方式逐步使用新的 PodTemplate ,最终实现 Pod 滚动更新, new-controller.json 需要与之前 RC 在相同的 namespace 下。

scale命令 :扩容或缩容 Deployment 、 ReplicaSet 、 Replication Controller 或 Job 中 Pod 数量

scale 也可以指定多个前提条件,如:当前副本数量或 --resource-version ,进行伸缩比例设置前,系统会先验证前提条件是否成立。这个就是弹性伸缩策略。

autoscale命令 :这个比 scale 更加强大,也是弹性伸缩策略 ,它是根据流量的多少来自动进行扩展或者缩容。

指定 Deployment 、 ReplicaSet 或 ReplicationController ,并创建已经定义好资源的自动伸缩器。使用自动伸缩器可以根据需要自动增加或减少系统中部署的pod数量。

certificate命令 :用于证书资源管理,授权等

cluster-info 命令 :显示集群信息

top 命令 :用于查看资源的cpu,内存磁盘等资源的使用率

cordon命令 :用于标记某个节点不可调度

uncordon命令 :用于标签节点可以调度

drain命令 : 用于在维护期间排除节点。

taint命令 :用于给某个 Node 节点设置污点

describe命令 :显示特定资源的详细信息

logs命令 :用于在一个pod中打印一个容器的日志,如果pod中只有一个容器,可以省略容器名

参数选项 :

exec命令 :进入容器进行交互,在容器中执行命令

命令选项 :

attach命令 :连接到一个正在运行的容器。

参数选项 :

cp命令 :拷贝文件或者目录到pod容器中

用于 pod 和外部的文件交换,类似于 docker 的 cp ,就是将容器中的内容和外部的内容进行交换。

api-servions命令 :打印受支持的 api 版本信息

help命令 :用于查看命令帮助

config 命令 : 用于修改 kubeconfig 配置文件(用于访问api,例如配置认证信息)

设置 kubectl 与哪个 Kubernetes 集群进行通信并修改配置信息。查看 使用 kubeconfig 跨集群授权访问 文档获取详情配置文件信息。

version 命令 :打印客户端和服务端版本信息

plugin 命令 :运行一个命令行插件

apply命令 :通过文件名或者标准输入对资源应用配置

通过文件名或控制台输入,对资源进行配置。 如果资源不存在,将会新建一个。可以使用 JSON 或者 YAML 格式。

参数选项 :

patch命令 :使用补丁修改,更新资源的字段,也就是修改资源的部分内容

replace命令 : 通过文件或者标准输入替换原有资源

convert命令 :不同的版本之间转换配置文件

要以特定格式将详细信息输出到终端窗口,可以将 -o 或 --output 参数添加到支持的 kubectl 命令。

Kubectl 日志输出详细程度是通过 -v 或者 --v 来控制的,参数后跟了一个数字表示日志的级别。 Kubernetes 通用的日志习惯和相关的日志级别在 这里 有相应的描述。

以上是 kubectl 一些基本命令操作,需要时方便查阅。