Pod的控制器是什么?
pod控制器:工作负载均衡。workload。用于管理pod的中间层。确保pod资源符合预期的状态。
预期状态:
-
副本数
-
容器的重启策略
-
镜像拉取策略
pod出现故障时的重启等等
Pod控制器的类型
1、 replicaSet:指定副本的数量
三个组件:
-
Pod的副本数
-
标签选择器:判断哪个pod归自己管理
-
扩缩容
2、 Deployment控制器,他是工作在replicaSet之上。管理无状态应用。目前是最好的控制器。支持滚动跟新和回滚。提供声明式配置。
3、 statefulSet:也是控制器的一种,管理有状态的应用。也可也设置副本数,可以扩缩容。 Pod的序号是固定的。重启之后,Pod的名称也不会发生变化。表示有状态的pod
4、 DaemonSet:可以在所有节点部署一个pod。它没有副本数。可以限制部署的节点。也是无状态应用。服务必须是守护进程。例如: ingress、logstash、flannel
5、 job:工作pod控制器。执行完成即可退出。不需要重启,不需要重建。
6、 cronjob:周期性的定时任务控制器。不需要再后台持续运行。
Pod与控制器之间的关系
1、 controllers
1、 controllers:管理控制器
pod通过label---selector进行关联。
通过标签和选择标签和控制器关联
strategy字段:
web应用不需要加strategy字段会导致服务中断。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx1
strategy:
type: Recreate
#每次有更新,都会把旧的pod全部停止,然后再启动新的实例。服务可能会短暂的终端。无特殊需要可不加
template:
metadata:
labels:
app: nginx1
spec:
containers:
- image: nginx:1.22
name: nginx
strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25%
这是deployment的默认更新策略
rollingUpdate:滚动跟新
maxSurge: 25% 升级过程中,新启动的pod数量不能超过期望pod数的25%
maxUnavailable: 25% 升级过程中,新的pod启动好后,销毁的旧pod数量不能超过期望pod的25%
升级和销毁都不能超过期望pod的25%这样不会导致业务中断
2、 无状态应用
2、 无状态应用:pod名称是无序的。认为所有pod都是一体的。共享NFS存储。
所有deployment下的pod共享一个存储。
statfulSet:有状态应用。pod的名称是有序的。所有pod都是独立的。存储卷也是独立的。顺序从0开始到n。
delete删除也不会改变pod的序号。扩缩容也是有序扩缩容。同样从0开始
headless service:无头服务,他没有clusterIP。必须要有动态的pvc
statfulSet有状态应用控制器实验举例:
apiVersion: v1
kind: Service
metadata:
name: nginx-web
labels:
app: nginx2
spec:
ports:
- port: 80
targetPort: 80
clusterIP: ""
selector:
app: nginx2
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
labels:
app: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
serviceName: "nginx-web"
template:
metadata:
labels:
app: nginx2
spec:
apiVersion: v1
kind: Service
metadata:
name: nginx-web
labels:
app: nginx2
spec:
ports:
- port: 80
targetPort: 80
clusterIP: ""
#clusterIP必须为空
selector:
app: nginx2
---
apiVersion: apps/v1
#开始创建控制器
kind: StatefulSet
metadata:
name: web
labels:
app: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
serviceName: "nginx-web"
#定义应用哪个service文件
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: nginx
image: nginx:1.22
volumeMounts:
#定义挂载卷
- name: html
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
#定义动态卷
- metadata:
name: html
spec:
accessModes: ["ReadWriteMany"]
#定义挂载卷权限
storageClassName: "nfs-client-storageclass"
resources:
requests:
storage: 2Gi
headless service无头服务:是k8s集群中一种特殊的服务类型。
-
他不分配clusterIP给service。
-
不会负载均衡到后端的pod。
-
通过DNS来提供服务的发现和访问。
由于ClusterIP是空的。k8s集群会给每个headless service中的pod创建一个dns记录。
格式: pod-name.headless-service-name.namespace.svc.cluster.local.
通过dns直接解析访问pod的IP地址
为什么要使用headless?
有序、独立个体
deployment的pod是没有名称的。随机字符串且无序的。他需要一个集中的clusterIP来集中统一为pod提供网络。
statefulset是有序的。pod名称是固定的。即便是重建之后pod的表示也不变。pod的名称是唯一的标识符。
系统直接通过pod名称解析IP地址。
只要pod名称不变通过pod名来映射IP地址即可
为什么要使用动态PV?
只要是有状态的副本集群都会涉及到持久化存储。但是每个pod是独立个体。每个pod都有自己专用的存储点。
statefulSet再定义时就规定了每个pod不能使用同一个存储卷。所以才需要动态PV
定义好了每个pod都必须绑定一个存储卷所以使用动态pv
statefulset的使用场景
-
用于不是固定节点的应用。不是固定IP的应用。
-
更新发布比较频繁的场景
-
支持自动伸缩。节点资源不够,可以自动扩容的场景。
删除statefulset
不需要clusterIP。没有clusterIP的就是无头服务headless
3、 demonSet
3、 demonSet:确保每个节点上都运行一个pod副本。如果有node加入集群,也会为他薪资一个pod
实验举例:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemon
labels:
app: nginx1
#提高代码的可读性。方便别人读。不同业务可以通过namespace隔离。
#命名时根据业务进行专业命名
spec:
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx:1.22
#部署一个daemonset的控制器。
#daemonset不能指定副本数他会在每个节点上都创建一个pod
和deployment一样都是无状态应用。
指定节点部署:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemon
labels:
app: nginx1
#提高代码的可读性。方便别人读。不同业务可以通过namespace隔离。
#命名时根据业务进行专业命名
spec:
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx:1.22
nodeSelector:
ingress: "true"
#只在有ingress为true这个标签的节点上部署,没有这个标签的节点不会部署
kubectl delete daemonsets.apps nginx-daemon
#删除daemonSet控制器
daemonSet不需要指定调度策略,默认会在每个节点上创建一个pod。除非设置了污点。我们也可以通过指定的方式。只把daemonSet部署在指定的节点。
daemonSet没有副本数选择。
控制器类型的资源创建方式:基于控制器创建的pod,delete只是相当于重启。要彻底删除pod,必须删除控制器
千万不要随别delete
4、job
4、 job:分为两类
job表示普通任务
cronjob表示定时任务
job的作用就是执行只需要执行一次性的任务。例如:执行脚本、数据库迁移、视频解码等等业务。
job普通任务
实验举例:
apiVersion: batch/v1
kind: Job
metadata:
name: centos
spec:
template:
spec:
containers:
- name: centos
image: centos:7
command: ["/bin/bash", "-c", "test -e /etc/passwd"]
#定义一个任务
#Job类型的参数必须要设置重启策略。只支持“OnFailure、Never”两种策略
restartPolicy: Never
#指定重启策略
backoffLimit: 4
#定义重启次数。如果不加默认6次
#允许任务失败的次数是4次。
#当达到4次之后。根据容器的重启策略restartPolicy来进行容器的重启或者是不重启。
kubectl delete jobs.batch centos
#删除控制器
对于k8s系统来说,既然定义了是job。你只需要执行一次,或者指定册数即可。不能一直允许。
它拥有两个限制:
-
必须要指定容器容器策略:OnFailure、Never
-
执行失败的次数也是受限制的。默认是6次。字数可以通过添加 backoffLimit 来自定义失败次数
-
跟新yaml文件要先删除任务。再更新。不能动态更新。
5、 cronjob
cronjob:周期性执行任务,定时执行。和linux的crontab含义是一样的。语法一样都是 分 时 日 月 周
应用场景:定时备份、通知作用、定时检查(结合探针一起布置设定多长时间执行一次)
实验举例:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Allow
#可选字段 执行失败任务的保留个数
startingDeadlineSeconds: 15
#可选字段 pod启动之后必须在一定时间内开始执行。如果超过15秒仍未运行,则任务将不会运行。任务也会标记失败。
successfulJobsHistoryLimit: 3
#可选字段 保留成功的任务数。默认保留3个
jobTemplate:
#定义任务模板。容器需要执行的命令是什么
spec:
template:
spec:
containers:
- name: hello
image: centos:7
command: ["/bin/bash", "-c", "date; echo zyg"]
restartPolicy: Never
kubectl delete cronjobs.batch hello
#删除定时任务
总结
五个都是控制器创建的pod都是依赖于控制器。
deployment:无状态应用。最好用的。也是最多的
statefulSet:有状态应用。有序的。独立的pod
daemonSet:无状态应用。不能定义副本数。每个系欸但都运行一个pod。可以指定节点。
job:执行一次性的任务。必须要有重启策略。同时默认失败次数6次。只有失败次数达到,重启策略才会生效
cronjob:定时任务。通知。备份或者探测。执行定时任务。必须要有重启策略。默认失败3次。只有失败次数达到后重启策略才会生效