1.1 Pod控制器介绍
在Kubernetes中,Pod是最小的管理单元,用于运行容器。根据Pod的创建方式,可以将其分为两类:
-
自主式Pod(Stateless Pods):这些Pod是直接由用户或管理员创建的,通常是通过直接使用
kubectl run
命令或通过YAML文件定义来创建的。这些Pod在创建后由Kubernetes直接管理,但它们的生命周期是独立的。这意味着如果这些Pod被删除,Kubernetes不会自动重建它们。自主式Pod通常用于运行短生命周期的任务或服务,例如批处理作业、数据迁移等。 -
控制器创建的Pod(Managed Pods):这些Pod是由Kubernetes控制器创建和管理的。控制器是Kubernetes中的高级对象,它们负责根据定义的规则创建、更新和删除Pod。控制器创建的Pod通常是为了实现更复杂的应用部署和管理需求,例如部署、复制集(ReplicaSet)、状态集(StatefulSet)、DaemonSet等。这些Pod的生命周期是由控制器管理的,如果Pod被删除,控制器会根据其配置自动重建Pod,以确保集群中始终有足够数量的Pod在运行。
Pod控制器(Pod Controller)是Kubernetes中的一种对象,用于管理一组具有相同配置的Pod。Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。
1.1.1 常见使用场景
Pod控制器用于管理一组Pod,确保它们按照预定的规则运行和扩展。以下是Kubernetes中常见的几种Pod控制器及其适用场景的整理:
-
ReplicationController:这是早期用于确保指定数量的Pod副本始终运行的控制器,但现在已经不推荐使用,其功能被ReplicaSet所替代。
-
ReplicaSet:用于保证Pod的副本数量维持在用户指定的数量。它支持Pod数量的扩缩容,以及Pod模板的更新,但不涉及应用状态的管理。
-
Deployment:是ReplicaSet的扩展,提供了应用的声明式更新能力。它允许用户定义应用的期望状态,自动处理Pod的创建、更新和删除,支持滚动更新和版本回退。
-
Horizontal Pod Autoscaler (HPA):根据CPU使用率或其他选择的度量指标自动扩展Pod的数量,适用于需要根据负载动态调整Pod数量的场景。
-
DaemonSet:确保在集群中的每个Node上都运行一个Pod的副本,通常用于运行集群存储、日志收集等守护进程类任务。
-
Job:用于运行批处理任务,即执行一次性任务。当Pod完成其工作后,Job控制器会负责清理这些Pod。
-
CronJob:用于周期性地创建Job对象,执行定时任务,类似于Unix中的crontab。
-
StatefulSet:用于管理有状态的服务,它为Pod提供了稳定的网络标识、顺序部署、缩放以及扩展和滚动更新的能力。
1.1.2 Pod控制器分类
Kubernetes的控制器分为以下几类:
-
无状态应用:由Deployment和ReplicaSet管理,适用于不需要持久化存储的应用。
-
有状态应用:由StatefulSet管理,适用于需要持久化存储和有序部署的应用。
-
守护型应用:由DaemonSet管理,适用于需要在所有或特定Node上运行的服务。
-
批处理应用:由Job和CronJob管理,适用于执行一次性或周期性任务。
1.2 Pod与控制器之间的关系
-
Pod与控制器之间的关系是,控制器是Kubernetes中用于管理一组Pod的高级对象,而Pod是Kubernetes中运行容器的最小单元。
-
控制器通过定义一组标签选择器来跟踪和控制具有这些标签的Pod。
-
当Pod因故障而终止时,控制器会根据定义的规则自动创建新的Pod来替换它,从而确保应用的持续运行和所需的副本数量
-
此外,控制器还负责处理Pod的水平扩展、版本更新和滚动升级等运维任务,而Pod本身只负责运行容器化的应用。
-
控制器为Pod提供了生命周期管理和运维自动化的框架。
1.3 ReplicaSet(RS)控制器
-
ReplicaSet(RS)是一种Kubernetes控制器,用于确保指定数量的Pod副本始终运行,从而提供高可用性和负载均衡。副本集通过监控和管理Pod的副本数量,自动进行Pod的创建、更新和删除,以维护用户定义的副本数量。
1.3.1 清单文件写法
--- apiVersion: apps/v1 # 版本号 kind: ReplicaSet # 类型 metadata: # 元数据 name: rs-nginx # rs名称 namespace: default # 所属命名空间 labels: # 标签 controller: rs spec: # 详情描述 replicas: 3 # 副本数量 selector: # 选择器,通过它指定该控制器管理哪些pod matchLabels: app: nginx-pod # Labels匹配规则 matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} # Expressions匹配规则 template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.11.1 ports: - containerPort: 80
ReplicaSet配置中spec
字段下的三个关键选项:
-
replicas:这个字段指定了ReplicaSet应该维护的Pod副本的数量。默认情况下,如果未指定,它会设置为1。通过增加副本数量,可以提高应用的可用性和容错性。
-
selector:选择器用于确定ReplicaSet管理的Pod集合。它通过标签选择器(Label Selector)机制工作。ReplicaSet的选择器必须与Pod的标签匹配,这样ReplicaSet才能跟踪和控制这些Pod。选择器由两部分组成:
-
matchLabels:这是一个匹配所有标签的字典,只有当Pod的所有这些标签都与选择器中的标签完全匹配时,ReplicaSet才会管理该Pod。
-
matchExpressions:这是一个更复杂的匹配,允许使用特定的操作符(如In, NotIn, Exists, DoesNotExist等)来匹配标签。
-
-
template:这是一个Pod模板,ReplicaSet使用它来创建新的Pod。当Pod数量少于
replicas
指定的数量时,或者当现有的Pod失败需要替换时,ReplicaSet会根据这个模板创建新的Pod。模板中定义了Pod的详细规格,包括容器的镜像、名称、端口、环境变量、存储卷等。
1.3.2 创建ReplicaSet
[root@K8s-master ~]# vim pc-replicaset.yaml --- apiVersion: apps/v1 # 指定了API版本,这是ReplicaSet所使用的API版本 kind: ReplicaSet metadata: name: pc-rs namespace: test spec: replicas: 3 # 指定了ReplicaSet应该确保在运行的Pod的数量。 selector: # 定义了哪些Pod应该被ReplicaSet管理 matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.11.1 [root@K8s-master ~]# kubectl apply -f pc-replicaset.yaml replicaset.apps/pc-rs created [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-rs-75hwq 1/1 Running 0 2m46s 10.244.2.30 k8s-node-02 <none> <none> pc-rs-jgrc9 1/1 Running 0 2m46s 10.244.2.32 k8s-node-02 <none> <none> pc-rs-zwllg 1/1 Running 0 2m46s 10.244.2.31 k8s-node-02 <none> <none> # 建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码 [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide #查看rs NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-rs 3 3 3 170m nginx nginx:1.11.1 app=nginx-pod # DESIRED:期望副本数量 # CURRENT:当前副本数量 # READY:已经准备好提供服务的副本数量
1.3.3 ReplicaSet扩缩容
-
方法一编辑ReplicaSet
pc-rs
# 将rs的副本数改成6 [root@K8s-master ~]# kubectl edit rs pc-rs -n test ... spec: replicas: 6 ... [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-rs 6 6 6 175m nginx nginx:1.11.1 app=nginx-pod [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-rs-75hwq 1/1 Running 0 176m 10.244.2.30 k8s-node-02 <none> <none> pc-rs-84qbg 1/1 Running 0 62s 10.244.2.35 k8s-node-02 <none> <none> pc-rs-8d8l8 1/1 Running 0 62s 10.244.2.33 k8s-node-02 <none> <none> pc-rs-g4792 1/1 Running 0 62s 10.244.2.34 k8s-node-02 <none> <none> pc-rs-jgrc9 1/1 Running 0 176m 10.244.2.32 k8s-node-02 <none> <none> pc-rs-zwllg 1/1 Running 0 176m 10.244.2.31 k8s-node-02 <none> <none>
-
方法二使用命令修改
# 使用scale命令实现扩缩容, 后面--replicas=n直接指定目标数量即可 [root@K8s-master ~]# kubectl scale rs pc-rs --replicas 2 -n test replicaset.apps/pc-rs scaled [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-rs-jgrc9 1/1 Running 0 3h1m 10.244.2.32 k8s-node-02 <none> <none> pc-rs-zwllg 1/1 Running 0 3h1m 10.244.2.31 k8s-node-02 <none> <none>
1.3.4 ReplicaSet镜像更新
-
方法一编辑ReplicaSet
pc-rs
[root@K8s-master ~]# kubectl edit rs pc-rs -n test ... spec: containers: - image: nginx:1.11.2 ... [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide #从nginx:1.11.1更新到了nginx:1.11.2 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-rs 2 2 2 3h9m nginx nginx:1.11.2 app=nginx-pod
-
方法二使用命令修改
# kubectl set image rs rs名称 容器=镜像版本 -n namespace [root@K8s-master ~]# kubectl set image rs pc-rs nginx=nginx:1.11.3 -n test replicaset.apps/pc-rs image updated [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-rs 2 2 2 3h12m nginx nginx:1.11.3 app=nginx-pod
1.3.5 ReplicaSet删除
[root@K8s-master ~]# kubectl delete rs pc-rs -n test replicaset.apps "pc-rs" deleted [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide Error from server (NotFound): replicasets.apps "pc-rs" not found [root@K8s-master ~]# kubectl get pod -n test -o wide No resources found in test namespace. # 如果希望仅仅删除RS对象(保留Pod),可以使用kubectl delete命令时添加--cascade=false选项(不推荐) [root@K8s-master ~]# kubectl delete rs pc-rs -n test --cascade=orphan replicaset.apps "pc-rs" deleted [root@K8s-master ~]# kubectl get rs pc-rs -n test -o wide Error from server (NotFound): replicasets.apps "pc-rs" not found [root@K8s-master ~]# kubectl get pod -n test -o wide #Pod保留 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-rs-4rdpw 1/1 Running 0 108s 10.244.2.40 k8s-node-02 <none> <none> pc-rs-7n9qj 1/1 Running 0 108s 10.244.2.41 k8s-node-02 <none> <none> pc-rs-rkgmr 1/1 Running 0 108s 10.244.2.39 k8s-node-02 <none> <none> [root@K8s-master ~]# kubectl delete pod pc-rs-4rdpw -n test #没有了控制器Pod不会创建 pod "pc-rs-4rdpw" deleted [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-rs-7n9qj 1/1 Running 0 4m10s 10.244.2.41 k8s-node-02 <none> <none> pc-rs-rkgmr 1/1 Running 0 4m10s 10.244.2.39 k8s-node-02 <none> <none> [root@K8s-master ~]# kubectl delete -f pc-replicaset.yaml #也可以直接删文件 replicaset.apps "pc-rs" deleted [root@K8s-master ~]# kubectl get pod -n test -o wide No resources found in test namespace.
1.4 Deployment(Deploy)控制器
-
从Kubernetes 1.2版本开始,引入了Deployment控制器,它提供了一种更高级别的抽象来管理应用的生命周期,包括应用的声明式更新、回滚、暂停和恢复等。Deployment的设计目标是简化应用的部署和扩展,同时提供强大的应用更新和版本管理功能。
-
这种控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。
1.4.1 Deployment主要功能
-
ReplicaSet管理:Deployment控制器会创建一个或多个ReplicaSet对象来管理Pod的副本,确保指定数量的Pod副本始终运行。
-
声明式更新:用户可以声明他们希望Pod如何更新,Deployment会自动将当前状态变更为用户所期望的状态。
-
滚动更新:Deployment支持滚动更新(Rolling Update),这意味着在更新过程中,旧版本的Pod会逐个被新版本的Pod替换,直到所有Pod都更新到新版本。
-
版本控制:Deployment记录了Pod模板的历史版本,允许用户回滚到之前的版本,如果新版本存在问题。
-
暂停和恢复:用户可以暂停Deployment的更新,进行维护或修改,之后可以恢复更新。
-
扩展和缩减:用户可以根据需要对Deployment控制的Pod数量进行扩展或缩减。
-
健康检查:Deployment可以使用liveness和readiness探针来确定Pod的健康状态,并在必要时进行适当的处理。
-
策略配置:用户可以为Deployment配置更新策略,包括更新的速度和模式。
-
历史记录:Deployment控制器会保留Pod模板的变更历史,通常保留最近的几次更新,以便于回滚操作。
-
状态检查:提供了观察Deployment状态的能力,包括它的更新进度和条件。
1.4.2 Deployment 清单文件
--- apiVersion: apps/v1 # 版本号 kind: Deployment # 类型 metadata: # 元数据 name: pc-deployment # rs名称 namespace: test # 所属命名空间 labels: # 标签 controller: deploy spec: # 详情描述 replicas: 3 # 副本数量 revisionHistoryLimit: 3 # 保留历史版本 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:1.11.1 ports: - containerPort: 80
1.4.3 创建Deployment
[root@K8s-master ~]# kubectl get deployments.apps -n test -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 3/3 3 3 29s nginx nginx:1.11.1 app=nginx-pod [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-deploy-58f96bbff4-5tg5s 1/1 Running 0 41s 10.244.2.46 k8s-node-02 <none> <none> pc-deploy-58f96bbff4-8z2hb 1/1 Running 0 41s 10.244.2.47 k8s-node-02 <none> <none> pc-deploy-58f96bbff4-tgfxq 1/1 Running 0 41s 10.244.2.45 k8s-node-02 <none> <none>
1.4.4 Deployment扩缩容
-
命令方式
[root@K8s-master ~]# kubectl scale deploy pc-deploy --replicas=5 -n test deployment.apps/pc-deploy scaled [root@K8s-master ~]# kubectl get deployments.apps -n test -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 5/5 5 5 2m25s nginx nginx:1.11.1 app=nginx-pod
-
编辑副本
[root@K8s-master ~]# kubectl edit deployments.apps pc-deploy -n test spec: progressDeadlineSeconds: 600 replicas: 10 [root@K8s-master ~]# kubectl get deployments.apps -n test -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 10/10 10 10 4m2s nginx nginx:1.11.1 app=nginx-pod
1.4.5 Deployment镜像更新
Deployment控制器确实支持两种主要的更新策略:重建更新(Recreate)和滚动更新(RollingUpdate)。这两种策略定义了如何替换Deployment中的Pods以进行更新。可以通过strategy
字段指定更新策略类型,并设置相关的属性。以下是两种策略的简要说明:
-
重建更新(Recreate):
-
在这种策略下,Deployment控制器会先终止所有正在运行的Pods,然后再创建新的Pods。
-
这种方法会导致短暂的停机时间,因为旧的Pods全部停止后才进行新的Pods的创建。
-
这种策略适用于小型应用或对停机时间不敏感的场景。
-
属性设置示例:
spec: strategy: # 策略 type: Recreate # 重建更新
-
-
滚动更新(RollingUpdate):
-
这是默认的更新策略,它允许你指定两个属性:
maxUnavailable
和maxSurge
。 -
maxUnavailable
定义了在更新过程中可以处于不可用状态的最大Pod数量。这可以设置为绝对数量或是Pod总数的百分比。 -
maxSurge
定义了可以超出期望数量创建的新Pod的最大数量。这同样可以设置为绝对数量或是Pod总数的百分比。 -
滚动更新策略可以确保在更新过程中始终有一定数量的Pod在线,从而减少或避免停机时间。
-
属性设置示例:
strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 #在更新过程中,可以有一个Pod处于不可用状态 maxSurge: 1 #可以有一个额外的Pod在更新完成前被创建
-
1.4.5.1 重建更新(Recreate)
[root@K8s-master ~]# vim pc-deployment.yaml #spec下添加策略 spec: strategy: type: Recreate [root@K8s-master ~]# kubectl apply -f pc-deployment.yaml deployment.apps/pc-deploy configured [root@K8s-master ~]# kubectl set image deploy pc-deploy nginx=nginx:1.11.4 -n test deployment.apps/pc-deploy image updated [root@K8s-master ~]# kubectl get pods -n test -w #动态监控 NAME READY STATUS RESTARTS AGE pc-deploy-6d547d6945-7nmfx 0/1 Pending 0 0s pc-deploy-6d547d6945-k5dpk 0/1 Pending 0 0s pc-deploy-6d547d6945-pnnkj 0/1 Pending 0 0s pc-deploy-6d547d6945-7nmfx 0/1 ContainerCreating 0 1s pc-deploy-6d547d6945-pnnkj 0/1 ContainerCreating 0 1s pc-deploy-6d547d6945-k5dpk 0/1 ContainerCreating 0 2s pc-deploy-6d547d6945-k5dpk 1/1 Running 0 28s pc-deploy-6d547d6945-7nmfx 1/1 Running 0 30s pc-deploy-6d547d6945-pnnkj 1/1 Running 0 32s [root@K8s-master ~]# kubectl get deployments.apps pc-deploy -n test -o wide #版本为1.11.4 NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 3/3 3 3 22m nginx nginx:1.11.4 app=nginx-pod
1.4.5.2 滚动更新(RollingUpdate)
[root@K8s-master ~]# vim pc-deployment.yaml spec: strategy: type: RollingUpdate rollingUpdate: maxSurge: 25% maxUnavailable: 25% [root@K8s-master ~]# kubectl apply -f pc-deployment.yaml deployment.apps/pc-deploy configured [root@K8s-master ~]# kubectl set image deploy pc-deploy nginx=nginx:1.11.5 -n test deployment.apps/pc-deploy image updated [root@K8s-master ~]# kubectl get pods -n test -w NAME READY STATUS RESTARTS AGE pc-deploy-58f96bbff4-22bfx 1/1 Running 0 8s pc-deploy-58f96bbff4-4hktp 1/1 Running 0 8s pc-deploy-58f96bbff4-7g4qm 1/1 Running 0 8s pc-deploy-58f96bbff4-jvwdg 1/1 Running 0 8s pc-deploy-58f96bbff4-n4jd9 1/1 Running 0 8s pc-deploy-58f96bbff4-ndfh6 1/1 Running 0 8s pc-deploy-58f96bbff4-qgm7s 1/1 Running 0 8s pc-deploy-58f96bbff4-x2drb 1/1 Running 0 8s pc-deploy-5f67d695c4-qq8pj 0/1 Pending 0 1s pc-deploy-5f67d695c4-qq8pj 0/1 Pending 0 1s pc-deploy-5f67d695c4-z95kp 0/1 Pending 0 0s pc-deploy-5f67d695c4-z95kp 0/1 Pending 0 0s pc-deploy-58f96bbff4-x2drb 1/1 Terminating 0 16s pc-deploy-58f96bbff4-7g4qm 1/1 Terminating 0 16s pc-deploy-5f67d695c4-7tjrl 0/1 Pending 0 0s pc-deploy-5f67d695c4-qq8pj 0/1 ContainerCreating 0 1s pc-deploy-5f67d695c4-7tjrl 0/1 Pending 0 0s pc-deploy-5f67d695c4-fgtfm 0/1 Pending 0 0s pc-deploy-5f67d695c4-fgtfm 0/1 Pending 0 0s pc-deploy-5f67d695c4-z95kp 0/1 ContainerCreating 0 0s pc-deploy-5f67d695c4-7tjrl 0/1 ContainerCreating 0 0s pc-deploy-5f67d695c4-fgtfm 0/1 ContainerCreating 0 0s ... # 至此,新版本的pod创建完毕,就版本的pod销毁完毕 # 中间过程是滚动进行的,也就是边销毁边创建 [root@K8s-master ~]# kubectl get deployments.apps -n test -o wide #全部更新 NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 8/8 8 8 3m17s nginx nginx:1.11.5 app=nginx-pod
-
滚动更新过程
# 查看rs,发现原来的rs的依旧存在,只是pod数量变为了0,而后又新产生了一个rs,pod数量为4 # 其实这就是deployment能够进行版本回退的奥妙所在,后面会详细解释 [root@K8s-master ~]# kubectl get rs -n test NAME DESIRED CURRENT READY AGE pc-deploy-58f96bbff4 0 0 0 15m pc-deploy-5f67d695c4 8 8 8 15m
1.4.5.3 版本回退
-
deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能
-
kubectl rollout: 版本升级相关功能,支持下面的选项:
-
status 显示当前升级状态
-
history 显示 升级历史记录
-
pause 暂停版本升级过程
-
resume 继续已经暂停的版本升级过程
-
restart 重启版本升级过程
-
undo 回滚到上一级版本(可以使用--to-revision回滚到指定版本)
-
-
查看当前升级版本的状态
[root@K8s-master ~]# kubectl rollout status deployment pc-deploy -n test deployment "pc-deploy" successfully rolled out
-
查看升级历史记录
[root@K8s-master ~]# kubectl set image deploy pc-deploy nginx=nginx:1.11.5 -n test deployment.apps/pc-deploy image updated [root@K8s-master ~]# kubectl set image deploy pc-deploy nginx=nginx:1.11.6 -n test deployment.apps/pc-deploy image updated [root@K8s-master ~]# kubectl rollout history deploy pc-deploy -n test deployment.apps/pc-deploy REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> # 可以发现有三次版本记录,说明完成过两次升级
-
版本回退
# 这里直接使用--to-revision=1回滚到了1版本, 如果省略这个选项,就是回退到上个版本,就是2版本 [root@K8s-master ~]# kubectl rollout undo deployment pc-deploy --to-revision=1 -n test deployment.apps/pc-deploy rolled back [root@K8s-master ~]# kubectl get deployments.apps pc-deploy -n test -o wide # 版本为nginx:1.11.1 NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deploy 3/3 2 3 6m48s nginx nginx:1.11.1 app=nginx-pod
-
查看rs
[root@K8s-master ~]# kubectl get rs -n test NAME DESIRED CURRENT READY AGE pc-deploy-58f96bbff4 3 3 3 7m34s pc-deploy-5f67d695c4 0 0 0 5m45s pc-deploy-6ff4547c4c 0 0 0 5m40s # 查看rs,发现第一个rs中有3个pod运行,后面两个版本的rs中pod为运行 # 其实deployment之所以可是实现版本的回滚,就是通过记录下历史rs来实现的, # 一旦想回滚到哪个版本,只需要将当前版本pod数量降为0,然后将回滚版本的pod提升为目标数量就可以了
1.4.5.4 金丝雀发布
-
金丝雀发布(Canary Release)是一种渐进式的部署策略,用于逐步将新版本的应用程序或服务部署到生产环境中。这种方法允许开发者在全面推广之前,先在一小部分用户或服务器上测试新版本,以确保新版本在实际使用中的表现符合预期。
-
金丝雀发布的关键步骤包括:
-
准备新版本:开发并测试新版本的应用程序。
-
部署新版本:将新版本的应用程序部署到生产环境,但只对一小部分用户或服务器可见。
-
监控和测试:密切监控新版本的性能和用户反馈,确保它按预期工作。
-
逐步扩展:如果新版本表现良好,逐步增加访问新版本的用户比例,直到完全替换旧版本。
-
回滚:如果在测试过程中发现问题,可以立即回滚到旧版本,以避免影响所有用户。
-
-
在Kubernetes环境中,金丝雀发布可以通过Deployment控制器来实现。Deployment控制器允许你定义应用的期望状态,包括应用的版本和运行的副本数量。通过使用Deployment,你可以控制更新过程,包括暂停和恢复更新,以及设置滚动更新的策略。
-
例如,你可以创建一个新的Deployment来部署新版本的Pod,然后使用Kubernetes的服务(如Service或Ingress)将一部分流量路由到新版本的Pod上。如果一切顺利,你可以继续更新,逐步增加新版本Pod的数量,直到完全替换旧版本。如果出现问题,可以暂停更新,甚至回滚到旧版本。
-
金丝雀发布是一种有效的风险管理策略,可以帮助减少新版本部署可能导致的负面影响。
# 更新部署中使用的容器镜像,并立即暂停 [root@K8s-master ~]# kubectl set image deploy pc-deploy nginx=nginx:1.11.4 -n test && kubectl rollout pause deployment pc-deploy -n test deployment.apps/pc-deploy image updated deployment.apps/pc-deploy paused # 查看rs只有一个被更新 [root@K8s-master ~]# kubectl get rs -n test -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-deploy-58f96bbff4 3 3 3 2m33s nginx nginx:1.11.1 app=nginx-pod,pod-template-hash=58f96bbff4 pc-deploy-6d547d6945 1 1 1 4s nginx nginx:1.11.4 app=nginx-pod,pod-template-hash=6d547d6945 [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-deploy-58f96bbff4-mcxd6 1/1 Running 0 3m43s 10.244.2.104 k8s-node-02 <none> <none> pc-deploy-58f96bbff4-phx2s 1/1 Running 0 3m43s 10.244.2.103 k8s-node-02 <none> <none> pc-deploy-58f96bbff4-x9snq 1/1 Running 0 3m43s 10.244.2.105 k8s-node-02 <none> <none> pc-deploy-6d547d6945-bphm9 1/1 Running 0 74s 10.244.2.106 k8s-node-02 <none> <none> #继续更新 [root@K8s-master ~]# kubectl rollout resume deploy pc-deploy -n test deployment.apps/pc-deploy resumed [root@K8s-master ~]# kubectl get rs -n test -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-deploy-58f96bbff4 0 0 0 4m49s nginx nginx:1.11.1 app=nginx-pod,pod-template-hash=58f96bbff4 pc-deploy-6d547d6945 3 3 3 2m20s nginx nginx:1.11.4 app=nginx-pod,pod-template-hash=6d547d6945 [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-deploy-6d547d6945-74l6b 1/1 Running 0 8s 10.244.2.107 k8s-node-02 <none> <none> pc-deploy-6d547d6945-bphm9 1/1 Running 0 2m23s 10.244.2.106 k8s-node-02 <none> <none> pc-deploy-6d547d6945-wswks 1/1 Running 0 6s 10.244.2.108 k8s-node-02 <none> <none>
1.5 Horizontal Pod Autoscaler(HPA)控制器
-
Horizontal Pod Autoscaler(HPA)是Kubernetes中用于自动根据当前的负载情况,自动调整Pod数量的一种控制器。HPA能够根据CPU使用率、内存使用量或其他选择的度量指标来自动扩展Pod的数量,以确保应用的性能。
-
HPA可以获取每个Pod利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。其实HPA与之前Deployment一样,也属于一种Kubernetes资源对象,它通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
-
HPA的工作原理如下:
-
指标收集:Kubernetes会收集Pod的度量指标,如CPU和内存的使用情况。
-
比较阈值:HPA会将这些指标与预设的阈值进行比较,这些阈值可以在HPA的配置中定义。
-
自动扩缩容:如果当前的负载超出了预设的阈值,HPA会增加Pod的数量以分散负载;如果负载低于阈值,HPA会减少Pod的数量以节省资源。
-
持续监控:HPA会持续监控Pod的负载,并根据需要调整Pod的数量。
-
1.5.1 安装Metrics Server
-
Metrics Server 是 Kubernetes 集群中的一个关键组件,用于收集和报告集群中资源的使用情况,如 CPU 和内存的使用率。这对于使用 HPA(Horizontal Pod Autoscaler)等自动化工具来管理资源至关重要。
-
选择 Metrics Server 版本:您需要选择一个与您的 Kubernetes 版本兼容的 Metrics Server 版本。以下是一些版本的兼容性信息43:
Metrics Server 版本 Metrics API group/version 支持的 Kubernetes 版本 0.6.x metrics.k8s.io/v1beta1 1.19+ 0.5.x metrics.k8s.io/v1beta1 *1.8+ 0.4.x metrics.k8s.io/v1beta1 *1.8+ 0.3.x metrics.k8s.io/v1beta1 1.8-1.21 注意:
*1.8+
表示支持 1.8 及之后的所有版本。
[root@K8s-master ~]# wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml [root@K8s-master ~]# sed -i 's#registry.k8s.io/metrics-server#registry.cn-hangzhou.aliyuncs.com/google_containers#g' metrics-server-components.yaml [root@K8s-master ~]# vim metrics-server-components.yaml # 添加以下内容 - --kubelet-insecure-tls
[root@K8s-master ~]# kubectl apply -f metrics-server-components.yaml [root@K8s-master ~]# kubectl get pod -n kube-system | grep metrics-server metrics-server-5c4b54658-kp8d9 1/1 Running 0 47s
-
查看Pod资源占用情况
[root@K8s-master ~]# kubectl top pod -n kube-system NAME CPU(cores) MEMORY(bytes) coredns-74586cf9b6-96v5x 2m 17Mi coredns-74586cf9b6-f5q7h 2m 20Mi etcd-k8s-master 11m 55Mi kube-apiserver-k8s-master 32m 369Mi kube-controller-manager-k8s-master 16m 64Mi kube-flannel-ds-6gqmv 2m 17Mi kube-flannel-ds-g7zcj 2m 18Mi kube-flannel-ds-hh52b 3m 17Mi kube-proxy-glhml 1m 19Mi kube-proxy-klcs2 1m 19Mi kube-proxy-x9v8k 1m 16Mi kube-scheduler-k8s-master 3m 25Mi metrics-server-5c4b54658-kp8d9 3m 21Mi
1.5.2 HPA API对象
-
HPA的API有四个版本
[root@K8s-master ~]# kubectl api-versions | grep autoscal autoscaling/v1 autoscaling/v2 autoscaling/v2beta1 autoscaling/v2beta2
HPA API 版本 | 支持的度量指标类型 | 描述 |
---|---|---|
autoscaling/v1 | CPU Metrics | 这是最初的 HPA API 版本,仅支持基于 CPU 使用率的自动缩放。 |
autoscaling/v2beta1 | Resource Metrics (如 CPU、内存) 和 Custom Metrics | 这个版本在 v1 的基础上增加了对资源指标(如内存使用率)和自定义指标的支持。自定义指标可以是来自应用程序的任何度量,由用户定义。 |
autoscaling/v2beta2 | Resource Metrics (如 CPU、内存)、Custom Metrics 和 External Metrics | v2beta2 版本进一步扩展了 v2beta1,增加了对外部指标(External Metrics)的支持。外部指标是那些来自集群外部的度量,例如来自云服务提供商的度量或者来自第三方服务的度量。 |
autoscaling/v2 | Resource Metrics (如 CPU、内存)、Custom Metrics 和 External Metrics | 这是 HPA 的稳定版本,包含了 v2beta2 中的所有特性,并进行了进一步的稳定和完善。推荐在生产环境中使用此版本以获得最佳的稳定性和特性支持。 |
-
autoscaling/v2
版本是 Kubernetes 社区经过测试和验证后的稳定版本,适合用于生产环境。它支持所有之前 beta 版本中引入的度量指标类型,包括资源指标、自定义指标和外部指标,为开发者提供了全面而灵活的自动缩放能力。
1.5.3 kubectl对HPA的支持
-
创建 HPA 对象: 使用
kubectl create
命令可以创建一个新的 HPA 对象。这需要一个配置文件,其中定义了要进行自动缩放的资源(如 Deployment 或 ReplicaSet)以及缩放的参数,如最小和最大 Pod 数量以及目标 CPU 使用率。 -
获取 HPA 对象: 使用
kubectl get hpa
命令可以获取集群中所有的 HPA 对象的列表。这可以帮助用户了解当前配置的自动缩放规则。 -
查看 HPA 对象详细信息: 使用
kubectl describe hpa
命令可以查看特定 HPA 对象的详细信息,包括当前的状态、配置的指标和历史缩放决策。 -
删除 HPA 对象: 使用
kubectl delete hpa
命令可以删除一个 HPA 对象,停止对指定资源的自动缩放。 -
简便创建 HPA 对象: 除了标准的创建命令外,
kubectl
提供了kubectl autoscale
命令来简便地创建 HPA 对象。这个命令允许用户直接在命令行中指定关键参数,而不需要准备一个完整的配置文件。
-
例如,下面的命令为名为
foo
的 ReplicaSet 创建了一个 HPA 对象,设置了最小 2 个副本、最大 5 个副本,并将目标 CPU 使用率设置为 80%:
$ kubectl autoscale rs foo --min=2 --max=5 --cpu-percent=80
示例参考:https://blog.51cto.com/u_13760351/2869347
1.5.4 准备deployment和servie
-
创建deployment
[root@K8s-master ~]# vim pod.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: test spec: selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.11.1 resources: requests: memory: "100Mi" cpu: "1" [root@K8s-master ~]# kubectl apply -f pod.yaml deployment.apps/nginx created [root@K8s-master ~]# kubectl get pod -n test NAME READY STATUS RESTARTS AGE nginx-7cc8c9585d-sqfdz 1/1 Running 0 2m1s
-
创建service
[root@K8s-master ~]# kubectl expose deployment nginx --type=NodePort --port=80 -n test service/nginx exposed [root@K8s-master ~]# kubectl get deployments.apps,svc,pod -n test NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 3m51s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx NodePort 10.108.6.6 <none> 80:31690/TCP 33s NAME READY STATUS RESTARTS AGE pod/nginx-7cc8c9585d-sqfdz 1/1 Running 0 3m51s
1.5.5 部署HPA
[root@K8s-master ~]# vim pc-hpa.yaml --- apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: pc-hpa namespace: test spec: minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 3 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx [root@K8s-master ~]# kubectl apply -f pc-hpa.yaml horizontalpodautoscaler.autoscaling/pc-hpa created [root@K8s-master ~]# kubectl get horizontalpodautoscalers.autoscaling -n test NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE pc-hpa Deployment/nginx 0%/3% 1 10 1 18s
1.5.6 压力测试
-
使用压测工具对service地址
192.168.110.21:31690
进行压测,然后通过控制台查看hpa和pod的变化
# 使用ab压力测试: 语法格式: ab [OPTIONS] URL 常用参数: -n:总请求数 -c:模拟的并行数 -k:以持久连接模式测试 [root@K8s-master ~]# yum install httpd-tools -y [root@K8s-master ~]# ab -c 1000 -n 300000 http://192.168.110.21:31690/
-
hpa变化
[root@K8s-master ~]# kubectl get hpa -n test -w NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE pc-hpa Deployment/nginx 0%/3% 1 10 1 3m49s pc-hpa Deployment/nginx 37%/3% 1 10 1 4m45s pc-hpa Deployment/nginx 82%/3% 1 10 4 5m pc-hpa Deployment/nginx 0%/3% 1 10 8 5m15s pc-hpa Deployment/nginx 0%/3% 1 10 10 5m30s
-
deployment变化
[root@K8s-master ~]# kubectl get deployment -n test -w NAME READY UP-TO-DATE AVAILABLE AGE nginx 4/8 8 4 3h15m nginx 4/10 8 4 3h15m nginx 4/10 8 4 3h15m nginx 4/10 8 4 3h15m nginx 4/10 10 4 3h15m nginx 5/10 10 5 3h15m nginx 6/10 10 6 3h16m nginx 7/10 10 7 3h16m nginx 8/10 10 8 3h16m nginx 9/10 10 9 3h16m nginx 10/10 10 10 3h16m
-
pod变化
[root@K8s-master ~]# kubectl get pod -n test -w NAME READY STATUS RESTARTS AGE nginx-7cc8c9585d-62d94 0/1 ContainerCreating 0 54s nginx-7cc8c9585d-7vbhl 0/1 ContainerCreating 0 39s nginx-7cc8c9585d-8lczq 0/1 ContainerCreating 0 39s nginx-7cc8c9585d-f9ksd 1/1 Running 0 39s nginx-7cc8c9585d-fl5gb 1/1 Running 0 24s nginx-7cc8c9585d-fn2gg 1/1 Running 0 39s nginx-7cc8c9585d-fv6jj 0/1 ContainerCreating 0 54s nginx-7cc8c9585d-qn9ls 1/1 Running 0 54s nginx-7cc8c9585d-sqfdz 1/1 Running 0 3h16m nginx-7cc8c9585d-zxp4n 0/1 ContainerCreating 0 24s nginx-7cc8c9585d-fv6jj 1/1 Running 0 64s nginx-7cc8c9585d-62d94 1/1 Running 0 66s nginx-7cc8c9585d-7vbhl 1/1 Running 0 53s nginx-7cc8c9585d-8lczq 1/1 Running 0 56s nginx-7cc8c9585d-zxp4n 1/1 Running 0 43s
1.6 DaemonSet(DS)控制器
-
DaemonSet类型的控制器可以保证在集群中的每一台(或指定)节点上都运行一个副本。一般适用于日志收集、节点监控等场景。也就是说,如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建。
DaemonSet 控制器的主要特点包括:
-
自动部署:在集群的所有节点上自动部署 Pod 的副本。
-
动态适应:当向集群添加新节点时,DaemonSet 会自动在新节点上创建 Pod 的副本。
-
自动清理:当节点从集群中移除时,其上的 Pod 也会被自动回收。
-
节点选择性:允许通过标签选择器指定 Pod 应该运行在哪些节点上。
-
更新管理:支持对所有 Pod 进行统一更新,并能在必要时回滚到之前的版本。
-
容忍污点:可以配置 Pod 以容忍节点上的污点,从而在即将被标记为不可调度的节点上运行。
-
服务发现:DaemonSet 管理的 Pod 可以通过 Kubernetes 服务发现机制被其他组件发现。
1.6.1 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.11.1 ports: - containerPort: 80
1.6.2 创建daemonset
[root@K8s-master ~]# vim pc-daemonset.yaml --- apiVersion: apps/v1 kind: DaemonSet metadata: name: pc-daemonset namespace: test spec: selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.11.1 [root@K8s-master ~]# kubectl apply -f pc-daemonset.yaml daemonset.apps/pc-daemonset created [root@K8s-master ~]# kubectl get ds -n test -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR pc-daemonset 2 2 2 2 2 <none> 21s nginx nginx:1.11.1 app=nginx-pod [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-7cc8c9585d-sqfdz 1/1 Running 0 3h36m 10.244.2.3 k8s-node-02 <none> <none> pc-daemonset-7whgg 1/1 Running 0 34s 10.244.1.9 k8s-node-01 <none> <none> pc-daemonset-zl8m5 1/1 Running 0 34s 10.244.2.8 k8s-node-02 <none> <none>
1.7 Job控制器
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务。
-
一次性任务:Job 用于运行那些只需要执行一次的任务,如数据分析、图像渲染或批量处理。
-
成功终止:Job 会跟踪其创建的 Pod 的成功完成(成功退出,退出状态为 0)的数量。
-
指定完成数量:Job 有一个目标完成数量,当成功结束的 Pod 数量达到这个指定的数量时,Job 就会完成。
-
并行处理:Job 可以配置并行性,即同时运行多个 Pod 来加速处理过程。Kubernetes 会尝试以最大并行数启动 Pod,直到达到所需的成功完成 Pod 的数量。
-
重启策略:Job 的重启策略通常设置为
OnFailure
,这意味着如果 Pod 失败(非零退出状态),它将被重启。 -
自动清理:一旦 Job 完成,即成功结束的 Pod 数量达到指定的目标,Kubernetes 将自动清理与该 Job 相关的所有资源。
-
回退机制:如果 Pod 由于某种原因(如节点故障)未能成功完成,Job 可以配置以重新创建并启动新的 Pod 来替换失败的 Pod。
-
监控和日志:Job 可以与 Kubernetes 的日志和监控系统集成,以便于跟踪作业的执行状态和历史。
1.1.1 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: counter-pod matchExpressions: # Expressions匹配规则 - key: app operator: In values: [counter-pod] template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: counter-pod spec: restartPolicy: Never # 重启策略只能设置为Never或者OnFailure containers: - name: counter image: busybox:1.30 command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 2;done"]
在 Kubernetes 中,Job
控制器的重启策略与 Pod
的重启策略是不同的。Job
本身并不控制容器的重启,而是控制着生成新 Pod
的行为。以下是 Job
控制器与重启策略相关的正确说明:
-
OnFailure:这是
Job
的默认重启策略。当Pod
由于容器故障而失败时(比如退出状态非零),Job
会认为这是一个失败,失败次数会增加,并且Job
会创建一个新的Pod
来替换失败的Pod
。这意味着任务会重试,直到成功完成。 -
Never:如果将重启策略设置为
Never
,当Pod
失败时,Job
不会创建新的Pod
来替换它,失败的Pod
将保留在系统中,并且失败次数会增加。这种策略通常用于调试,以便可以检查失败的Pod
的状态和日志。 -
Always:这个选项对于
Pod
的重启策略是有意义的,但对于Job
控制器来说,并不适用。Job
控制器不负责重启容器,它负责的是生成新的Pod
。如果Pod
的重启策略设置为Always
,无论何时容器退出,Kubernetes 都会重启该容器,而与Job
控制器无关。
1.1.2 创建Job控制器
[root@K8s-master ~]# vim pc-job.yaml --- apiVersion: batch/v1 kind: Job metadata: name: pc-job namespace: test spec: manualSelector: true selector: matchLabels: app: counter-pod # 确保这个与 template 中的 labels 匹配 template: metadata: labels: app: counter-pod # 这里的 labels 需要与 selector 的 matchLabels 对应 spec: restartPolicy: Never containers: - name: counter image: busybox:1.30 command: ["/bin/sh", "-c", "for i in 9 8 7 6 5 4 3 2 1; do echo $i; sleep 3; done"] [root@K8s-master ~]# kubectl apply -f pc-job.yaml job.batch/pc-job created # 查看job [root@K8s-master ~]# kubectl get job -n test -o wide -w NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR pc-job 0/1 0s counter busybox:1.30 app=counter-pod pc-job 0/1 0s 0s counter busybox:1.30 app=counter-pod pc-job 0/1 10s 10s counter busybox:1.30 app=counter-pod pc-job 0/1 38s 38s counter busybox:1.30 app=counter-pod pc-job 1/1 40s 40s counter busybox:1.30 app=counter-pod
-
监控Pod状态
[root@K8s-master ~]# kubectl get pods -n test -w NAME READY STATUS RESTARTS AGE nginx-7cc8c9585d-bwxdq 1/1 Running 0 19s pc-job-nr266 0/1 Pending 0 0s pc-job-nr266 0/1 Pending 0 0s pc-job-nr266 0/1 ContainerCreating 0 0s pc-job-nr266 1/1 Running 0 9s pc-job-nr266 0/1 Completed 0 37s pc-job-nr266 0/1 Completed 0 39s # 通过观察pod状态可以看到,pod在运行完毕任务后,就会变成Completed状态
1.8 CronJob(CJ)控制器
CronJob
控制器是 Kubernetes 中用于周期性执行任务的一种控制器,它基于 Job
控制器来创建和管理作业。以下是 CronJob
的一些关键特点:
-
周期性调度:
CronJob
允许您定义一个基于时间的调度,类似于 Linux 的cron
工具,来周期性地执行任务。 -
时间点触发:
CronJob
根据指定的时间表(cron 表达式)触发,可以精确到分钟。 -
一次性或重复执行:尽管
CronJob
主要用于重复性任务,但它也可以配置为仅执行一次。 -
立即执行:如果需要,可以在创建
CronJob
之后立即启动第一个作业。 -
并行性控制:可以设置
CronJob
的并行性策略,决定是否允许多个 Job 实例并行运行,或者在新实例启动前完成上一个实例。 -
成功和失败处理:
CronJob
可以配置成功和失败的工作节(job history limit)限制,以控制保留成功和失败的 Job 记录的数量。 -
暂停和恢复:
CronJob
支持暂停和恢复功能,允许您临时停止或恢复周期性任务的执行。 -
时区处理:
CronJob
允许您指定时区,以确保任务在特定地理区域的特定时间执行。 -
灵活的 cron 表达式:支持复杂的 cron 表达式,以满足不同的时间调度需求。
1.8.1 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的定义 spec: completions: 1 parallelism: 1 activeDeadlineSeconds: 30 backoffLimit: 6 manualSelector: true template: metadata: labels: app: counter-pod spec: restartPolicy: Never containers: - name: counter image: busybox:1.30 command: ["bin/sh", "-c", "for i in 9 8 7 6 5 4 3 2 1; do echo $i; sleep 20; done"]
1.8.2 schedule
schedule
是一个 cron 表达式,用于定义 CronJob
的执行计划。cron 表达式由五个字段组成,分别表示分钟、小时、日期(一个月中的哪一天)、月份和星期几。每个字段可以包含以下几种类型的值:
-
具体值:例如
1
或15
。 -
逗号分隔的多个值:例如
1,15
表示第 1 分钟和第 15 分钟。 -
范围:使用连字符
-
表示,例如1-3
表示从第 1 分钟到第 3 分钟。 -
通配符:使用星号
*
表示匹配任意值。 -
步长:使用斜杠
/
表示,例如*/15
表示从 0 开始每 15 分钟。
cron 表达式的字段含义如下:
-
分钟:0 到 59
-
小时:0 到 23
-
日期:1 到 31
-
月份:1 到 12 或 JAN 到 DEC
-
星期:0 到 6(0 表示星期天)或 SUN 到 SAT
1.8.3 concurrencyPolicy
concurrencyPolicy
定义了 CronJob
在处理并发运行的 Jobs 时的策略。它可以取以下三个值:
-
Allow:默认策略,允许多个
Job
并发运行。 -
Forbid:如果上一个
Job
尚未完成,下一个Job
将被跳过。只有当当前没有Job
在运行时,新的Job
才会启动。 -
Replace:如果当前有
Job
在运行,新的Job
将终止当前运行的Job
并取而代之。
1.8.4 创建conJob控制器
[root@K8s-master ~]# vim pc-cronjob.yaml --- apiVersion: batch/v1 kind: CronJob metadata: name: pc-cronjob namespace: test spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: restartPolicy: Never containers: - name: counter image: busybox:1.30 command: ["bin/sh", "-c", "for i in 9 8 7 6 5 4 3 2 1; do echo $i; sleep 3; done"] [root@K8s-master ~]# kubectl apply -f pc-cronjob.yaml cronjob.batch/pc-cronjob created
-
查看
[root@K8s-master ~]# kubectl get cronjobs -n test NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE pc-cronjob */1 * * * * False 0 <none> 15s [root@K8s-master ~]# kubectl get pod -n test NAME READY STATUS RESTARTS AGE nginx-7cc8c9585d-bwxdq 1/1 Running 0 15m pc-cronjob-28593115-kxx5t 0/1 Completed 0 28s [root@K8s-master ~]# kubectl get job -n test NAME COMPLETIONS DURATION AGE pc-cronjob-28593115 1/1 31s 39s
1.9 StatefulSet (有状态) 控制器
1.9.1 无状态应用(Stateless Applications)
-
相同性:所有的 Pod 都是相同的,没有区别。
-
无顺序:Pod 之间没有顺序或排名的要求。
-
位置无关:Pod 可以在任何节点上运行,位置不关键。
-
伸缩性:Pod 可以自由地创建、销毁或重新创建,通常由 Deployment 或 ReplicaSet 控制器管理。
1.9.2 有状态应用(Stateful Applications)
-
顺序和唯一性:每个 Pod 都需要是唯一的,并且有一个确定的顺序或索引与之相关联。
-
位置感知:Pod 的位置(即它运行在哪个节点上)可能很重要,特别是对于需要持久化存储的应用。
-
有序伸缩:Pod 的创建、销毁和替换需要按照特定的顺序进行。
-
持久性:每个 Pod 需要保持其身份,即使在重新调度后也要保持其名称和顺序。
1.9.3 StatefulSet 控制器
-
有状态管理:StatefulSet 是 Kubernetes 中用于管理有状态应用的控制器。
-
顺序和索引:为每个 Pod 提供了一个稳定的网络标识符和顺序索引。
-
存储:通常与持久化存储一起使用,以保证数据的持久性。
-
唯一性:每个 Pod 都有一个与之对应的持久名称和唯一标识符。
1.9.4 Headless Service
-
服务发现:Headless Service(无头服务)为 StatefulSet 中的每个 Pod 提供了稳定的 DNS 名称和域名。
-
无需负载均衡器:Headless Service 不需要 Kubernetes 创建一个外部的负载均衡器。
-
稳定的网络标识:每个 Pod 通过 Headless Service 获得一个稳定的 DNS 名称,即使 Pod 重新调度后,其名称也保持不变。
-
顺序性:Pod 的 DNS 名称反映了其顺序索引,这对于需要顺序的有状态应用来说是必要的。
Headless Service 的使用允许 StatefulSet 中的 Pods 通过 DNS 名称相互发现,并且这些名称是可预测和顺序的,这对于运行有状态服务(如分布式数据库或消息队列)至关重要。
1.9.5 StatefulSet 常见应用场景
-
消息队列:如 RabbitMQ。
-
协调服务:如 Zookeeper。
-
数据库:如 MySQL、Cassandra、MongoDB。
-
服务注册中心:如 Eureka。
1.9.6 创建StatefulSet
[root@K8s-master ~]# vim pc-stateful.yaml --- apiVersion: v1 kind: Service metadata: name: service-headlessness namespace: test spec: selector: app: nginx-pod clusterIP: None # 设置为 None 以创建 Headless Service ports: - port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: pc-statefulset namespace: test spec: replicas: 3 serviceName: service-headlessness selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.11.1 ports: - containerPort: 80 [root@K8s-master ~]# kubectl apply -f pc-stateful.yaml service/service-headlessness created statefulset.apps/pc-statefulset unchanged
-
查看
[root@K8s-master ~]# kubectl get statefulsets.apps pc-statefulset -n test -o wide # 查看StatefulSet NAME READY AGE CONTAINERS IMAGES pc-statefulset 3/3 112s nginx nginx:1.11.1 [root@K8s-master ~]# kubectl get pod -n test -o wide | grep pc-stateful pc-statefulset-0 1/1 Running 0 3m20s 10.244.2.128 k8s-node-02 <none> <none> pc-statefulset-1 1/1 Running 0 3m19s 10.244.2.129 k8s-node-02 <none> <none> pc-statefulset-2 1/1 Running 0 3m18s 10.244.1.13 k8s-node-01 <none> <none>
1.9.7 Deployment和StatefulSet的区别
-
Deployment和StatefulSet的区别:Deployment没有唯一标识而StatefulSet有唯一标识。
-
StatefulSet的唯一标识是根据主机名+一定规则生成的。
-
StatefulSet的唯一标识是主机名.无头Service名称.命名空间.svc.cluster.local。
1.10 状态与无状态化对特点
1.10.1 无状态服务 (Stateless Services) 的特点:
-
相同性:所有 Pod 都是相同的,没有任何区别或身份。
-
无顺序:Pod 之间没有特定的顺序或依赖关系。
-
位置无关性:Pod 可以在任何节点上运行,其功能不会受到影响。
-
伸缩性:Pod 可以自由地根据需要进行扩容(增加实例)和缩容(减少实例)。
-
易于扩展:由于 Pod 之间没有区别,可以简单地通过增加或减少 Pod 数量来扩展或缩减服务。
1.10.2 有状态服务 (Stateful Services) 的特点:
-
实例唯一性:每个实例都有其独特性,可能包括不同的配置、状态或元数据。
-
顺序重要性:实例之间可能存在顺序或依赖关系,例如在分布式数据库中。
-
位置感知:Pod 运行的位置可能对其功能有影响,尤其是在使用持久化存储时。
-
不对等的关系:实例之间可能存在领导者和跟随者的关系,或者需要按照特定的顺序进行操作。
-
外部存储依赖:有状态服务可能依赖于外部存储系统来维持状态,如数据库或分布式存储。
1.10.2 StatefulSet 的金丝雀发布:
StatefulSet 支持金丝雀发布,这是一种逐步推出新版本服务的策略,以减少更新带来的风险。StatefulSet 的更新策略包括:
-
OnDelete:在这种策略下,StatefulSet 不会自动更新 Pods。只有当您手动删除 Pod 时,StatefulSet 才会创建一个新的 Pod 来替换它。这种策略允许您手动控制更新过程。
-
RollingUpdate(默认):这是 StatefulSet 的默认更新策略。在这种策略下,StatefulSet 会逐个更新 Pods,通常从序号最高的 Pod 开始,以确保每个 Pod 都有一个唯一的索引。这种滚动更新可以减少服务中断的风险,因为它允许逐步替换实例,而不是同时替换所有实例。
updateStrategy: type: RollingUpdate # 指定更新策略为 RollingUpdate rollingUpdate: # RollingUpdate 策略的配置 partition: 2 # 从序号为 2 的 Pod 开始更新