文章目录
在kubernetes中,按照pod的创建方式可以将其分为两类:
自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建
控制器创建的pod:kubernetes通过控制器创建的pod,这种pod删除了之后还会自动重建
kubernetes一般都是通过pod控制器对pod进行管理,确保pod资源符合预期的状态。当pod的资源出现故障时,会尝试进行重启和重建pod。
在kubernetes中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有下面这些:
ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代
ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级
Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本
Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷
DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务
Job:它创建出来的pod只要完成任务就立即退出,不需要重启或重建,用于执行一次性任务
Cronjob:它创建的Pod负责周期性任务控制,不需要持续后台运行
StatefulSet:管理有状态应用
一、ReplicaSet
这种控制器保证一定数量的pod能够正常运行,一旦运行中的pod发生故障,就会重启或重建,同时也可以对pod的数量进行扩容,对版本镜像进行升级。
ReplicaSet的资源清单:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: rs
spec: # 详情描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
1、创建
vim pod-replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-pod
namespace: dev
labels:
dep: repli
spec:
replicas: 3
selector:
matchLabels:
dep: nginx-rep-pod
template:
metadata:
labels:
dep: nginx-rep-pod
spec:
containers:
- name: nginx-rep
image: nginx:1.17.1
ports:
- containerPort: 80
kubectl create -f pod-replicaset.yaml
2、扩缩容
(1)方法一
kubectl edit rs "名称" -n dev
该方式直接可以进行修改:
修改后查看:
(2)方法二
kubectl scale rs "名称" --replicas=2 -n dev
注:
--replicas=n直接指定目标数量即可
3、镜像升级
方法一:同上(扩缩容)
方法二:
kubectl set image rs rs名称 容器=镜像版本 -n namespace
4、删除
kubectl delete-f pod-replicaset.yaml
二、Deployment
k8s从V1.2版本开始引入Deployment控制器,这种控制器是通过管理ReplicaSet来间接管理pod,所以Deployment比RealicaSet功能更强大。
典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 支持发布的暂停、继续
Deployment的资源清单如下:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: deploy
spec: # 详情描述
replicas: 3 # 副本数量
revisionHistoryLimit: 3 # 保留历史版本,默认:10
paused: false # 暂停部署,默认是false
progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600
strategy: # 策略
type: RollingUpdate # 滚动更新策略
rollingUpdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
1、创建与扩容
(1)命令形式
创建:
kubectl create deploy nginx --image=nginx:1.17.1 -n dev
扩容:
kubectl scale deployment nginx --replicas 3 -n dev
说明:与ReplicaSet一样,也可以通过kubectl edit deploy “名称” -n dev来修改扩容
删除时直接删除对应的deployment即可:
kubectl delete deploy nginx -n dev
(2)使用yaml文件
vim deployment-dev.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: button-nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
test: nginx-test
template:
metadata:
labels:
test: nginx-test
spec:
containers:
- image: nginx:1.17.1
name: nginx4
ports:
- containerPort: 85
protocol: TCP
kubectl create -f deployment-dev.yaml
删除:
kubectl delete -f deployment-dev.yaml
更新:
kubectl apply -f deployment-dev.yaml
2、镜像升级
deployment支持两种更新策略:重建更新和滚动更新,可以通过strategy指定策略类型,支持属性有两个:
strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性:
type:指定策略类型,支持两种策略
Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod
RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
vim deployment-dev-new.yaml
这里使用rollingUpdate类型:
apiVersion: apps/v1
kind: Deployment
metadata:
name: button-nginx
namespace: dev
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 30%
maxSurge: 20%
replicas: 3
selector:
matchLabels:
test: nginx-test
template:
metadata:
labels:
test: nginx-test
spec:
containers:
- image: nginx:1.17.2
name: nginx4
ports:
- containerPort: 80
protocol: TCP
注:查看delpoyment,发现原来的依旧存在,只是pod数量变为了0,而后又新产生了一个delpoyment,pod数量为3,其实这就是deployment能够进行版本回退的原因
3、版本回退
deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能。
kubectl rollout: 版本升级相关功能,支持下面的选项:
status 显示当前升级状态
history 显示升级历史记录
pause 暂停版本升级过程
kubectl rollout pause deploy "名称" -n dev
resume 继续已经暂停的版本升级过程
kubectl rollout resume deploy "名称" -n dev
restart 重启版本升级过程
kubectl rollout restart deploy "名称" -n dev
undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)
kubectl rollout undo deploy "名称" --to-revision=1 -n dev
注:nginx版本又回到了1.17.1
我们平时更新新版本应用的时候,可以在一部分pod更新完成后执行暂停操作,此时一部分属于新版本,一部分还是属于旧版本,可以筛选一小部分用户请求路由到新版本的pod应用,如果确认升级新版本,则继续完成剩余pod的滚动升级即可,否则立即回退更新操作,这种被成为金丝雀发布。
三、Horizontal Pod Autoscaler(HPA)
Horizontal Pod Autoscaler(HPA)实现通过监测Pod的使用情况,实现pod数量的自动调整。HPA可以获取每个Pod利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。
注:kubernetes 1.8以下需要安装heapster,1.8以上建议使用metrics server,这里只演示metrics server的安装
yum install git -y
# 获取metrics-server
git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
cd /**/metrics-server/deploy/1.8+/
vim metrics-server-deployment.yaml
具体配置位置见下图:
hostNetwork: true
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
配置完成后保存继续执行如下命令:
kubectl apply -f ./
安装完成后稍等片刻:
kubectl get pod -n kube-system
kubectl top node
创建:
vim hpa-dev.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
strategy: # 策略
type: RollingUpdate # 滚动更新策略
replicas: 1
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
protocol: TCP
resources: # 资源配额
limits: # 限制资源(上限)
cpu: "1" # CPU限制,单位是core数
requests: # 请求资源(下限)
cpu: "100m" # CPU限制,单位是core数
---
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30333
selector:
app: nginx-pod
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: pc-hpa
namespace: dev
spec:
minReplicas: 1 #最小pod数量
maxReplicas: 10 #最大pod数量
targetCPUUtilizationPercentage: 3 # CPU使用率指标,当CPU平均负载大于30%后,将自动伸缩,最大伸缩Pod数为10个,最小1个。
scaleTargetRef: # 指定要控制的nginx信息
apiVersion: apps/v1
kind: Deployment
name: nginx
kubectl create -f hpa-dev.yaml
为了测试效果,我们使用Jmeter模拟高并发环境。
这是再查看就会发现又新创建了pod:
最多创建到10个pod
当请求量降低之后,创建的pod就会自动删除,直到满足配置的要求。
四、DaemonSet(DS)
这种控制器可以保证集群中的每一个节点上只运行一个副本,适用于节点监控、日志收集等场景。
DaemonSet控制器的特点:
- 集群中添加节点时,指定的 Pod 副本也将添加到该节点上
- 当节点从集群中移除时,Pod 也就被回收了
DaemonSet的资源清单:
apiVersion: apps/v1 # 版本号
kind: DaemonSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: daemonset
spec: # 详情描述
revisionHistoryLimit: 3 # 保留历史版本
updateStrategy: # 更新策略
type: RollingUpdate # 滚动更新策略
rollingUpdate: # 滚动更新
maxUnavailable: 1 # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
创建:
vim ds-dev.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pc-ds
namespace: dev
spec:
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
protocol: TCP
kubectl create -f ds-dev.yaml
可以发现每个节点上都只运行了一个pod。
五、Job
Job控制器用于调配pod对象运行一次性任务,容器中的进程在正常运行结束后不会对其进行重启,而是将pod对象置于completed状态。若容器中的进程因错误而终止,则需要依据配置确定重启与否,未运行完成的pod对象因其所在的节点故障而意外终止后会被重新调度。
Job的资源清单:
apiVersion: batch/v1 # 版本号
kind: Job # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: job
spec: # 详情描述
completions: 1 # 指定job需要成功运行Pods的次数。默认值: 1
parallelism: 1 # 指定job在任一时刻应该并发运行Pods的数量。默认值: 1
activeDeadlineSeconds: 30 # 指定job可运行的时间期限,超过时间还未结束,系统将会尝试进行终止。
backoffLimit: 6 # 指定job失败后进行重试的次数。默认是6
manualSelector: true # 是否可以使用selector选择器选择pod,默认是false
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: job-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [counter-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: job-pod
spec:
restartPolicy: Never # 重启策略只能设置为Never或者OnFailure
containers:
- name: bb-job
image: busybox
command: ['sh', '-c']
args: ['echo "start job";sleep 60; echo "job end"']
特别说明:
重启策略设置的说明:
如果指定为OnFailure,则job会在pod出现故障时重启容器,而不是创建pod,failed次数不变
如果指定为Never,则job会在pod出现故障时创建新的pod,并且故障pod不会消失,也不会重启,failed次数加1
如果指定为Always的话,就意味着一直重启,Job控制器不能设置为Always
创建:
vim job-dev.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
manualSelector: true
selector:
matchLabels:
app: job-pod
template:
metadata:
labels:
app: job-pod
spec:
restartPolicy: Never
containers:
- name: bb-job
image: busybox
command: ['sh', '-c']
args: ['echo "start job";sleep 60; echo "job end"']
kubectl create -f job-dev.yaml
创建完成后可以看到任务正在执行
任务执行后再次查看,发现状态已经成了Completed
Job控制器也支持并行任务,接下来在上面的配置中做一些修改:
vim job-dev-new.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
completions: 8 # 指定job需要成功运行Pods的次数。默认值: 1
parallelism: 4 # 指定job在任一时刻应该并发运行Pods的数量。默认值: 1
manualSelector: true
selector:
matchLabels:
app: job-pod
template:
metadata:
labels:
app: job-pod
spec:
restartPolicy: Never
containers:
- name: bb-job
image: busybox
command: ['sh', '-c']
args: ['echo "start job";sleep 60; echo "job end"']
kubectl create -f job-dev-new.yaml
kubectl get pods -n dev -w
观察如下的创建过程:
六、CronJob(CJ)
这种控制器简单的理解就是在特定的时间点反复的去运行job任务。这里的反复是通过cron表达式定义的。
CronJob的资源清单:
apiVersion: batch/v1beta1 # 版本号
kind: CronJob # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: cronjob
spec: # 详情描述
schedule: # cron格式的作业调度运行时间点,用于控制任务在什么时间执行
concurrencyPolicy: # 并发执行策略,用于定义前一次作业运行尚未完成时是否以及如何运行后一次的作业
failedJobHistoryLimit: # 为失败的任务执行保留的历史记录数,默认为1
successfulJobHistoryLimit: # 为成功的任务执行保留的历史记录数,默认为3
startingDeadlineSeconds: # 启动作业错误的超时时长
jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象;下面其实就是job的定义
metadata:
spec:
completions: 1
parallelism: 1
activeDeadlineSeconds: 30
backoffLimit: 6
manualSelector: true
selector:
matchLabels:
app: counter-pod
matchExpressions: 规则
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox
说明:
1、cron表达式不过多说明
cron表达式,用于指定任务的执行时间
*/1 * * * *
<分钟> <小时> <日> <月份> <星期>
2、并发执行策略
concurrencyPolicy:
Allow: 允许Jobs并发运行(默认)
Forbid: 禁止并发运行,如果上一次运行尚未完成,则跳过下一次运行
Replace: 替换,取消当前正在运行的作业并用新作业替换它
创建:
vim cronjob-dev.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-dev
namespace: dev
labels:
test: cronjob-dev
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
metadata:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: bb-dev
image: busybox
command: ['sh', '-c']
args: ['echo "start job";sleep 10; echo "job end"']
kubectl create -f cronjob-dev.yaml
查看可以发现,每分钟会执行一次