k8s之深入解剖Pod(三)
目录:
Pod的调度
Pod的扩容和缩容
Pod的滚动升级
一、Pod的调度
Pod只是容器的载体,通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度和自动控制功能。
1、RC、Deployment全自动调度
RC的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。
2、NodeSelector:定向调度
Master上的Schedule负责实现Pod的调度,但无法知道Pod会调度到哪个节点上。可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,达到将Pod调度到指定的Node上。
(1)首先通过kubectl label命令给目标Node打上标签
kubectl label nodes node-name key=value
例如这边给cnode-2和cnode-3添加标签
查看是否已打上标签可以使用如下命令
kubelct describe nodes node-name
(2)在Pod定义上添加nodeSelector的设置,
apiVersion: v1
kind: ReplicationController
metadata:
name: nodeselectorrc
labels:
name: nodeselectorrc
spec:
replicas: 1
template:
metadata:
name: nodeselectorrc
labels:
name: nodeselectorrc
spec:
containers:
- name: nodeselectorrc
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
nodeSelector:
name: cnode-2
【注】如果没有节点有这个标签,那么Pod会无法进行调度
3、NodeAffinity:亲和性调度
由于NodeSelector通过Node的label进行精确匹配,所以NodeAffinity增加了In,NotIn,Exists、DoesNotExist、Gt、Lt等操作符来选择Node,能够使调度更加灵活,同时在NodeAffinity中将增加一些信息来设置亲和性调度策略
(1)RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才可以调度Pod到Node上
(2)PreferredDuringSchedulingIngoredDuringExecution:强调优选满足指定规则,调度器尝试将Pod调度到Node上,但不强求,多个优先级规则还可以设置权重,以定义执行的选后顺序。
需要在Pod的metadata.annotations中设置NodeAffinity的内容,例如
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIngoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: name
operator: In
values: ["cnode-1","cnode-2"]
上述yaml脚本是说明只有Node的label中包含key=name,并且值并非是["cnode-1","cnode-2"]中的一个,才能成为Pod的调度目标,其中操作符还有In,Exists,DoesNotExist,Gt,Lt。
PreferredDuringSchedulingIngoredDuringExecution使用如下:
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIngoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: name
operator: In
values: ["cnode-1","cnode-2"]
4、DaemonSet:特定场景调度
用于管理在集群中每个Node上仅运行一份Pod的副本实例
适合以下场景:
1、在每个Node上运行GlusterFS存储或者Ceph存储的daemon进程
2、每个Node上运行一个日志采集程序 ,例如fluentd或者logstach。
3、每个Node上运行一个健康程序,采集该Node的运行性能数据,例如Prometheus node Exporter
调度策略于RC类似,也可使用NodeSelector或者NodeAffinity来进行调度
例如:为每个Node上启动一个nginx
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-nginx
labels:
name: ds-nginx
spec:
selector:
matchLabels:
name: ds-nginx
template:
metadata:
name: ds-nginx
labels:
name: ds-nginx
spec:
containers:
- name: ds-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
5、Job批处理调度
可通过Job资源对象定义并启动一个批处理任务,通常并行或串行启动多个计算进程去处理一批工作任务,处理完成后,整个批处理任务结束。
按照批处理任务实现方式的不同,可分为如下几种模式 :
1、Job Template Expansion模式:一个Job对象对应一个待处理的Work Item,有几个Work item就产生几个独立的Job,适合Work item少,每个Work item要处理的数据量比较大的场景
例如:定义一个Job模板,job.yaml.txt
apiVersion: batch/v1
kind: Job
metadata:
name: process-item-$ITEM
labels:
jobgroup: jobexample
spec:
template:
metadata:
name: jobexample
labels:
jobgroup: jobexample
spec:
containers:
- name: c
image: busybox
imagePullPolicy: IfNotPresent
command: ["sh","-c","echo $Item && sleep 5"]
restartPolicy: Never
#使用如下命令生成yaml文件
for i in a b c; do cat job.yaml.txt | sed "s/\$ITEM/${i}/" > ./job-$i.yaml; done
#查看运行情况
kubectl get jobs -l jobgroup=jobexample
2、Queue with Pod Per Work Item模式:采用一个任务队列存放Work Item,一个Job作为消费者去完成这些Work item,此模式下,Job会启动N个Pod,每个Pod对应一个WorkItem
3、Queue with Variable Pod Count模式:采用一个任务队列存放Work Item,一个Job作为消费者去完成这些Work item,Job启动的Pod数量是可变的
4、Single Job with Static Work Assignment模式:一个Job产生多个Pod,采用程序静态方式分配任务项
考虑到批处理的并行问题,k8s将job分为以下三种类型:
1、Non-parallel Jobs
一个Job只启动一个Pod,除非Pod异常,才会 重启该Pod,一旦 Pod正常结束,Job将结束。
2、Parallel Jobs with a fixed completion count
并行job会 启动多个Pod,需要设定Pod的参数.spec.completions为一个正数,当正常 结束的Pod数量达到此数时,Job结束,同时此参数用于控制并行度,即同时启动几个Job来处理Work item
3、Parallel Jobs with a work queue
任务队列的并行job需要一个独立的队列,work item都在一个队列中存放,不能设置job的 .spec.completions参数,此时job有以下一些特性
(1)每个Pod能独立判断和决定是否还有任务项需要储里
(2)如果某个Pod能正常结束,则Job不会在启动新的Pod
(3)如果一个Pod成功结束,则此时应该不存在其他Pod还在干活 的情况,应该都处于即将结束 、退出的状态 。
(4)如果 所有Pod都结束了,且至少有一个Pod成功结束,则整个Job才算成功 结束。
另外,k8s从1.12版本后给job加入了ttl控制,当pod完成任务后,自动进行Pod的关闭,资源回收。
6、Cronjob:定时任务
能根据设定的定时表达式定时调度Pod
(1)Cron Job的定时表达式(与Linux的基本相同)
Minutes Hours DayOfMonth Month DayOfWeek Year
其中每个域都可出现的字符如下。
◎ Minutes:可出现【,-*/】这4个字符,有效范围为0~59的整数。
◎ Hours:可出现【,-*/】这4个字符,有效范围为0~23的整 数。
◎ DayofMonth:可出现【,-*/?LWC】这8个字符,有效范围为0~31的整数。
◎ Month:可出现【,-*/】这4个字符,有效范围为1~12的整数或JAN~DEC。
◎ DayofWeek:可出现【,-*/?LC#】这8个字符,有效范围为1~7的整数或SUN~SAT。1表示星期天,2表示星期一,以此类推
◎ *:表示匹配该域的任意值,假如在Minutes域使用,则表示每分钟都会触发事件。
◎ /:表示从起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域设置为5/20,则意味着第1次触发在第5min时,接下来每20min触发一次
◎ -:指定一个整数范围。譬如,1-4 意味着整数 1、2、3、4。
◎ ,:隔开的一系列值指定一个列表。譬如3, 4, 6, 8 标明这四个指定的整数。
比如需要每分钟执行一次:
*/1 * * * *
(2)创建Cron Job
使用yaml文件
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["/bin/bash","-c","date;echo Hello"]
restartPolicy: OnFailure
7、PodAffinity:Pod亲和与互斥调度策略
根据在节点上正在运行的 Pod的标签而不是节点的标签进行判断和调度,要求对节点和Pod两个条 件进行匹配。这种规则可以描述为:如果在具有标签X的Node上运行了一个或者多个符合条件Y的Pod,那么Pod应该(如果是互斥的情况,那么就变成拒绝)运行在这个Node上。
这里X指的是一个集群中的节点、机架、区域等概念,通过 Kubernetes内置节点标签中的key来进行声明。这个key的名字为 topologyKey,意为表达节点所属的topology范围。
◎ kubernetes.io/hostname
◎ failure-domain.beta.kubernetes.io/zone
◎ failure-domain.beta.kubernetes.io/region
与节点不同的是,Pod是属于某个命名空间的,所以条件Y表达的 是一个或者全部命名空间中的一个Label Selector。
和节点亲和相同,Pod亲和与互斥的条件设置也是requiredDuringSchedulingIgnoredDuringExecution和 preferredDuringSchedulingIgnoredDuringExecution。
Pod的亲和性被定义于PodSpec的affinity字段下的podAffinity子字段中。Pod间的互斥性则被定义于同一层次的podAntiAffinity子字段中。
例如:
参照目标Pod
apiVerison: v1
kind: Pod
metadata:
name: pod-flag
labels:
security: s1
app: nginx
spec:
containers:
- name: nginx
image: nginx
(1)Pod亲和性调度
apiVersion: v1
kind: Pod
metadata:
name: pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values: ["s1"]
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx
创建之后会发现两个Pod在同一个节点上
(2)Pod互斥性调度
apiVersion: v1
kind: Pod
metadata:
name: pod-antiaffinity
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values: ["s1"]
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx
创建之后会发现这个Pod跟参照Pod不在同一个节点上
8、Pod Priority Preemption:Pod优先级调度
在中大型集群中,为了尽可能提高集群的资源利用率,会采用优先级方案,即不同类型的负载对应不同的优先级,同时允许集群中的所有负载所需的资源总量超过集群可提供的资源,在这种情况下,当发生资源不足的情况时,系统可以选择释放一些不重要的负载(优先级最低的),保障最重要的负载能够获取足够的资源稳定运行。
如果发生了需要抢占的调度,高优先级Pod就可能抢占节点N,并将其低优先级Pod驱逐出节点N。
(1)首先创建PriorityClasses
apiVersion: v1
kind: scheduling.k8s.io/v1beta1
metadata:
name: high-priority
value: 10000
globalDefault: false
(2)然后在Pod中引用Pod优先级
apiVersion: v1
kind: Pod
metadata:
name: nginx-priority
spec:
containers:
- name: nginx
image: nginx
priorityClassName: high-priority
二、Pod的扩容和缩容
1、通过kubectl scale
通过kubectl scale进行扩容和缩容,其实就是修改控制器的副本数字段
kubectl scale rc rc-name --replicas=副本数量
比如我将nodeselectorrc扩容为3
缩容也是一样,将副本数量改小就行
2、Horizontal Pod AutoScale(HPA)
实现基于cpu使用率进行自动Pod扩缩容,HPA控制器基于Master的kube-controller-manager服务启动参数
--horizontal-pod-authscaler-sync-period
定义的时长(默认为30s),周期性的监测目标pod的cpu使用率,并在满足条件时对RC或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率
创建HPA时可以使用kubectl autoscale命令进行快速创建或者使用yaml配置文件进行创建,在创建HPA前,需要已经存在一个RC或者Deployment对象,并且必须定义resources.requests.cpu的资源请求值,如果不设置该值,则heapster将无法采集Pod的cpu使用率
【注】此方式需要安装heapster进行采集资源的cpu使用率
命令行方式:
kubectl autoscale rc rc-name --min=1 --max=10 --cpu-percent=50
yaml方式:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: hpa-name
spec:
scaleTargetRef:
apiVersion: v1
kind: ReplicationController
name: rc-name
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
上述两种方式都是在cpu使用率达到50%的时候进行扩缩容,最小副本数为1,最大副本数为10
三、Pod的滚动升级
滚动升级通过kubectl rolling-update命令完成,该命令创建了一个RC,然后自动控制旧的RC中的Pod副本的数量逐渐减少至0,同时新的RC中的Pod副本的数量从0逐步增加至目标值,最终实现了Pod的升级。新旧的RC需要在同一个Namespace下。
1、使用yaml进行升级
比如有一个nginx的v1版本:nginx-v1.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: roll-v1
labels:
name: roll-v1
version: v1
spec:
replicas: 3
selector:
name: roll-v1
version: v1
template:
metadata:
name: roll-v1
labels:
name: roll-v1
version: v1
spec:
containers:
- name: roll-v1
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
创建之后如下:
需要将其升级为v2版本:nginx-v2.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: roll-v2
labels:
name: roll-v2
version: v2
spec:
replicas: 3
selector:
name: roll-v2
version: v2
template:
metadata:
name: roll-v2
labels:
name: roll-v2
version: v2
spec:
containers:
- name: roll-v2
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
使用如下命令进行升级:
kubectl rolling-update roll-v1 -f nginx-v2.yaml
执行之后会逐步替换掉v1版本的pod
需要注意的是:
1、RC的名字不能与旧的RC相同
2、在selector中至少有一个Label与旧的不同,以表示其是新的RC。(其实是必须所有label不一样)
2、使用命令方式直接升级
也可以使用命令行直接替换掉容器的镜像
kubectl rolling-update rc-name --image=image-name:version
3、回滚
当滚动更新出现问题时,可以进行回滚
kubectl rolling-update rc-name --image=image-name:version --rollback
===============================
我是Liusy,一个喜欢健身的程序员。
欢迎关注微信公众号【Liusy01】,一起交流Java技术及健身,获取更多干货,领取Java进阶干货,领取最新大厂面试资料,一起成为Java大神。
来都来了,关注一波再溜呗。
k8s之深入解剖Pod(三)的更多相关文章
- k8s之深入解剖Pod(一)
上文说了一下k8s的简单使用,接下来就让我们来具体深入了解一下Pod.为了避免篇幅太长,所以会分成几篇. 目录: Pod定义详解 静态Pod Pod容器共享Volume 一.Pod定义详解 先看一个简 ...
- k8s之深入解剖Pod(二)
目录: Pod配置管理:ConfigMap 容器内获取Pod信息:Downward API Pod生命周期和重启策略 Pod健康检查 一.ConfigMap 将应用所需的配置信息与程序进行分离,可以使 ...
- k8s核心资源之Pod概念&入门使用讲解(三)
目录 1. k8s核心资源之Pod 1.1 什么是Pod? 1.2 Pod如何管理多个容器? 1.3 Pod网络 1.4 Pod存储 1.5 Pod工作方式 1.5.1 自主式Pod 1.5.2 控制 ...
- k8s集群搭建(三)
Dashboard安装 Kubernetes Dashboard是k8s提供基于Web的监控和操作界面,可以通过UI来显示集群的所有工作负载,除了查看资源,还是创建.编辑.更新.删除资源. 根据Kub ...
- k8s集群Job Pod 容器可能因为多种原因失效,想要更加稳定的使用Job负载,有哪些需要注意的地方?
k8s集群Job Pod 容器可能因为多种原因失效,想要更加稳定的使用Job负载,有哪些需要注意的地方? 面试官:"计数性Job默认完成模式是什么?Indexed模式如何发布自定义索引呢?& ...
- k8s运维之pod排错
k8s运维之pod排错 K8S是一个开源的,用于管理云平台中多个主机上的容器化应用,Kubernetes的目标是让部署容器化变得简单并且高效 K8S的核心优势: 1,基于yaml文件实现容器的自动创建 ...
- kubeadm搭建K8s集群及Pod初体验
基于Kubeadm 搭建K8s集群: 通过上一篇博客,我们已经基本了解了 k8s 的基本概念,也许你现在还是有些模糊,说真的我也是很模糊的.只有不断地操作去熟练,强化自己对他的认知,才能提升境界. 我 ...
- k8s通过Service访问Pod
如何创建服务 1.创建Deployment #启动三个pod,运行httpd镜像,label是run:mcw-httpd,Seveice将会根据这个label挑选PodapiVersion: apps ...
- k8s通过service访问pod(五)--技术流ken
service 每个 Pod 都有自己的 IP 地址.当 controller 用新 Pod 替代发生故障的 Pod 时,新 Pod 会分配到新的 IP 地址.这样就产生了一个问题: 如果一组 Pod ...
随机推荐
- iOS gif图显示问题
问题 有时候需要显示gif动态图,让界面更加的绚丽,但是iOS默认只支持png,gpg图片.那么如何才能显示gif图呢? 解决方式 添加框架 CoreGraphics.framework ImageI ...
- 无效的HTTP_主机头Invalid HTTP_HOST header: '192.168.56.100:8888'. You may need to add '192.168.56.100' to ALLOWED_HOSTS.
Invalid HTTP_HOST header: '192.168.56.100:8888'. You may need to add '192.168.56.100' to ALLOWED_HOS ...
- git学习与应用
git是什么 Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目:同类的有svn,如果知道svn是干嘛的(上篇),那么git是啥就不多解释了. Git 与常用的版本控制工具 C ...
- 【CF375D】Trees and Queries——树上启发式合并
(题面不是来自Luogu) 题目描述 有一个大小为n且以1为根的树,树上每个点都有对应的颜色ci.现给出m次询问v, k,问以v为根的子树中有多少种颜色至少出现了k次. 输入格式 第一行两个数n,m表 ...
- 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)
在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...
- SpringBoot整合阿里短信服务
导读 由于最近手头上需要做个Message Gateway,涉及到:邮件(点我直达).短信.公众号(点我直达)等推送功能,网上学习下,整理下来以备以后使用. 步骤 点我直达 登录短信服务控制台 点我直 ...
- 《技术男征服美女HR》—Fiber、Coroutine和多线程那些事
1.起点 我叫小白,坐在这间属于华夏国超一流互联网公司企鹅巴巴的小会议室里,等着技术面试官的到来. 令我感到不舒服的,是坐在我对面的那位HR美女一个劲儿的盯着我打量!虽说本人帅气,但是也不能这么毫无顾 ...
- TextClip构造方法报OSError:MoviePy creation of None failed because of the following [WinError 2]系统找不到指定的文件
☞ ░ 前往老猿Python博文目录 ░ 在使用moviepy的构造方法创建实例时报错: "C:\Program Files\Python37\python.exe" F:/stu ...
- Python中super()或object.__new__报TypeError: object.__new__() takes no arguments错误的解决方案
出现这种情况是调用object类__new__方法参数传递多了导致: 一般是使用了类似super().new(cls,*args,**kwargs) 或object.new(self,*args,** ...
- PyQt(Python+Qt)学习随笔:树型部件QTreeWidget中使用sortItems进行项排序
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件QTreeWidget中的项可以使用sortItems方法按照指定列进行排序,调用语法: s ...