Pod控制器相关知识

控制器的必要性

自主式Pod对象由调度器调度到目标工作节点后即由相应节点上的kubelet负责监控其容器的存活状态,容器主进程崩溃后,kubelet能够自动重启相应的容器。但对出现非主进程崩溃类的容器错误却无从感知,这便依赖于pod资源对象定义的存活探测,以便kubelet能够探知到此类故障。但若pod被删除或者工作节点自身发生故障(工作节点上都有kubeletkubelet不可用,因此其健康状态便无法保证),则便需要控制器来处理相应的容器重启和配置。

常见的工作负载控制器

Pod控制器由masterkube-controller-manager组件提供,常见的此类控制器有:

ReplicationController

ReplicaSet:代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能

Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。

DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,常用于实现系统级**后台任务。比如ELK服务

StatefulSet:管理有状态应用

Job:只要完成就立即退出,不需要重启或重建

CronJob:周期性任务控制,不需要持续后台运行

Pod控制器概述

Kubernetes的核心功能之一还在于要确保各资源对象的当前状态(status)以匹配用户期望的状态(spec),使当前状态不断地向期望状态“和解”(reconciliation)来完成容器应用管理。而这些则是kube-controller-manager的任务。

创建为具体的控制器对象之后,每个控制器均通过API Server提供的接口持续监控相关资源对象的当前状态,并在因故障、更新或其他原因导致系统状态发生变化时,尝试让资源的当前状态想期望状态迁移和逼近。

List-Watchkubernetes实现的核心机制之一,在资源对象的状态发生变动时,由API Server负责写入etcd并通过水平触发(level-triggered)机制主动通知给相关的客户端程序以确保其不会错过任何一个事件。控制器通过API Serverwatch接口实时监控目标资源对象的变动并执行和解操作,但并不会与其他控制器进行任何交互。

Pod和Pod控制器

Pod控制器资源通过持续性地监控集群中运行着的Pod资源对象来确保受其管控的资源严格符合用户期望的状态,例如资源副本的数量要精确符合期望等。通常,一个Pod控制器资源至少应该包含三个基本的组成部分:

标签选择器:匹配并关联Pod资源对象,并据此完成受其管控的Pod资源计数。

期望的副本数:期望在集群中精确运行着的Pod资源的对象数量。

Pod模板:用于新建Pod资源对象的Pod模板资源。

ReplicaSet控制器

ReplicaSet概述

ReplicaSet是取代早期版本中的ReplicationController控制器,其功能基本上与ReplicationController相同

ReplicaSet(简称RS)是Pod控制器类型的一种实现,用于确保由其管控的Pod对象副本数在任意时刻都能精确满足期望的数量。ReplicaSet控制器资源启动后会查找集群中匹配器标签选择器的Pod资源对象,当前活动对象的数量与期望的数量不吻合时,多则删除,少则通过Pod模板创建以补足。

ReplicaSet能够实现以下功能:

  • 确保Pod资源对象的数量精确反映期望值:ReplicaSet需要确保由其控制运行的Pod副本数量精确吻合配置中定义的期望值,否则就会自动补足所缺或终止所余。

  • 确保Pod健康运行:探测到由其管控的Pod对象因其所在的工作节点故障而不可用时,自动请求由调度器于其他工作节点创建缺失的Pod副本。

  • 弹性伸缩:可通过ReplicaSet控制器动态扩容或者缩容Pod资源对象的数量。必要时还可以通过HPA控制器实现Pod资源规模的自动伸缩。

创建ReplicaSet

核心字段

spec字段一般嵌套使用以下几个属性字段:

replicas    <integer>:指定期望的Pod对象副本数量
selector <Object>:当前控制器匹配Pod对象副本的标签选择器,支持matchLabels和matchExpressions两种匹配机制
template <Object>:用于定义Pod时的Pod资源信息
minReadySeconds <integer>:用于定义Pod启动后多长时间为可用状态,默认为0秒

ReplicaSet示例

#(1)命令行查看ReplicaSet清单定义规则
[root@k8s-master ~]# kubectl explain rs
[root@k8s-master ~]# kubectl explain rs.spec
[root@k8s-master ~]# kubectl explain rs.spec.template #(2)创建ReplicaSet示例
[root@k8s-master ~]# vim manfests/rs-demo.yaml
apiVersion: apps/v1 #api版本定义
kind: ReplicaSet #定义资源类型为ReplicaSet
metadata: #元数据定义
name: myapp
namespace: default
spec: #ReplicaSet的规格定义
replicas: 2 #定义副本数量为2个
selector: #标签选择器,定义匹配Pod的标签
matchLabels:
app: myapp
release: canary
template: #Pod的模板定义
metadata: #Pod的元数据定义
name: myapp-pod #自定义Pod的名称
labels: #定义Pod的标签,需要和上面的标签选择器内匹配规则中定义的标签一致,可以多出其他标签
app: myapp
release: canary
spec: #Pod的规格定义
containers: #容器定义
- name: myapp-containers #容器名称
image: ikubernetes/myapp:v1 #容器镜像
imagePullPolicy: IfNotPresent #拉取镜像的规则
ports: #暴露端口
- name: http #端口名称
containerPort: 80 #(3)创建ReplicaSet定义的Pod
[root@k8s-master ~]# kubectl apply -f manfests/rs-demo.yaml
replicaset.apps/myapp created
[root@k8s-master ~]# kubectl get rs #查看创建的ReplicaSet控制器
NAME DESIRED CURRENT READY AGE
myapp 4 4 4 3m23s
[root@k8s-master ~]# kubectl get pods #通过查看pod可以看出pod命令是规则是前面是replicaset控制器的名称加随机生成的字符串
NAME READY STATUS RESTARTS AGE
myapp-bln4v 1/1 Running 0 6s
myapp-bxpzt 1/1 Running 0 6s #(4)修改Pod的副本数量
[root@k8s-master ~]# kubectl edit rs myapp
replicas: 4
[root@k8s-master ~]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp 4 4 4 2m50s myapp-containers ikubernetes/myapp:v2 app=myapp,release=canary
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myapp-8hkcr 1/1 Running 0 2m2s app=myapp,release=canary
myapp-bln4v 1/1 Running 0 3m40s app=myapp,release=canary
myapp-bxpzt 1/1 Running 0 3m40s app=myapp,release=canary
myapp-ql2wk 1/1 Running 0 2m2s app=myapp,release=canary

更新ReplicaSet控制器

修改Pod模板:升级应用

修改上面创建的replicaset示例文件,将镜像ikubernetes/myapp:v1改为v2版本

[root@k8s-master ~]# vim manfests/rs-demo.yaml
spec: #Pod的规格定义
containers: #容器定义
- name: myapp-containers #容器名称
image: ikubernetes/myapp:v2 #容器镜像
imagePullPolicy: IfNotPresent #拉取镜像的规则
ports: #暴露端口
- name: http #端口名称
containerPort: 80
[root@k8s-master ~]# kubectl apply -f manfests/rs-demo.yaml #执行apply让其重载
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
Name Image
myapp-bln4v ikubernetes/myapp:v1
myapp-bxpzt ikubernetes/myapp:v1 #说明:这里虽然重载了,但是已有的pod所使用的镜像仍然是v1版本的,只是新建pod时才会使用v2版本,这里测试先手动删除已有的pod。
[root@k8s-master ~]# kubectl delete pods -l app=myapp #删除标签app=myapp的pod资源
pod "myapp-bln4v" deleted
pod "myapp-bxpzt" deleted
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image #再次查看通过ReplicaSet新建的pod资源对象。镜像已使用v2版本
Name Image
myapp-mdn8j ikubernetes/myapp:v2
myapp-v5bgr ikubernetes/myapp:v2

扩容和缩容

可以直接通过vim 编辑清单文件修改replicas字段,也可以通过kubect edit 命令去编辑。kubectl还提供了一个专用的子命令scale用于实现应用规模的伸缩,支持从资源清单文件中获取新的目标副本数量,也可以直接在命令行通过“--replicas”选项进行读取。

[root@k8s-master ~]# kubectl get rs    #查看ReplicaSet
NAME DESIRED CURRENT READY AGE
myapp 2 2 2 154m
[root@k8s-master ~]# kubectl get pods #查看Pod
NAME READY STATUS RESTARTS AGE
myapp-mdn8j 1/1 Running 0 5m26s
myapp-v5bgr 1/1 Running 0 5m26s #扩容
[root@k8s-master ~]# kubectl scale replicasets myapp --replicas=5 #将上面的Deployments控制器myapp的Pod副本数量提升为5个
replicaset.extensions/myapp scaled
[root@k8s-master ~]# kubectl get rs #查看ReplicaSet
NAME DESIRED CURRENT READY AGE
myapp 5 5 5 156m
[root@k8s-master ~]# kubectl get pods #查看Pod
NAME READY STATUS RESTARTS AGE
myapp-lrrp8 1/1 Running 0 8s
myapp-mbqf8 1/1 Running 0 8s
myapp-mdn8j 1/1 Running 0 6m48s
myapp-ttmf5 1/1 Running 0 8s
myapp-v5bgr 1/1 Running 0 6m48s #收缩
[root@k8s-master ~]# kubectl scale replicasets myapp --replicas=3
replicaset.extensions/myapp scaled
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp 3 3 3 159m
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-mdn8j 1/1 Running 0 10m
myapp-ttmf5 1/1 Running 0 3m48s
myapp-v5bgr 1/1 Running 0 10m

删除ReplicaSet控制器资源

使用Kubectl delete命令删除ReplicaSet对象时默认会一并删除其管控的各Pod对象,有时,考虑到这些Pod资源未必由其创建,或者即便由其创建也并非自身的组成部分,这时候可以添加“--cascade=false”选项,取消级联关系。

[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp 3 3 3 162m
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-mdn8j 1/1 Running 0 12m
myapp-ttmf5 1/1 Running 0 6m18s
myapp-v5bgr 1/1 Running 0 12m
[root@k8s-master ~]# kubectl delete replicasets myapp --cascade=false
replicaset.extensions "myapp" deleted
[root@k8s-master ~]# kubectl get rs
No resources found.
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-mdn8j 1/1 Running 0 13m
myapp-ttmf5 1/1 Running 0 7m
myapp-v5bgr 1/1 Running 0 13m #通过上面的示例可以看出,添加--cascade=false参数后再删除ReplicaSet资源对象时并没有将其管控的Pod资源对象一并删除。

Deployment控制器

Deployment概述

Deployment(简写为deploy)是kubernetes控制器的又一种实现,它构建于ReplicaSet控制器之上,可为PodReplicaSet资源提供声明式更新。

Deployment控制器资源的主要职责是为了保证Pod资源的健康运行,其大部分功能均可通过调用ReplicaSet实现,同时还增添部分特性。

  • 事件和状态查看:必要时可以查看Deployment对象升级的详细进度和状态。

  • 回滚:升级操作完成后发现问题时,支持使用回滚机制将应用返回到前一个或由用户指定的历史记录中的版本上。

  • 版本记录:对Deployment对象的每一个操作都予以保存,以供后续可能执行的回滚操作使用。

  • 暂停和启动:对于每一次升级,都能够随时暂停和启动。

  • 多种自动更新方案:一是Recreate,即重建更新机制,全面停止、删除旧有的Pod后用新版本替代;另一个是RollingUpdate,即滚动升级机制,逐步替换旧有的Pod至新的版本。

创建Deployment

Deployment其核心资源和ReplicaSet相似

#(1)命令行查看ReplicaSet清单定义规则
[root@k8s-master ~]# kubectl explain deployment
[root@k8s-master ~]# kubectl explain deployment.spec
[root@k8s-master ~]# kubectl explain deployment.spec.template #(2)创建Deployment示例
[root@k8s-master ~]# vim manfests/deploy-demo.yaml
apiVersion: apps/v1 #api版本定义
kind: Deployment #定义资源类型为Deploymant
metadata: #元数据定义
name: deploy-demo #deployment控制器名称
namespace: default #名称空间
spec: #deployment控制器的规格定义
replicas: 2 #定义副本数量为2个
selector: #标签选择器,定义匹配Pod的标签
matchLabels:
app: deploy-app
release: canary
template: #Pod的模板定义
metadata: #Pod的元数据定义
labels: #定义Pod的标签,需要和上面的标签选择器内匹配规则中定义的标签一致,可以多出其他标签
app: deploy-app
release: canary
spec: #Pod的规格定义
containers: #容器定义
- name: myapp #容器名称
image: ikubernetes/myapp:v1 #容器镜像
ports: #暴露端口
- name: http #端口名称
containerPort: 80 #(3)创建Deployment对象
[root@k8s-master ~]# kubectl apply -f manfests/deploy-demo.yaml
deployment.apps/deploy-demo created #(4)查看资源对象
[root@k8s-master ~]# kubectl get deployment #查看Deployment资源对象
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-demo 2/2 2 2 10s
[root@k8s-master ~]# kubectl get replicaset #查看ReplicaSet资源对象
NAME DESIRED CURRENT READY AGE
deploy-demo-78c84d4449 2 2 2 20s
[root@k8s-master ~]# kubectl get pods #查看Pod资源对象
NAME READY STATUS RESTARTS AGE
deploy-demo-78c84d4449-22btc 1/1 Running 0 23s
deploy-demo-78c84d4449-5fn2k 1/1 Running 0 23s
---
说明:
通过查看资源对象可以看出,Deployment会自动创建相关的ReplicaSet控制器资源,并以"[DEPLOYMENT-name]-[POD-TEMPLATE-HASH-VALUE]"格式为其命名,其中的hash值由Deployment自动生成。而Pod名则是以ReplicaSet控制器的名称为前缀,后跟5位随机字符。

更新策略

ReplicaSet控制器的应用更新需要手动分成多步并以特定的次序进行,过程繁杂且容易出错,而Deployment却只需要由用户指定在Pod模板中要改动的内容,(如镜像文件的版本),余下的步骤便会由其自动完成。Pod副本数量也是一样。

Deployment控制器支持两种更新策略:滚动更新(rollingUpdate)和重建创新(Recreate),默认为滚动更新

  • 滚动更新(rollingUpdate):即在删除一部分旧版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是升级期间,容器中应用提供的服务不会中断,但更新期间,不同客户端得到的相应内容可能会来自不同版本的应用。

  • 重新创建(Recreate):即首先删除现有的Pod对象,而后由控制器基于新模板重行创建出新版本的资源对象。

Deployment控制器的滚动更新操作并非在同一个ReplicaSet控制器对象下删除并创建Pod资源,新控制器的Pod对象数量不断增加,直到旧控制器不再拥有Pod对象,而新控制器的副本数量变得完全符合期望值为止。如图所示

滚动更新时,应用还要确保可用的Pod对象数量不低于某阀值以确保可以持续处理客户端的服务请求,变动的方式和Pod对象的数量范围将通过kubectl explain deployment.spec.strategy.rollingUpdate.maxSurgekubectl explain deployment.spec.strategy.rollingUpdate.maxUnavailable两个属性同时进行定义。其功能如下:

  • maxSurge:指定升级期间存在的总Pod对象数量最多可超出期望值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;例如,如果期望值为3,当前的属性值为1,则表示Pod对象的总数不能超过4个。

  • maxUnavailable:升级期间正常可用的Pod副本数(包括新旧版本)最多不能低于期望值的个数,其值可以是0或正整数,也可以是期望值的百分比;默认值为1,该值意味着如果期望值是3,则升级期间至少要有两个Pod对象处于正常提供服务的状态。

maxSurgemaxUnavailable属性的值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行滚动更新操作。

Deployment控制器可以保留其更新历史中的旧ReplicaSet对象版本,所保存的历史版本数量由kubectl explain deployment.spec.revisionHistoryLimit参数指定。只有保存于revision历史中的ReplicaSet版本可用于回滚。

注:为了保存版本升级的历史,需要在创建Deployment对象时于命令中使用“--record”选项。

Deployment更新升级

修改Pod模板相关的配置参数便能完成Deployment控制器资源的更新。由于是声明式配置,因此对Deployment控制器资源的修改尤其适合使用applypatch命令来进行;如果仅只是修改容器镜像,“set image”命令更为易用。

1)首先通过set image命令将上面创建的Deployment对象的镜像版本改为v2版本

#打开1个终端进行升级
[root@k8s-master ~]# kubectl set image deployment/deploy-demo myapp=ikubernetes/myapp:v2
deployment.extensions/deploy-demo image updated #同时打开终端2进行查看pod资源对象升级过程
[root@k8s-master ~]# kubectl get pods -l app=deploy-app -w
NAME READY STATUS RESTARTS AGE
deploy-demo-78c84d4449-2rvxr 1/1 Running 0 33s
deploy-demo-78c84d4449-nd7rr 1/1 Running 0 33s
deploy-demo-7c66dbf45b-7k4xz 0/1 Pending 0 0s
deploy-demo-7c66dbf45b-7k4xz 0/1 Pending 0 0s
deploy-demo-7c66dbf45b-7k4xz 0/1 ContainerCreating 0 0s
deploy-demo-7c66dbf45b-7k4xz 1/1 Running 0 2s
deploy-demo-78c84d4449-2rvxr 1/1 Terminating 0 49s
deploy-demo-7c66dbf45b-r88qr 0/1 Pending 0 0s
deploy-demo-7c66dbf45b-r88qr 0/1 Pending 0 0s
deploy-demo-7c66dbf45b-r88qr 0/1 ContainerCreating 0 0s
deploy-demo-7c66dbf45b-r88qr 1/1 Running 0 1s
deploy-demo-78c84d4449-2rvxr 0/1 Terminating 0 50s
deploy-demo-78c84d4449-nd7rr 1/1 Terminating 0 51s
deploy-demo-78c84d4449-nd7rr 0/1 Terminating 0 51s
deploy-demo-78c84d4449-nd7rr 0/1 Terminating 0 57s
deploy-demo-78c84d4449-nd7rr 0/1 Terminating 0 57s
deploy-demo-78c84d4449-2rvxr 0/1 Terminating 0 60s
deploy-demo-78c84d4449-2rvxr 0/1 Terminating 0 60s #同时打开终端3进行查看pod资源对象变更过程
[root@k8s-master ~]# kubectl get deployment deploy-demo -w
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-demo 2/2 2 2 37s
deploy-demo 2/2 2 2 47s
deploy-demo 2/2 2 2 47s
deploy-demo 2/2 0 2 47s
deploy-demo 2/2 1 2 47s
deploy-demo 3/2 1 3 49s
deploy-demo 2/2 1 2 49s
deploy-demo 2/2 2 2 49s
deploy-demo 3/2 2 3 50s
deploy-demo 2/2 2 2 51s # 升级完成再次查看rs的情况,以下可以看到原的rs作为备份,而现在启动的是新的rs
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deploy-demo-78c84d4449 0 0 0 4m41s
deploy-demo-7c66dbf45b 2 2 2 3m54s

2)Deployment扩容

#1、使用kubectl scale命令扩容
[root@k8s-master ~]# kubectl scale deployment deploy-demo --replicas=3
deployment.extensions/deploy-demo scaled
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
deploy-demo-7c66dbf45b-7k4xz 1/1 Running 0 10m
deploy-demo-7c66dbf45b-gq2tw 1/1 Running 0 3s
deploy-demo-7c66dbf45b-r88qr 1/1 Running 0 10m #2、使用直接修改配置清单方式进行扩容
[root@k8s-master ~]# vim manfests/deploy-demo.yaml
spec: #deployment控制器的规格定义
replicas: 4 #定义副本数量为2个
[root@k8s-master ~]# kubectl apply -f manfests/deploy-demo.yaml
deployment.apps/deploy-demo configured
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
deploy-demo-78c84d4449-6rmnm 1/1 Running 0 61s
deploy-demo-78c84d4449-9xfp9 1/1 Running 0 58s
deploy-demo-78c84d4449-c2m6h 1/1 Running 0 61s
deploy-demo-78c84d4449-sfxps 1/1 Running 0 57s #3、使用kubectl patch打补丁的方式进行扩容
[root@k8s-master ~]# kubectl patch deployment deploy-demo -p '{"spec":{"replicas":5}}'
deployment.extensions/deploy-demo patched
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
deploy-demo-78c84d4449-6rmnm 1/1 Running 0 3m44s
deploy-demo-78c84d4449-9xfp9 1/1 Running 0 3m41s
deploy-demo-78c84d4449-c2m6h 1/1 Running 0 3m44s
deploy-demo-78c84d4449-sfxps 1/1 Running 0 3m40s
deploy-demo-78c84d4449-t7jxb 1/1 Running 0 3s

金丝雀发布

采用先添加再删除的方式,且可用Pod资源对象总数不低于期望值的方式进行,配置如下:

1)添加其总数多余期望值一个

[root@k8s-master ~]# kubectl patch deployment deploy-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
deployment.extensions/deploy-demo patched

2)启动更新过程,在修改相应容器的镜像版本后立即暂停更新进度。

[root@k8s-master ~]# kubectl set image deployment/deploy-demo myapp=ikubernetes/myapp:v3 && kubectl rollout pause deployment deploy-demo
deployment.extensions/deploy-demo image updated
deployment.extensions/deploy-demo paused #查看
[root@k8s-master ~]# kubectl get deployment #查看deployment资源对象
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-demo 6/5 1 6 37m
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image #查看pod资源对象的name和image
Name Image
deploy-demo-6bf8dbdc9f-fjnzn ikubernetes/myapp:v3
deploy-demo-78c84d4449-6rmnm ikubernetes/myapp:v1
deploy-demo-78c84d4449-9xfp9 ikubernetes/myapp:v1
deploy-demo-78c84d4449-c2m6h ikubernetes/myapp:v1
deploy-demo-78c84d4449-sfxps ikubernetes/myapp:v1
deploy-demo-78c84d4449-t7jxb ikubernetes/myapp:v1
[root@k8s-master ~]# kubectl rollout status deployment/deploy-demo #查看更新情况
Waiting for deployment "deploy-demo" rollout to finish: 1 out of 5 new replicas have been updated...
---
#通过上面查看可以看出,当前的pod数量为6个,因为此前我们定义的期望值为5个,这里多出了一个,且这个镜像版本为v3版本。 #全部更新
[root@k8s-master ~]# kubectl rollout resume deployment deploy-demo
deployment.extensions/deploy-demo resumed
#再次查看
[root@k8s-master ~]# kubectl get deployment #查看deployment资源对象
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-demo 5/5 5 5 43m
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image #查看pod资源对象的name和image
Name Image
deploy-demo-6bf8dbdc9f-2z6gt ikubernetes/myapp:v3
deploy-demo-6bf8dbdc9f-f79q2 ikubernetes/myapp:v3
deploy-demo-6bf8dbdc9f-fjnzn ikubernetes/myapp:v3
deploy-demo-6bf8dbdc9f-pjf4z ikubernetes/myapp:v3
deploy-demo-6bf8dbdc9f-x7fnk ikubernetes/myapp:v3
[root@k8s-master ~]# kubectl rollout status deployment/deploy-demo #查看更新情况
Waiting for deployment "deploy-demo" rollout to finish: 1 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 1 out of 5 new replicas have been updated...
Waiting for deployment spec update to be observed...
Waiting for deployment spec update to be observed...
Waiting for deployment "deploy-demo" rollout to finish: 1 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 1 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "deploy-demo" rollout to finish: 1 old replicas are pending termination...
deployment "deploy-demo" successfully rolled out

回滚Deployment控制器下的应用发布

若因各种原因导致滚动更新无法正常进行,如镜像文件获取失败,等等;则应该将应用回滚到之前的版本,或者回滚到指定的历史记录中的版本。则通过kubectl rollout undo命令完成。如果回滚到指定版本则需要添加--to-revision选项

1)回到上一个版本

[root@k8s-master ~]# kubectl rollout undo deployment/deploy-demo
deployment.extensions/deploy-demo rolled back
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
Name Image
deploy-demo-78c84d4449-2xspz ikubernetes/myapp:v1
deploy-demo-78c84d4449-f8p46 ikubernetes/myapp:v1
deploy-demo-78c84d4449-mnmvc ikubernetes/myapp:v1
deploy-demo-78c84d4449-tsl7r ikubernetes/myapp:v1
deploy-demo-78c84d4449-xdt8j ikubernetes/myapp:v1

2)回滚到指定版本

#通过该命令查看更新历史记录
[root@k8s-master ~]# kubectl rollout history deployment/deploy-demo
deployment.extensions/deploy-demo
REVISION CHANGE-CAUSE
2 <none>
4 <none>
5 <none> #回滚到版本2
[root@k8s-master ~]# kubectl rollout undo deployment/deploy-demo --to-revision=2
deployment.extensions/deploy-demo rolled back
[root@k8s-master ~]# kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
Name Image
deploy-demo-7c66dbf45b-42nj4 ikubernetes/myapp:v2
deploy-demo-7c66dbf45b-8zhf5 ikubernetes/myapp:v2
deploy-demo-7c66dbf45b-bxw7x ikubernetes/myapp:v2
deploy-demo-7c66dbf45b-gmq8x ikubernetes/myapp:v2
deploy-demo-7c66dbf45b-mrfdb ikubernetes/myapp:v2

DaemonSet控制器

DaemonSet概述

DaemonSet用于在集群中的全部节点上同时运行一份指定Pod资源副本,后续新加入集群的工作节点也会自动创建一个相关的Pod对象,当从集群移除借点时,此类Pod对象也将被自动回收而无需重建。管理员也可以使用节点选择器及节点标签指定仅在具有特定特征的节点上运行指定的Pod对象。

应用场景

  • 运行集群存储的守护进程,如在各个节点上运行glusterdceph

  • 在各个节点上运行日志收集守护进程,如fluentdlogstash

  • 在各个节点上运行监控系统的代理守护进程,如Prometheus Node ExportercollectdDatadog agentNew Relic agentGanglia gmond等。

创建DaemonSet

DaemonSet控制器的spec字段中嵌套使用的相同字段selectortemplateminReadySeconds,并且功能和用法基本相同,但它不支持replicas,因为毕竟不能通过期望值来确定Pod资源的数量,而是基于节点数量。

这里使用nginx来示例,生产环境就比如使用上面提到的logstash等。

#(1) 定义清单文件
[root@k8s-master ~]# vim manfests/daemonset-demo.yaml
apiVersion: apps/v1 #api版本定义
kind: DaemonSet #定义资源类型为DaemonSet
metadata: #元数据定义
name: daemset-nginx #daemonset控制器名称
namespace: default #名称空间
labels: #设置daemonset的标签
app: daem-nginx
spec: #DaemonSet控制器的规格定义
selector: #指定匹配pod的标签
matchLabels: #指定匹配pod的标签
app: daem-nginx #注意:这里需要和template中定义的标签一样
template: #Pod的模板定义
metadata: #Pod的元数据定义
name: nginx
labels: #定义Pod的标签,需要和上面的标签选择器内匹配规则中定义的标签一致,可以多出其他标签
app: daem-nginx
spec: #Pod的规格定义
containers: #容器定义
- name: nginx-pod #容器名字
image: nginx:1.12 #容器镜像
ports: #暴露端口
- name: http #端口名称
containerPort: 80 #暴露的端口 #(2)创建上面定义的daemonset控制器
[root@k8s-master ~]# kubectl apply -f manfests/daemonset-demo.yaml
daemonset.apps/daemset-nginx created #(3)查看验证
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemset-nginx-7s474 1/1 Running 0 80s 10.244.1.61 k8s-node1 <none> <none>
daemset-nginx-kxpl2 1/1 Running 0 94s 10.244.2.58 k8s-node2 <none> <none>
[root@k8s-master ~]# kubectl describe daemonset/daemset-nginx
......
Name: daemset-nginx
Selector: app=daem-nginx
Node-Selector: <none>
......
Desired Number of Nodes Scheduled: 2
Current Number of Nodes Scheduled: 2
Number of Nodes Scheduled with Up-to-date Pods: 2
Number of Nodes Scheduled with Available Pods: 2
Number of Nodes Misscheduled: 0
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
......

通过上面验证查看,Node-Selector字段的值为空,表示它需要运行在集群中的每个节点之上。而当前的节点数是2个,所以其期望的Pod副本数(Desired Number of Nodes Scheduled)为2,而当前也已经创建了2个相关的Pod对象。

注意

对于特殊的硬件的节点来说,可能有的运行程序只需要在某一些节点上运行,那么通过Pod模板的spec字段中嵌套使用nodeSelector字段,并确保其值定义的标签选择器与部分特定工作节点的标签匹配即可。

更新DaemonSet对象

DaemonSet自Kubernetes1.6版本起也开始支持更新机制,相关配置嵌套在kubectl explain daemonset.spec.updateStrategy字段中。其支持RollingUpdate(滚动更新)和OnDelete(删除时更新)两种策略,滚动更新为默认的更新策略。
#(1)查看镜像版本
[root@k8s-master ~]# kubectl get pods -l app=daem-nginx -o custom-columns=NAME:metadata.name,NODE:spec.nodeName,Image:spec.containers[0].image
NAME NODE Image
daemset-nginx-7s474 k8s-node1 nginx:1.12
daemset-nginx-kxpl2 k8s-node2 nginx:1.12 #(2)更新
[root@k8s-master ~]# kubectl set image daemonset/daemset-nginx nginx-pod=nginx:1.14
[root@k8s-master ~]# kubectl get pods -l app=daem-nginx -o custom-columns=NAME:metadata.name,NODE:spec.nodeName,Image:spec.containers[0].image #再次查看
NAME NODE Image
daemset-nginx-74c95 k8s-node2 nginx:1.14
daemset-nginx-nz6n9 k8s-node1 nginx:1.14 #(3)查坎详细信息
[root@k8s-master ~]# kubectl describe daemonset daemset-nginx
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 49m daemonset-controller Created pod: daemset-nginx-6kzg6
Normal SuccessfulCreate 49m daemonset-controller Created pod: daemset-nginx-jjnc2
Normal SuccessfulDelete 40m daemonset-controller Deleted pod: daemset-nginx-jjnc2
Normal SuccessfulCreate 40m daemonset-controller Created pod: daemset-nginx-kxpl2
Normal SuccessfulDelete 40m daemonset-controller Deleted pod: daemset-nginx-6kzg6
Normal SuccessfulCreate 40m daemonset-controller Created pod: daemset-nginx-7s474
Normal SuccessfulDelete 15s daemonset-controller Deleted pod: daemset-nginx-7s474
Normal SuccessfulCreate 8s daemonset-controller Created pod: daemset-nginx-nz6n9
Normal SuccessfulDelete 5s daemonset-controller Deleted pod: daemset-nginx-kxpl2

通过上面查看可以看出,默认的滚动更新策略是一次删除一个工作节点上的Pod资源,待其最新版本Pod重建完成后再开始操作另一个工作节点上的Pod资源。

DaemonSet控制器的滚动更新机制也可以借助于minReadySeconds字段控制滚动节奏;必要时也可以执行暂停和继续操作。其也可以进行回滚操作。

(六)Kubernetes Pod控制器-ReplicaSet和Deployment和DaemonSet的更多相关文章

  1. Kubernetes学习之路(十二)之Pod控制器--ReplicaSet、Deployment

    一.Pod控制器及其功用 Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效,则会重新新建pod的资源. pod控制器 ...

  2. 6、Kubernetes Pod控制器应用进阶

    定义pod时,在spec字段中常用的定义字段有哪些? master ~]# kubectl explain pods.spec.containers KIND: Pod VERSION: v1 RES ...

  3. k8s之pod控制器

    1.生产中,很少会跑一个自主式pod,一般由控制器去创建pod,其配置文件中内嵌了pod的创建方式. pod控制器:ReplicaSet.Deployment.DaemonSet.Job.Cronjo ...

  4. Kubernetes的pod控制器及ReplicaSet控制器类型的pod的定义

    为什么需要Pod Kubernetes项目之所以这么做的原因: 因为Kubernetes是谷歌公司基于Borg项目做出来的,谷歌工程师发现,他们部署的应用往往存在这进程与进程组的关系.具体说呢,就是这 ...

  5. kubernetes系列07—Pod控制器详解

    本文收录在容器技术学习系列文章总目录 1.Pod控制器 1.1 介绍 Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无 ...

  6. 05-kubernetes Pod控制器应用进阶

    目录 Pod 资源 标签 给资源打标签 标签选择器 Pod 生命周期 实际操作 livenessProbe 实战 livenessProbe exec 测试 livenessProbe httpGet ...

  7. 五,pod控制器应用进阶

    目录 Pod 资源 标签 给资源打标签 标签选择器 Pod 生命周期 pod状态探测 livenessProbe 状态探测 livenessProbe exec 测试 livenessProbe ht ...

  8. 06 . Kubernetes之Pod控制器详细介绍及应用

    Pod API属性详解 Pod是k8s集群中的最小编排单位.将这个设计落实到API对象上,容器就成了Pod属性里一个普通的字段.那么到底哪些属性属于Pod对象,哪些属性属于容器的呢?先看下面的一段描述 ...

  9. kubernetes 的pod控制器

    转载于网络   pod是kubernetes的最小单元,自主式创建的pod删除就没有了,但是通过资源控制器创建的pod如果删除还会重建.pod控制器就是用于实现代替我们去管理pod的中间层,并帮我们确 ...

随机推荐

  1. iptables 常用处理动作

    在iptables中,-j 参数用来指定要进行的处理动作,常用的处理动作包括:ACCEPT.REJECT.DROP.REDIRECT.MASQUERADE.LOG.DNAT.SNAT.MIRROR.Q ...

  2. C/C++ 交换两个数,不使用第三个变量, 函数模板来实现

    #include <iostream> template<typename T> void exchangeTwoNumber(T &t1, T &t2): v ...

  3. bzoj2839 集合计数 组合计数 容斥原理|题解

    集合计数 题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是 ...

  4. Linux上安装git并在gitlab上建立对应的项目

    1.CentOS上面安装git我所用的CentOS为CentOS6.5,其他版本没有测试. yum install git 安装之后查看git版本信息 git --version 2.配置git信息g ...

  5. python3.5以上版本,typing模块提高代码健壮性

    一 前言 Python是一门弱类型的语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数, ...

  6. gunicorn 参数

    gunicorn -w 4 -b 0.0.0.0:8080 yourpyfilename:app --log-level DEBUG --timeout 60gunicorn的命令对应参数含义如下: ...

  7. 企业SDLC建设不成熟设想

    一.说明 1.1 背景说明 之前在N市,面试的是“IT系统安全工程师”的岗位但合同上签的是“集成工程师”的名头(前阵子找之前的邮件offer才注意到的),工作内容现在看来还是和当时离职时表述一样基本一 ...

  8. C++贪心算法实现部分背包问题

    问题描述: 在部分背包问题中,可以不必拿走整个一件物品,而是可以拿走该物品的任意部分.以此求得在限定背包总重量,从给定的物品中进行选择的情况下的最佳(总价值最高)的选择方案. 细节须知: 分别输出到同 ...

  9. Python 中拼音库 PyPinyin 的用法【华为云技术分享】

    [摘要] 最近碰到了一个问题,项目中很多文件都是接手过来的中文命名的一些素材,结果在部署的时候文件名全都乱码了,导致项目无法正常运行. 后来请教了一位大佬怎么解决文件名乱码的问题,他说这个需要正面解决 ...

  10. Elasticsearch 史上最全最常用工具清单

    基础类工具 1.Head插件 1)功能概述: ES集群状态查看.索引数据查看.ES DSL实现(增.删.改.查操作) 比较实用的地方:json串的格式化 2)地址:http://mobz.github ...