k8s 标签-2
标签-2
上一篇笔记的结尾处我们简单提了一下标签,并通过标签将pod指定给了某个node,因为当时写的时候比较晚了,所以并没有一次性写完,这篇我们接着看标签
node的角色
在我们使用命令kubectl get nodes查看节点的时候,你会发现有一栏是ROLES,只有master是有的,其他节点都是none
[root@master k8s]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 2d1h v1.26.0
node1 Ready <none> 2d1h v1.26.0
node2 Ready <none> 2d1h v1.26.0
他默认就是这样显示的,当然,如果你使用的k8s集群版本是1.21或者1.22之前的版本,那么他先是的就是master,而不是control-plane,这个无关竟要,版本问题
现在node1和node2这一栏显示的空的,我们可以修改他吗?当然是可以的,没有任何的问题,修改他其实就是修改标签
# 我们先查看master节点,他既然有这个值,那么他肯定是有一些node节点没有的标签的
[root@master k8s]# kubectl get nodes/master --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready control-plane 2d1h v1.26.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=
我们在标签栏位里面可以找到 node-role.kubernetes.io/control-plane=
你可以查看一下node节点的,是没有的,而且他这个好像是没有value的,只有key,那他好像就是读取的control-plane这个内容,那我么如果加上一个前缀跟他一样的,但是最后这里我们将他修改成其他值,我们来看看效果
# 我们同样不给他value
[root@master k8s]# kubectl label nodes master node-role.kubernetes.io/master=
node/master labeled
# 现在我们再来查看一下这个节点的角色
[root@master k8s]# kubectl get nodes/master
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 2d1h v1.26.0
我们会发现他确实是把master加上去了,其实这个标签是很特殊的,它并不需要value,如果你想要给他value也是可以的,不会报错,但是他并不会使用你给的value来当他的角色
修改node节点的角色,将他的角色修改成他的主机名
# 我们已经知道他的规则了,那我们想要修改就非常的容易了
[root@master k8s]# kubectl label nodes node1 node-role.kubernetes.io/node1=
[root@master k8s]# kubectl label nodes node2 node-role.kubernetes.io/node2=
我们来验证一下
[root@master k8s]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 2d1h v1.26.0
node1 Ready node1 2d1h v1.26.0
node2 Ready node2 2d1h v1.26.0
没有任何的问题
标签的作用
我们之前是可以通过一些方法,将pod指定到节点上去创建,那么为什么要这么干呢,为什么不让他自己调度呢
我们可以这样设想一下,如果你用的是服务器搞的集群,并且服务器的配置还不太一样,比如有一台服务器他的CPU很强,算力很高,但是硬盘的读写速度不太行
另外一台服务器CPU没有那么好,但是硬盘用的NVMe的,读写速度那是相当的快,你现在需要创建一个pod,这个pod是跑数据库,只需要他读写速度快就好了,并不需要CPU有很强的算力,那我们能让他自己调度吗?显然是不太行的,所以我们需要指定他调度到那一台硬盘好的服务器上,那我们就可以给这两台服务器都打上标签,一台是高算力,一台是快IO对吧
那我们在以后去调度pod的时候是不是直接通过标签去选择就可以了呢,对吧
Cordon,Drain以及污点
Cordon--告警警戒
这个的意思就是,只要节点被打上这个标记了,那么他就不会参与到调度算法里面了,我们可以来看看,记住,他是不参与到调度算法里,如果这个节点已经存在pod,是没有影响的
# 我们先查看一下node的状态
[root@master k8s]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 2d2h v1.26.0
node1 Ready node1 2d2h v1.26.0
node2 Ready node2 2d2h v1.26.0
一切都是正常的,现在我们来给node1加一个cordon,然后再查看
[root@master k8s]# kubectl cordon node1
node/node1 cordoned
[root@master k8s]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 2d2h v1.26.0
node1 Ready,SchedulingDisabled node1 2d2h v1.26.0
node2 Ready node2 2d2h v1.26.0
现在我们可以看见,node1的状态是Ready,但是后面还有一个参数,是不能被调度,那我们现在来创建pod,看看是否真的真的不会在node1上创建出来
[root@master k8s]# kubectl run pod01 --image=nginx --image-pull-policy=IfNotPresent
pod/pod01 created
[root@master k8s]# kubectl run pod02 --image=nginx --image-pull-policy=IfNotPresent
pod/pod02 created
[root@master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod01 1/1 Running 0 15s 10.244.104.59 node2 <none> <none>
pod02 1/1 Running 0 10s 10.244.104.60 node2 <none> <none>
我们创建了2个pod,他确实都是在node2上起的,你还可以继续创建更多pod他也只会在node2上
好的,我们现在知道了他不会在node1上创建了,那我们如果在node2上也加一个cordon呢,那pod是在哪呢?master上吗?
[root@master k8s]# kubectl cordon node2
node/node2 cordoned
[root@master k8s]# kubectl run pod03 --image=nginx --image-pull-policy=IfNotPresent
pod/pod03 created
[root@master k8s]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod01 1/1 Running 0 95s
pod02 1/1 Running 0 90s
pod03 0/1 Pending 0 4s
我们可以看到,他现在的状态是pending,他既没有创建到node1,也没到node2上,那master上没有做cordon,他为什么没有在master上创建呢?这个问题留着,等会就知道了
我们取消cordon
[root@master k8s]# kubectl uncordon node1
node/node1 uncordoned
[root@master k8s]# kubectl uncordon node2
node/node2 uncordoned
Drain
他跟Cordon的共同点是,只要加上了这个操作,那么他们都是不可被调度的,不同点是Drain他会比Dordon多一个动作,Dordon对于已经存在的pod是不会驱逐的,但是Drain对于已经存在的pod是会进行驱逐的
我们来做个实验看看
# 我们先跑2个pod,让他自己调度,不出意外应该是一个在node1,一个在node2
[root@master k8s]# kubectl run pod01 --image=nginx --image-pull-policy=IfNotPresent
pod/pod01 created
[root@master k8s]# kubectl run pod02 --image=nginx --image-pull-policy=IfNotPresent
pod/pod02 created
[root@master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod01 1/1 Running 0 10s 10.244.104.61 node2 <none> <none>
pod02 1/1 Running 0 6s 10.244.166.166 node1 <none> <none>
现在每个节点上都被调度了一个pod,那我们现在给node1加上Cordon,给node2加上Drain,来看看他们的区别
[root@master k8s]# kubectl cordon node1
node/node1 cordoned
[root@master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod01 1/1 Running 0 2m1s 10.244.104.61 node2 <none> <none>
pod02 1/1 Running 0 117s 10.244.166.166 node1 <none> <none>
在node1上加上cordon之后pod是没有任何的变化的
# 现在我们给node2加上Drain
# 注意,一定加加上--ignore-daemonsets 和--force
[root@master k8s]# kubectl drain node2 --ignore-daemonsets=true --force
node/node2 cordoned
Warning: ignoring DaemonSet-managed Pods: calico-system/calico-node-9f7ck, calico-system/csi-node-driver-hzj2r, kube-system/kube-proxy-xmxpj; deleting Pods that declare no controller: default/pod01
evicting pod tigera-operator/tigera-operator-cfc98749c-nzvs8
evicting pod default/pod01
pod/tigera-operator-cfc98749c-nzvs8 evicted
pod/pod01 evicted
node/node2 drained
现在我们再来查看一下pod
[root@master k8s]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod02 1/1 Running 0 32m
[root@master k8s]#
现在我们发现pod01已经没有了,想要取消的话直接使用取消Cordon的命令,原因是Drain的过程是先给节点打上Cordon,然后开始驱逐,所以它也是有Cordon这一步动作的,所以是可以直接用Cordon命令取消的
驱逐演示
刚刚使用pod他是直接将pod给删掉了,并没有在其他的地方把这个pod搞起来,驱逐难道不是应该给他换个地方吗?这其实是因为pod的原因,我们可以使用deployment控制器来实现这个效果,控制器现在只需要了解一下就行了,后面会说到,大概就是你给这个控制器一个你想要的规模数量,比如我想要5个pod,那么他会保持你的pod在5个,多了删,少了补
# 生产yaml文件
[root@master k8s]# kubectl create deployment web01 --image=nginx --dry-run=client -o yaml > depolyment.yaml
metadata:
creationTimestamp: null
labels:
app: web01
name: web01
spec:
replicas: 5
selector:
matchLabels:
app: web01
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web01
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
resources: {}
status: {}
# 我们使用这个文件来创建控制器,然后在给node2加上Drain
[root@master k8s]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web01-854bdfcbd8-6j958 1/1 Running 0 29s 10.244.104.12 node2 <none> <none>
web01-854bdfcbd8-dlx6r 1/1 Running 0 29s 10.244.104.10 node2 <none> <none>
web01-854bdfcbd8-mcc9q 1/1 Running 0 29s 10.244.166.170 node1 <none> <none>
web01-854bdfcbd8-rd8sv 1/1 Running 0 29s 10.244.104.11 node2 <none> <none>
web01-854bdfcbd8-v2tfn 1/1 Running 0 29s 10.244.166.169 node1 <none> <none>
# 加上Drain
[root@master k8s]# kubectl drain node2 --ignore-daemonsets --force
[root@master k8s]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web01-854bdfcbd8-6mmcx 1/1 Running 0 15s 10.244.166.173 node1 <none> <none>
web01-854bdfcbd8-cdkmw 1/1 Running 0 15s 10.244.166.172 node1 <none> <none>
web01-854bdfcbd8-j82mv 1/1 Running 0 15s 10.244.166.171 node1 <none> <none>
web01-854bdfcbd8-mcc9q 1/1 Running 0 102s 10.244.166.170 node1 <none> <none>
web01-854bdfcbd8-v2tfn 1/1 Running 0 102s 10.244.166.169 node1 <none> <none>
现在我们可以看到之前在node2上的pod现在全部都被干掉了,然后又重新被调度到了node1上,这个就是驱逐
污点
pod为什么不会宁愿是pending他都不会调度到master上呢?因为master上默认就是有污点的,我们来看看
[root@master k8s]# kubectl describe node master |grep Taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
我们现在可以看到,他这个有显示Taints里面有个NoSchedule,就是不被调度,这样一切就都解释的通了,这也就是为什么master上默认不会运行业务pod
我们再来看看node1上有没有这个
[root@master k8s]# kubectl describe node master |grep Taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
注意了,你如果查到的node1是这样的,说明你之前做的Cordon没有取消,一定要取消掉,还原他的默认调度策略
# 取消完之后他就应该是这样的,污点显示none,没有任何的污点
[root@master k8s]# kubectl describe node node1 |grep Taint
Taints: <none>
我们来给node1也加上一个污点,让他不被调度
# 注意,打污点的时候也是key:value的形式,但是key是什么并不重要,重要的value
[root@master k8s]# kubectl taint node node1 wudian:NoSchedule
node/node1 tainted
这样污点就被打上了,刚刚说过了,污点的key并不重要,随意是什么都可以的
现在来创建pod,他是一定会在node2上创建pod的,因为master和node1都有污点,我们来看看
[root@master k8s]# kubectl run taint-pod2 --image=nginx --image-pull-policy=IfNotPresent
pod/taint-pod2 created
[root@master k8s]# kubectl run taint-pod3 --image=nginx --image-pull-policy=IfNotPresent
pod/taint-pod3 created
[root@master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
taint-pod 1/1 Running 0 22s 10.244.104.62 node2 <none> <none>
taint-pod2 1/1 Running 0 8s 10.244.104.63 node2 <none> <none>
taint-pod3 1/1 Running 0 4s 10.244.104.1 node2 <none> <none>
可以看到,确实所有的pod都被调度到了node2上
污点的删除也很简单,只需要在key后面加上-就可以了
[root@master k8s]# kubectl taint node node1 wudian-
node/node1 untainted
也是可以把master上的污点给他删除掉的,删除之后后面再创建pod他就会往master上进行调度了
污点的Cordon的区别
看到这里,也许没有搞清楚污点和Cordon他们的区别在哪,不都是不能被调度吗。为什么要搞这么多一样的功能呢?其实他们是有其别的,你看,污点这个名字,是不是就像你读书的时候学校给你的处分啊,难道说学校给你处分之后,你就不能来学校读书了吗?当然是可以的啊,这个Cordon就像是你在学校搞了很严重的事情,现在老师让你回家反省一周,你能回去一天就来学校吗?肯定不行啊,这个也就是他们的区别
如果节点存在污点,但是我指定了污点容忍,这个节点也会参与到调度中来,那么他依旧是可以被创建出来的,但是你这个节点有Cordon,不管你怎么指定,他都是pending状态的
# 实践是检验真理的唯一标准,上操作,还记得我们之前使用标签指定pod在哪个节点上创建吧。
# 我们给node1指定一个标签,同样给他一个NoSchedule的污点,再通过yaml文件来指定污点容忍,以及节点选择
[root@master k8s]# kubectl label nodes node1 cloud=666
node/node1 labeled
[root@master k8s]# kubectl taint node node1 cloud=666:NoSchedule
node/node1 tainted
现在我们已经操作好了,他既有标签,也有污点,直接只用yaml文件来创建pod
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod01
name: pod01
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod01
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
# 在这里加上的是节点选择器
nodeSelector:
cloud: "666"
# 这里加上的污点容忍,key=value:effect 这个要跟之前定义的污点一样
tolerations:
- key: "cloud"
operator: "Equal"
value: "666"
effect: "NoSchedule"
status: {}
使用这个yaml文件来看看效果
[root@master k8s]# kubectl apply -f label1.yml
pod/pod01 created
[root@master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod01 1/1 Running 0 5s 10.244.166.168 node1 <none> <none>
我们可以看到,虽然node1有污点,但是这个pod有污点容忍,他一样可以被调度到node1上
k8s 标签-2的更多相关文章
- k8s标签
一.标签是什么 标签是k8s特色的管理方式,便于分类管理资源对象. 一个标签可以对应多个资源,一个资源也可以有多个标签,它们是多对多的关系. 一个资源拥有多个标签,可以实现不同维度的管理. 可以使用标 ...
- k8s标签label
1.给节点设置标签 一遍pod部署选择 kubectl label node 节点名 disktype=ssd kubectl label node master1 disktype=ssd 效果 [ ...
- docker+k8s基础篇三
Docker+K8s基础篇(三) kubernetes上的资源 A:k8s上的常用资源 Pod的配置清单 A:Pod上的清单定义 B:Pod创建资源的方法 C:spec下其它字段的介绍 Pod的生命周 ...
- Docker学习(十一)Docker系列结束-新的开始K8S
Docker学习(十一)Docker系列结束-新的开始K8S 标签(空格分隔): docke k8s Docker系列结束 上一篇讲到使用docker官方提供的容器编排工具docker-compose ...
- 一个请求过来都经过了什么?(Thrift版)
一.背景 最初遇到这个问题是去58面试.部门领导是原同事,所以面试比较水.水到什么程度呢? 面试就是走个形式而已,不会不过的. 一面面试官就问了一个问题:“一个请求过来都经过了什么?” 剩下的全是闲 ...
- Linux运维博客大全
系统 U盘安装Linux详细步骤_hanxh7的博客-CSDN博客_u盘安装linux 使用U盘安装linux系统 - lwenhao - OSCHINA 各厂商服务器存储默认管理口登录信息(默认IP ...
- 最新 2022 年 Kubernetes 面试题高级面试题及附答案解析
题1:Kubernetes Service 都有哪些类型? 通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上.其主要类型有: C ...
- 容器编排系统之K8s资源标签、标签选择器、资源注解
前文我们聊到了使用k8s资源配置清单定义资源的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14132890.html:今天我们来聊下资源标签,标签选 ...
- k8s核心资源之:标签(label)
简介 label是标签的意思,一对 key/value ,被关联到对象上,k8s中的资源对象大都可以打上标签,如Node.Pod.Service 等 一个资源可以绑定任意多个label,k8s 通过 ...
- k8s入门_label标签、nodeSelector
什么是label Label以key/value键值对的形式附加到任何对象上,如Pod,Service,Node, RC(ReplicationController)/RS(ReplicaSet)等. ...
随机推荐
- C++类内存分布+ Studio工具
书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Stu ...
- OSPF路由 与 ISIS路由 与路由学习对比
转载请注明出处: 1.OSPF 路由学习规律 OSPF使用链路状态数据库(Link State Database)来存储网络拓扑信息.每个OSPF路由器通过交换链路状态更新(Link State Up ...
- CF1401C
题目简化和分析: 交换数组使其变为升序,满足交互的两数 \(a_i\) 与 \(a_j\),$ \min{a_i(1\le i\le n)}|\gcd(a_i,a_j)$ . 简单思维题,Div.2 ...
- 强化学习的一周「GitHub 热点速览」
当强化学习遇上游戏,会擦出什么样的火花呢?PokemonRedExperiments 将经典的 Pokeman 游戏接上了强化学习,效果非同凡响,不然能一周获得 4.5k star 么?看看效果图就知 ...
- Java替换RequestBody和RequestParam参数的属性
Java替换RequstBody和RequestParam参数的属性 本文主要讲解在Java环境中如何替换RequestBody和RequestParam参数中的属性 背景 近期由于接手的老项目中存在 ...
- Redis 6 学习笔记 4 —— 通过秒杀案例,学习并发相关和apache bench的使用,记录遇到的问题
背景 这是某硅谷的redis案例,主要问题是解决计数器和人员记录的事务操作 按照某硅谷的视频敲完之后出现这样乱码加报错的问题 乱码的问题要去tomcat根目录的conf文件夹下修改logging.pr ...
- Hooks的核心原理梳理
我们前端都在诟病专业版,它的组件,它的耦合嵌套之深,它的性能. 我们希望改善,我们认为,如果--就好了. 如果重构就好了,如果技术栈统一就好了,如果有规范就好了. 其实,不用等,我们只要在写代码,就可 ...
- JavaScript 语法:流程控制语句
作者:WangMin 格言:努力做好自己喜欢的每一件事 JavaScript流程控制语句的三种基本结构:顺序结构,选择结构,循环结构 顺序结构 从上到下执行的代码就是顺序结构,程序默认就是由上到下顺序 ...
- 普冉PY32系列(十二) 基于PY32F002A的6+1通道遥控小车III - 驱动篇
目录 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) P ...
- Kotlin协程系列(一)
一.协程的定义 最近看了一本有关kotlin协程的书籍,对协程又有了不一样的了解,所以准备写一个关于kotlin协程系列的文章. 言归正传,我们在学习一个新东西的时候,如果连这个东西"是什么 ...