在 Kubernetes 集群中,Deployment 是一个非常重要的资源对象,它为 Pod 和 ReplicaSet 提供了声明式的管理方式,极大地简化了应用的部署和运维流程。本文将详细介绍 Deployment 的相关知识,并通过实际案例展示其用法。
一、Deployment 概述
Deployment 可以看作是比 ReplicaSet(RS)更高级的 API 对象,它主要用于管理长期运行的应用服务。其典型应用场景包括:
- 定义 Deployment 来创建 Pod 和 ReplicaSet
- 实现应用的滚动升级和回滚
- 对应用进行扩容和缩容操作
- 暂停和继续 Deployment 的更新过程
从本质上来说,Deployment 代表了用户对 Kubernetes 集群的一次更新操作。当进行滚动升级时,它会创建一个新的 ReplicaSet,然后逐步增加新 RS 中的副本数量,同时减少旧 RS 中的副本数量,直到旧 RS 的副本数为 0。这种复合操作难以用单个 RS 来描述,因此需要 Deployment 这一更通用的对象进行管理。按照 Kubernetes 的发展方向,未来长期运行的业务都将通过 Deployment 进行管理。
二、Deployment YAML 文件详解
一个完整的 Deployment YAML 文件包含多个关键部分,下面对其进行详细说明:
yaml
apiVersion: apps/v1 # 接口版本
kind: Deployment # 接口类型
metadata:
name: cango-demo # Deployment 名称
namespace: cango-prd # 命名空间
labels:
app: cango-demo # 标签
spec:
replicas: 3 # 期望的副本数量
selector: # 选择器,用于匹配 Pod 模板
matchLabels:
app: cango-demo
strategy: # 更新策略
rollingUpdate: # 滚动更新配置
maxSurge: 1 # 滚动升级时允许超出期望副本数的最大数量
maxUnavailable: 1 # 滚动升级时允许不可用的最大副本数
template: # Pod 模板
metadata:
labels:
app: cango-demo # 模板标签,需与 selector 匹配
spec: # 容器模板定义
containers:
- name: cango-demo1 # 容器名称
image: swr.cn-east-2.myhuaweicloud.com/cango-prd/cango-demo:0.0.1-SNAPSHOT # 镜像地址
command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ] # 启动命令
args: # 启动参数
- '-storage.local.retention=$(STORAGE_RETENTION)'
- '-storage.local.memory-chunks=$(STORAGE_MEMORY_CHUNKS)'
- '-config.file=/etc/prometheus/prometheus.yml'
- '-alertmanager.url=http://alertmanager:9093/alertmanager'
- '-web.external-url=$(EXTERNAL_URL)'
imagePullPolicy: IfNotPresent # 镜像拉取策略,不存在则拉取
livenessProbe: # 存活探针,检测容器是否存活
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60 # 启动后延迟多久开始检测
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe: # 就绪探针,检测容器是否就绪
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
resources: # 资源限制
requests: # 资源请求
cpu: 2
memory: 2048Mi
limits: # 资源限制
cpu: 2
memory: 2048Mi
env: # 环境变量
- name: LOCAL_KEY
value: value
- name: CONFIG_MAP_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
ports: # 端口配置
- name: http
containerPort: 8080
volumeMounts: # 卷挂载
- name: log-cache
mountPath: /tmp/log
- name: sdb
mountPath: /data/media
- name: nfs-client-root
mountPath: /mnt/nfs
- name: example-volume-config
mountPath: /etc/config
- name: rbd-pvc
volumes: # 卷定义
- name: log-cache
emptyDir: {}
- name: sdb
hostPath:
path: /any/path/it/will/be/replaced
- name: example-volume-config
configMap:
name: example-volume-config
items:
- key: log-script
path: path/to/log-script
- key: backup-script
path: path/to/backup-script
- name: nfs-client-root
nfs:
server: 10.42.0.55
path: /opt/public
- name: rbd-pvc
persistentVolumeClaim:
claimName: rbd-pvc1
其中需要注意的是命令和参数的关系:
- 如果 command 和 args 都未设置,将使用 Docker 镜像的默认配置
- 如果设置了 command 但未设置 args,将执行 command 且不带任何参数
- 如果未设置 command 但设置了 args,将使用镜像默认的 ENTRYPOINT 并传入 args 作为参数
- 如果两者都设置,将忽略镜像默认配置,使用设置的 command 和 args
三、企业应用案例
3.1 环境准备
首先创建 Deployment 的 YAML 文件 my-blue.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 3
selector:
matchLabels:
app: myapp-blue
template:
metadata:
labels:
app: myapp-blue
spec:
containers:
- name: myapp-blue
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
然后创建对应的 Service 文件 my-blue-service.yaml 以提供访问入口:
yaml
apiVersion: v1
kind: Service
metadata:
name: service-blue
spec:
selector:
app: myapp-blue
type: NodePort
ports:
- port: 80
nodePort: 30030
targetPort: 80
使用以下命令提交资源清单:
bash
运行
kubectl apply -f my-blue.yaml
kubectl apply -f my-blue-service.yaml
可以通过以下命令查看创建的资源:
bash
运行
kubectl get pod
kubectl get svc
3.2 扩缩容操作
扩缩容非常简单,只需修改 YAML 文件中 replicas 的数量即可。例如,将副本数改为 5:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 5 # 修改此处的数量
selector:
matchLabels:
app: myapp-blue
template:
metadata:
labels:
app: myapp-blue
spec:
containers:
- name: myapp-blue
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
修改后执行 kubectl apply -f my-blue.yaml 即可生效。
3.3 滚动更新
滚动更新通过修改容器镜像版本来实现,例如将镜像从 v1 更新到 v2:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 3
selector:
matchLabels:
app: myapp-blue
template:
metadata:
labels:
app: myapp-blue
spec:
containers:
- name: myapp-blue
image: janakiramm/myapp:v2 # 修改镜像版本
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
同样执行 kubectl apply -f my-blue.yaml 应用更新,Deployment 会按照预设的更新策略进行滚动更新。
3.4 回滚操作
如果更新后出现问题,可以进行回滚操作。首先查看历史版本:
bash
运行
kubectl rollout history deployment <deployment名称>
然后回滚到指定版本:
bash
运行
kubectl rollout undo deployment <deployment名称> --to-revision=1
四、自定义更新策略
Deployment 的更新策略主要通过 maxSurge 和 maxUnavailable 来配置:
maxSurge:与期望副本数相比,允许超出的最大比例或数量,值越大更新速度越快maxUnavailable:与期望副本数相比,允许不可用的最大比例或数量,值越小服务越稳定
设置方式
-
按数量设置:
maxUnavailable: 取值范围为 [0, 副本数]maxSurge: 取值范围为 [0, 副本数]- 注意:两者不能同时为 0
-
按比例设置:
maxUnavailable: 取值范围为 [0%, 100%],计算时向下取整maxSurge: 取值范围为 [0%, 100%],计算时向上取整- 注意:两者不能同时为 0
配置案例
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: v1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
通过合理配置 Deployment,我们可以轻松实现应用的部署、更新、扩缩容和回滚等操作,极大地提高了 Kubernetes 集群中应用的管理效率。