
Deployment管理与使用
一、Kubernetes管理对象
1. 控制器概述
设定空调温度的时候,通过遥控器定义期望状态(Desired State),而房间实时温度就是当前状态(Current State)。操作遥控器后,空调会持续调节,让当前状态不断趋近并匹配期望状态。
在Kubernetes中,控制器会持续监听集群的实际状态,核心工作就是驱动集群的当前状态向期望状态对齐。
作为设计原则之一,Kubernetes采用控制器分工模式,多个控制器各司其职,各自负责集群状态的一个特定方面。最典型的设计是,控制器以某一类资源作为期望状态依据,专门管控另一类资源,使其逐步向期望状态演进。
2. ReplicationController(RC)
ReplicationController(复制控制器,简称RC)的核心作用是确保在任何时候都有特定数量的Pod副本处于运行状态,确保单个或一组同类型Pod持续可用。
RC可以指定Pod的副本数量,并且在其中有Pod故障时可以自动拉起新的Pod,大大简化了管理难度。
ReplicationController是Kubernetes早期的初代副本控制器,ReplicaSet(简称RS)作为其升级替代版本,完全兼容ReplicationController的所有能力,同时扩展了更强的功能。生产环境中,更推荐使用ReplicaSet的Deployment来实现副本管理。
4. ReplicaSet副本集(RS)
ReplicaSet是ReplicationController(RC)的新一代升级版,核心能力与RC基本一致:负责维持Pod副本数量稳定、管控Pod运行调度。二者使用方式也相近,主要差异在于ReplicaSet升级了API接口,扩展了更多能力。
ReplicaSet的核心职责,是维护一组数量固定、持续运行的Pod副本集合,确保指定数量且配置一致的Pod始终处于可用状态。
ReplicaSet资源同样必须配置“apiVersion”、“kind”和“metadata”字段
Pod标签选择器:通过“.spec.selector”字段定义标签选择规则。ReplicaSet要求Pod模板标签“.spec.template.metadata.labels”必须和“.spec.selector”匹配,否则API会直接拒绝该配置。
可以通过“.spec.replicas”设定预期运行的Pod副本数,ReplicaSet会自动创建或销毁Pod,始终保证实际副本数量与设定值一致。
5. 命令行接口
Kubernetes集群的各类运维操作均依托kubectl工具实现,可以对Deployment、ReplicaSet、Pod等资源,完成创建、删除等全生命周期管理,也可以查询资源状态、监控资源占用情况。
[Tricks] kubectl的基本语法。
kubectl [command] [TYPE] [NAME] [flags]command:指定你希望进行的操作,如create、get、describe、delete等
TYPE:指定操作对象的类型,如deployment、RS、Pod等
NAME:指定对象的名称
flags:可选的标志位
[Tricks] 常用的Command有五种。
[Tricks] 创建一个Deployment,镜像使用nginx。
root@k8s-master:~# kubectl create deployment dep01 --image=nginx
6. Deployment概述
目前k8s运维最常用控制器为Deployment,创建Deployment会自动生成ReplicaSet(RS)。日常业务部署优先使用Deployment,一般不会直接操作ReplicaSet。仅在需要自定义特殊更新流程、无需版本迭代的特殊场景下,才直接使用RS。
实际开发运维中无需手动操作ReplicaSet,直接在Deployment的spec字段定义应用配置即可完成业务部署与管控。Deployment层级管理逻辑如下。
容器 < Pod < ReplicaSet < Deployment5.1 资源组成关系
Pod:最小调度单元,内部一般搭载单个业务容器,也可以放置耦合度极高的多个容器。
ReplicaSet:管控一组完全相同的Pod,保障集群内始终维持指定数量Pod副本正常运行。
Deployment:高级管控层,可管理一个或多个不同ReplicaSet,依托RS间接管理所有Pod。
5.2 Deployment与RS区别
ReplicaSet:仅负责维持Pod副本数量稳定,无版本更新、滚动发布等高级功能。
Deployment:在RS基础上,提供声明式更新、滚动升级、版本回滚、扩容缩容等核心功能。
5.3 pod-template-hash
pod-template-hash(基于Pod模板计算出的哈希标识)是k8s系统内置固定标签,由Deployment控制器自动生成、自动挂载,无需人工手动定义、手动编写YAML添加。
来源主体:Deployment
标签值:一串7位数字+字母哈希字符串
计算依据:对Deployment中“spec.template”整个Pod模板全文做哈希算法运算
挂载对象:自动在ReplicaSet和该RS管理的所有Pod上
root@k8s-master:~# kubectl get replicasets.apps
NAME DESIRED CURRENT READY AGE
nginx-deployment-6896c96c7b 4 4 4 11m
7. Deployment弹性伸缩
相较于虚拟机,容器的核心优势是具备灵活的弹性伸缩功能,该能力由Kubernetes负责调度管控。Deployment弹性伸缩本质是Pod数量的增加或减少,可以快速完成实例调整,支撑业务自动化部署。Deployment弹性伸缩主要分为两种实现方式:
编辑YAML配置文件,修改replica副本数
使用scale命令,快速完成扩容或缩容操作
7.1 Deployment升级
当使用的Deployment需要升级时,如软件版本更新,可以使用“rolling update”功能滚动升级Deployment中所有的Pod。
7.2 Deployment回滚
使用Kubernetes滚动更新后,Kubernetes会记录下本次更新,并且保持一个历史版本。如果更新后出现应用异常,可以通过回滚操作回到之前的版本。
二、Deployment基础案例
1. 创建Deployment
[Step1] 本地新建YAML清单,定义Deployment资源描述模板。
root@k8s-master:~# vim nginx-deployment.yml
# 写入下列内容
# 版本号,固定为apps/v1,如果1.9.0以前版本使用apps/v1beta2
apiVersion: apps/v1
kind: Deployment # 资源类型
metadata: # 元数据
name: nginx-deployment
labels: # 定义标签
app: nginx-deployment # 自定义标签(键和值均可自定义)
spec:
replicas: 4 # 预期数量为4
selector:
matchLabels: # 标签匹配模式:精确匹配
app: nginx-deployment # 匹配的标签值
template: # 对Pod模板的定义,至少要定义一个Label
metadata:
labels: # 给Pod加上标签,需要和selector定义一致
app: nginx-deployment
spec:
containers: # 定义容器的属性
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80[Step2] 基于YAML清单向Kubernetes集群声明式地创建Deployment资源。
root@k8s-master:~# kubectl create -f nginx-deployment.yml[Step3] 验证:查看当前集群中的所有Deployment资源。
root@k8s-master:~# kubectl get deployments.apps
root@k8s-master:~# kubectl get deploy
[Step4] 验证:在创建Deployment时会自动生成ReplicaSet,查看当前集群中所有的ReplicaSet资源。Deployment控制器会将pod-template-hash标签添加到Deployment所创建的每个ReplicaSet中,此时能够看到pod-template-hash标签。
root@k8s-master:~# kubectl get replicasets.apps
[Step5] 验证:查看当前命名空间下所有的Pod,能够看到4个以ReplicaSet名称开头的Pod,同时能够看到定义的标签值。
root@k8s-master:~# kubectl get pod --show-labels
root@k8s-master:~# kubectl get pod -l app=nginx-deployment
2. 更新Deployment
[Step1] Deployment内滚动更新策略,默认配置“maxSurge: 25%”、“maxUnavailable: 25%”。更新时可扩容出最多25%的Pod,最多容许25%实例不可用。保障服务持续在线,实现平滑版本迭代。
# 查看nginx-deployment的完整详细信息,并以YAML格式输出
root@k8s-master:~# kubectl get deployments.apps nginx-deployment -o yaml
[Step2] 更新Deployment,将原有的镜像从“nginx:latest”修改为“httpd:latest”。在k8s新版本中不再推荐使用“--record”,未来版本中会删除,因此会出现相关提示。
root@k8s-master:~# kubectl set image deployments/nginx-deployment nginx=httpd:latest --record
# 除了上述通过命令的方式修改,也可以通过edit命令进行修改
root@k8s-master:~# kubectl edit deployments/nginx-deploymentkubectl set image:修改镜像
deployments/nginx-deployment:修改的Deployment名称
nginx=httpd:latest:将容器nginx镜像修改为httpd
--record:记录更新命令,方便回看历史

[Step3] 验证:查看Deployment升级进度,显示为“successfully”则表示更新成功。
root@k8s-master:~# kubectl rollout status deployment/nginx-deployment
[Step4] 验证:以YAML格式输出nginx-deployment完整配置,过滤出镜像字段,能够看到镜像已经修改为“httpd:latest”。
root@k8s-master:~# kubectl get deployments.apps nginx-deployment -o yaml | grep image
[Step5] 验证:查看当前集群中所有的ReplicaSet资源,能够看到更新后新增的RS。Kubernetes更新Deployment时,会根据新配置创建全新的ReplicaSet,而原有的旧版RS自动保存。以此保持历史应用版本,支持业务快速回滚恢复。
root@k8s-master:~# kubectl get rs
[Step6] 验证:查看nginx-deployment的完整详细信息,从“Events”事件列表中可以确认,所有调度工作均由Deployment控制器发起。
新版副本集“nginx-deployment-5b58b8b84”从0实例扩容到1,启动新版本业务Pod;
同步将旧版本副本集“nginx-deployment-6896c96c7b”从4实例缩容到3,逐步关停旧业务实例;
持续交替完成新版扩容、旧版缩容操作,分批完成实例数量迭代更替;
直至新版副本集扩容至预设4个目标实例,旧版副本集缩容为0,完成全量版本更替。
root@k8s-master:~# kubectl describe deployments.apps nginx-deployment
3. 回滚Deployment
[Step1] 假设此时我们使用的镜像有问题,需要回退至上一版本。首先查看nginx-deployment的版本更新历史,可以查看到两个版本。其中版本1为初始创建版本,在首次部署为添加记录参数,因此记录操作记录显示为“none”。第二次更新时使用了“--record”参数,系统自动留存对应的修改操作命令。
root@k8s-master:~# kubectl rollout history deployment/nginx-deployment
[Step2] 可以通过“--revision”参数查看指定版本的详细信息。
root@k8s-master:~# kubectl rollout history deployment/nginx-deployment --revision=2
[Step3] 将nginx-deployment回滚到版本1。
root@k8s-master:~# kubectl rollout undo deployment/nginx-deployment --to-revision=1
[Step4] 验证:查看当前集群中所有的ReplicaSet资源,此时已经切换为旧RS。
root@k8s-master:~# kubectl get replicasets.apps
[Step5] 验证:查看nginx-deployment的版本更新历史。Kubernetes不会覆盖版本历史,所有运维操作都会留存记录。回滚等同于一个全新发布,因此版本号会自动递增。
root@k8s-master:~# kubectl rollout history deployment nginx-deployment
### 4. 伸缩Deployment
[Step1] 查看当前集群中的所有Deployment资源以及当前命名空间下的所有Pod。
root@k8s-master:~# kubectl get deployments.apps
root@k8s-master:~# kubectl get pod
[Step2] 将nginx-deployment运行实例扩容到10个。
root@k8s-master:~# kubectl scale deployment/nginx-deployment --replicas=10
[Step3] 验证:查看当前集群中所有Deployment资源以及当前命名空间下的Pod,能够看到实例数量提升至10。
root@k8s-master:~# kubectl get deployments.apps
root@k8s-master:~# kubectl get pod
三、ReplicaSet基础案例
[Step1] 本地新建YAML清单,定义ReplicaSet资源描述模板。
root@k8s-master:~# vim nginx-replicaset.yml
# 写入下列内容
apiVersion: apps/v1 # 固定配置
kind: ReplicaSet # 资源类型
metadata:
name: nginx-replicaset
labels: # 定义标签
app: nginx-label # 自定义标签(键和值均可自定义)
spec:
replicas: 4 # 预期数量为4
selector:
matchLabels: # 标签匹配模式:精确匹配
app: nginx-label # 匹配的标签值
template: # 根据此模板来新建Pod
metadata:
labels: # 给Pod加上标签,需要和selector定义一致
app: nginx-label
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 1314
imagePullPolicy: IfNotPresent[Step2] 基于YAML清单向Kubernetes集群声明式地创建ReplicaSet资源。
root@k8s-master:~# kubectl create -f nginx-replicaset.yml[Step3] 验证:查看当前命名空间下所有ReplicaSet副本集的状态,能够看到运行的资源数与我们在YAML中定义的数量一致。
# "replicasets.apps"的缩写形式是"rs"
root@k8s-master:~# kubectl get replicasets.apps
root@k8s-master:~# kubectl get rs
[Step4] 验证:查看当前命名空间下所有的Pod,能够看到4个以“nginx-replicaset-”开头的Pod,同时能够看到定义的标签值。
root@k8s-master:~# kubectl get pod --show-labels
root@k8s-master:~# kubectl get pod -l app=nginx-label
[Step5] 验证:可以通过标签过滤的方式,查看指定标签值的Pod资源。
root@k8s-master:~# kubectl get pod -l app=nginx-label
[Step6]可以通过命令指定ReplicaSet名称与目标副本数,实现动态扩容或缩减。
root@k8s-master:~# kubectl scale replicaset nginx-replicaset --replicas 10
root@k8s-master:~# kubectl scale replicaset nginx-replicaset --replicas 8
[Step7] ReplicaSet会始终维持Pod副本数量与YAML配置中定义的副本数一致。因此,即便手动删除所有关联Pod,Kubernetes也会自动重新创建对应数量的Pod,保障副本规模稳定不变。
root@k8s-master:~# kubectl delete pod --all
[Step8] 虽然我们这里创建的nginx都是使用1314端口,但是都属于不同的Pod,不同的Pod拥有自己的网络资源,因此不会产生冲突。
root@k8s-master:~# kubectl get pod -o wide
[Step9] 如果将副本数设置为0,此时Pod的数量也会为0,但是ReplicaSet副本集仍然会存在。
root@k8s-master:~# kubectl scale replicaset nginx-replicaset --replicas 0
root@k8s-master:~# kubectl get replicasets.apps
root@k8s-master:~# kubectl get pod
[Step10] 删除ReplicaSet副本集。
# 两种删除方式效果一致
root@k8s-master:~# kubectl delete replicasets.apps nginx-replicaset
root@k8s-master:~# kubectl delete rs nginx-replicaset
