Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为
Deployment:适合无状态的服务部署
StatefullSet:适合有状态的服务部署
DaemonSet:一次部署,所有的node节点都会部署,例如一些典型的应用场景:
运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph
在每个Node上运行日志收集 daemon,例如 fluentd、 logstash
在每个Node上运行监控 daemon,例如 Prometheus Node Exporter
Job:一次性的执行任务
Cronjob:周期性的执行任务
总体来说,K8S有五种控制器,分别对应处理无状态应用、有状态应用、守护型应用和批处理应用
controllers:在集群上管理和运行容器的对象通过label-selector相关联
应用场景:web服务
Deployment中文意思为部署、调度,通过Deployment我们能操作RS(ReplicaSet),你可以简单的理解为它是一种通过yml文件的声明,在Deployment 文件里可以定义Pod数量、更新方式、使用的镜像,资源限制等。无状态应用都用Deployment来创建
通过Deployment对象,你可以轻松的做到以下事情:
Deployment创建
[root@master shuai]# vim nginx-delpoy.yaml
apiVersion: apps/v1
kind: Deployment '定义是Deployment'
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 '副本数量为3'
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
ports:
- containerPort: 80
'创建资源'
[root@master shuai]# kubectl apply -f nginx-delpoy.yaml
deployment.apps/nginx-deployment created
//Replicaset 是控制版本,副本数,回滚就是通过此来实现
'//查看所有资源'
[root@master shuai]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-d55b94fd-cndf2 1/1 Running 0 3m31s
pod/nginx-deployment-d55b94fd-ghlwk 1/1 Running 0 3m31s
pod/nginx-deployment-d55b94fd-tm4sw 1/1 Running 0 3m31s
pod/pod-example 1/1 Running 0 10h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d6h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3 3 3 3 3m31s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-d55b94fd 3 3 3 3m31s
查看控制器信息
kubectl deit deployment/nginx-deployment
.....省略信息.....
strategy:
rollingUpdate: '版本更新为滚动更新机制'
maxSurge: 25% '最大更新副本数是25%,最多扩容125%' '为了保持副本数量,增加的百分比同时要销毁多少'
maxUnavailable: 25% '最大删除副本是25%,最多缩容到75%'
type: RollingUpdate
...省略信息....
'执行kubectl describe deploy nginx-deployment 也可以查看'
....省略信息....
RollingUpdateStrategy: 25% max unavailable, 25% max surge
查看历史版本
[root@master shuai]# kubectl rollout history deploy/nginx-deployment
deployment.extensions/nginx-deployment
REVISION CHANGE-CAUSE
1 <none> '//这边只有一个,证明还没有滚动更新'
无状态服务的特点:
1)deployment 认为所有的pod都是一样的
2)不用考虑顺序的要求
3)不用考虑在哪个node节点上运行
4)可以随意扩容和缩容
有状态服务的特点:
1)实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
2)实例之间不对等的关系,以及依靠外部存储的应用。
如果想要让 nginx pod 使用 nginx:1.9.1 的镜像来代替原来的 nginx的镜像,运行以下命令
[root@master ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.apps/nginx-deployment image updated
或者我们可以使用 edit 命令来编辑 Deployment,将image从nginx改写成 nginx:1.9.1
kubectl edit deployment/nginx-deployment
查看更新进度
[root@master ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
Deployment更新时会创建一个新的ReplicaSet,然后将新的ReplicaSet中的Pod慢慢扩容到指定的副本数,将旧的ReplicaSet慢慢缩容到0。因此,更新时总能够确保旧的服务不会停止,这就是滚动更新。
当我们像上文一样更新了Deployment之后,我们发现nginx:1.9.1的镜像不是很稳定,因此想要修改回nginx:1.7.9的版本,此时我们不需要手动更改Deployment文件,而是利用Deployment的回滚功能。
使用rollout history命令查看Deployment的版本(revision):
[root@master ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=deploy.yml --record=true
2 kubectl create --filename=deploy.yml --record=true
因为我们创建 Deployment 的时候使用了 —recored 参数可以记录命令,我们可以很方便的查看每次 revison 的变化。
查看单个 revision 的详细信息:
[root@master ~]# kubectl rollout history deployment/nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=658d7f4b4b
Annotations: kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
可以使用rollout undo命令回滚到前一个revision
[root@master ~]# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
[root@master ~]# kubectl describe deployment/nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Fri, 24 Dec 2021 22:24:10 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 3
kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
也可以使用–to-revision参数指定某个历史版本:
[root@master ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back
[root@master ~]# kubectl describe deployment/nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Fri, 24 Dec 2021 22:24:10 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 4
kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 4 total | 3 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
你可以通过设置 .spec.revisonHistoryLimit 项来指定 deployment 最多保留多少 revison 历史记录。默认的会保留所有的 revision;如果将该项设置为 0,Deployment 就不允许回退了。
只有 Deployment 的 rollout 被触发才会创建一个 revision!注意!当且仅当 Deployment 的 Pod template被更改,例如更新 template 中的 label 和容器镜像时,才会触发一个rollout,从而为Deployment创建出一个新的 revision。
rollout命令的更多用法:
Job Controller负责根据Job Spec创建Pod,并持续监控Pod的状态,直至其成功结束。如果失败,则根据restartPolicy(只支持OnFailure和Never,不支持Always)决定是否创建新的Pod再次重试任务。
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
Kubernetes支持以下几种Job:
JOB类型 | 使用实例 | 行为 | completions | parallelism |
---|---|---|---|---|
一次性Job | 数据库迁移 | 创建一个Pod直至其成功结束 | 1 | 1 |
固定结束次数的Job | 处理工作队列的Pod | 依次创建一个Pod运行直至completions个成功结束 | 2+ | 1 |
固定结束次数的并行Job | 多个Pod同时处理工作队列 | 依次创建多个Pod运行直至completions个成功结束 | 2+ | 2+ |
并行Job | 多个Pod同时处理工作队列 | 创建一个或多个Pod直至有一个成功结束 | 1 | 2+ |
.job的使用
[root@master ~]# vi job.yml
---
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
template:
spec:
containers:
- name: myjob
image: busybox
command: ["echo", "hello k8s job"]
restartPolicy: Never
[root@master ~]# kubectl apply -f job.yml
job.batch/myjob created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myjob-gq27p 0/1 Completed 0 37s
#查看这个 pod的任务
[root@master ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
myjob 1/1 19s 5m11s
#查看这个 pod的日志
[root@master ~]# kubectl logs myjob-gq27p
hello k8s job
CronJob 可以用来执行基于时间计划的定时任务,类似于Linux/Unix系统中的 crontable (opens new window)。
CronJob 执行周期性的重复任务时非常有用,例如备份数据、发送邮件等。CronJob 也可以用来指定将来某个时间点执行单个任务,例如将某项任务定时到系统负载比较低的时候执行。
一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用Cron格式进行编写, 并周期性地在给定的调度时间执行 Job。
注意:
所有 CronJob 的 schedule: 时间都是基于kube-controller-manager. 的时区。
如果你的控制平面在 Pod 或是裸容器中运行了 kube-controller-manager, 那么为该容器所设置的时区将会决定 Cron Job 的控制器所使用的时区。
为 CronJob 资源创建清单时,请确保所提供的名称是一个合法的DNS 子域名. 名称不能超过 52 个字符。 这是因为 CronJob 控制器将自动在提供的 Job 名称后附加 11 个字符,并且存在一个限制, 即 Job 名称的最大长度不能超过 63 个字符。
CronJob 用于执行周期性的动作,例如备份、报告生成等。 这些任务中的每一个都应该配置为周期性重复的(例如:每天/每周/每月一次); 你可以定义任务开始执行的时间间隔。
下面的 CronJob 示例清单会在每分钟打印出当前时间和问候消息:
[root@master kubenetres]# vi cronjob.yml
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello nihao
restartPolicy: OnFailure
创建pod查看
[root@master ~]# kubectl apply -f cronjob.yml
Warning: batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob
cronjob.batch/hello created
#等一分钟查看
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27339330-kkfxv 0/1 Completed 0 2s
#查看日志
[root@master ~]# kubectl logs hello-27339330-kkfxv
Fri Dec 24 15:30:00 UTC 2021
Hello nihao