Deployment 核心概念
Deployment 是 Kubernetes 中管理无状态应用的核心对象,通过声明式配置实现对 Pod 和 ReplicaSet 的自动化管理。其核心功能围绕应用生命周期管理展开:
- 声明式更新:用户通过 YAML 文件定义期望状态,系统自动调整实际状态至匹配
- 版本控制:保留历史版本记录,支持滚动更新和快速回滚
- 扩缩容:动态调整 Pod 副本数量应对负载变化
- 自愈能力:自动替换故障节点,维持声明副本数
YAML 文件结构解析
典型 Deployment 配置文件包含以下关键字段:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
关键字段说明
metadata 部分
name: 必填字段,定义 Deployment 对象名称labels: 可选标签,用于资源分类和组织
spec 部分核心参数
replicas: 指定期望的 Pod 副本数量selector: 标签选择器,确定 Deployment 管理的 Pod 范围template: Pod 模板定义,必须包含匹配 selector 的标签
策略配置扩展
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
minReadySeconds: 10
revisionHistoryLimit: 10
strategy.type: 更新策略(RollingUpdate/Recreate)maxSurge: 更新期间允许超出副本数的百分比maxUnavailable: 更新期间允许不可用副本比例minReadySeconds: Pod 就绪后等待时间(秒)revisionHistoryLimit: 保留的历史版本数量
操作场景示例
滚动更新触发 修改 Pod 模板中的镜像版本后,自动触发渐进式更新流程:
shell
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
版本回滚操作 回退到上一个稳定版本:
shell
kubectl rollout undo deployment/nginx-deployment
状态监控命令 查看更新进度和状态:
shell
kubectl rollout status deployment/nginx-deployment
kubectl get replicasets -l app=nginx
高级配置技巧
资源配额管理 在 Pod 模板中配置资源限制:
yaml
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "250m"
memory: "256Mi"
健康检查配置 添加存活和就绪探针:
yaml
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
多容器部署 单个 Pod 中部署多个关联容器:
yaml
containers:
- name: nginx
image: nginx:1.16.1
- name: log-collector
image: fluentd:latest
bash
apiVersion: extensions/v1beta1 #接口版本
kind: Deployment #接口类型
metadata:
name: cango-demo #Deployment名称
namespace: cango-prd #命名空间
labels:
app: cango-demo #标签
spec:
replicas: 3
selector:
matchLabels:
app: cango-demo #匹配模板中label
strategy:
rollingUpdate: ##由于replicas为3,则整个升级,pod个数在2-4个之间
maxSurge: 1 #滚动升级时会先启动1个pod
maxUnavailable: 1 #滚动升级时允许的最大Unavailable的pod个数
template:
metadata:
labels:
app: cango-demo #模板名称必填
sepc: #定义容器模板,该模板可以包含多个容器
containers:
- name: cango-demo #镜像名称
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)'
#如果command和args均没有写,那么用Docker默认的配置。
#如果command写了,但args没有写,那么Docker默认的配置会被忽略而且仅仅执行.yaml文件的command(不带任何参数的)。
#如果command没写,但args写了,那么Docker默认配置的ENTRYPOINT的命令行会被执行,但是调用的参数是.yaml中的args。
#如果如果command和args都写了,那么Docker默认的配置被忽略,使用.yaml的配置。
imagePullPolicy: IfNotPresent #如果不存在则拉取
livenessProbe: #表示container是否处于live状态。如果LivenessProbe失败,LivenessProbe将会通知kubelet对应的container不健康了。随后kubelet将kill掉container,并根据RestarPolicy进行进一步的操作。默认情况下LivenessProbe在第一次检测之前初始化值为Success,如果container没有提供LivenessProbe,则也认为是Success;
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: ##CPU内存限制
requests:
cpu: 2
memory: 2048Mi
limits:
cpu: 2
memory: 2048Mi
env: ##通过环境变量的方式,直接传递pod=自定义Linux OS环境变量
- name: LOCAL_KEY #本地Key
value: value
- name: CONFIG_MAP_KEY #局策略可使用configMap的配置Key,
valueFrom:
configMapKeyRef:
name: special-config #configmap中找到name为special-config
key: special.type #找到name为special-config里data下的key
ports:
- name: http
containerPort: 8080 #对service暴露端口
volumeMounts: #挂载volumes中定义的磁盘
- name: log-cache
mountPath: /tmp/log
- name: sdb #普通用法,该卷跟随容器销毁,挂载一个目录
mountPath: /data/media
- name: nfs-client-root #直接挂载硬盘方法,如挂载下面的nfs目录到/mnt/nfs
mountPath: /mnt/nfs
- name: example-volume-config #高级用法第1种,将ConfigMap的log-script,backup-script分别挂载到/etc/config目录下的一个相对路径path/to/...下,如果存在同名文件,直接覆盖。
mountPath: /etc/config
- name: rbd-pvc #高级用法第2中,挂载PVC(PresistentVolumeClaim)
#使用volume将ConfigMap作为文件或目录直接挂载,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容,
volumes: # 定义磁盘给上面volumeMounts挂载
- name: log-cache
emptyDir: {}
- name: sdb #挂载宿主机上面的目录
hostPath:
path: /any/path/it/will/be/replaced
- name: example-volume-config # 供ConfigMap文件内容到指定路径使用
configMap:
name: example-volume-config #ConfigMap中名称
items:
- key: log-script #ConfigMap中的Key
path: path/to/log-script #指定目录下的一个相对路径path/to/log-script
- key: backup-script #ConfigMap中的Key
path: path/to/backup-script #指定目录下的一个相对路径path/to/backup-script
- name: nfs-client-root #供挂载NFS存储类型
nfs:
server: 10.42.0.55 #NFS服务器地址
path: /opt/public #showmount -e 看一下路径
- name: rbd-pvc #挂载PVC磁盘
persistentVolumeClaim:
claimName: rbd-pvc1 #挂载已经申请的pvc磁盘
三、企业应用案例 h3 3.1 环境准备 创建my-blue.yaml
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 3
selector:
matchLabels:
app: myapp-blue #匹配模板中label
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
bash
apiVersion: v1
kind: Service
metadata:
name: service-blue
spec:
selector:
app: myapp-blue
type: NodePort
ports:
- port: 80
nodePort: 30030
targetPort: 80
提交对应的资源清单
bash
[root@k8s-master01 ~]# kubectl apply -f my-blue.yaml
[root@k8s-master01 ~]# kubectl apply -f my-blue-service.yaml
#查看对应的资源
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mydm-7755b9f55f-7h2nb 1/1 Running 0 69s
mydm-7755b9f55f-bj9gf 1/1 Running 0 69s
mydm-7755b9f55f-hjckc 1/1 Running 0 69s
mydm-7755b9f55f-lfvrd 1/1 Running 0 69s
mydm-7755b9f55f-lxzw4 1/1 Running 0 69s
mydm-7755b9f55f-v74w8 1/1 Running 0 69s
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-blue NodePort 10.10.157.201 <none> 80:30030/TCP 87s
3.2 扩缩容 修改对应的yaml文件中的replicas的数量
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 5
selector:
matchLabels:
app: myapp-blue #匹配模板中label
template:
metadata:
labels:
app: myapp-blue
spec:
containers:
- name: myapp-blue
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
3.3 滚动更新 修改对应的yaml文件中的image信息
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydm
spec:
replicas: 3
selector:
matchLabels:
app: myapp-blue #匹配模板中label
template:
metadata:
labels:
app: myapp-blue
spec:
containers:
- name: myapp-blue
image: janakiramm/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
3.4 回滚 查看历史版本
bash
[root@k8s-master01 ~]# kubectl rollout history deployment name
回滚操作
bash
[root@k8s-master01 ~]# kubectl rollout undo deployment name --to-revision=1
自定义更新策略配置详解
maxSurge与maxUnavailable类型说明
maxSurge
定义与期望副本数相比,允许超出副本数的最大比例或绝对值。数值越大,副本更新速度越快,但可能短暂占用更多资源。
maxUnavailable
定义与期望副本数相比,允许不可用副本的最大比例或绝对值。数值越小,服务稳定性越高,更新过程更平滑,但可能延长更新时间。
设置类型
按数量配置
maxUnavailable取值范围为[0, 副本数],例如副本数为10时,可设为3表示最多允许3个副本不可用。maxSurge取值范围为[0, 副本数],例如设为2表示最多允许同时新增2个副本。- 两者不能同时为0,否则会导致更新无法进行。
按比例配置
maxUnavailable取值范围为[0%, 100%],计算时向下取整。例如10个副本的5%为0.5,实际按0处理。maxSurge取值范围为[0%, 100%],计算时向上取整。例如10个副本的5%为0.5,实际按1处理。- 两者不能同时为0%,需至少保证一个参数允许更新动作。
配置案例
案例1:快速更新(侧重速度)
yaml
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 30% # 允许快速扩容30%副本
maxUnavailable: 10% # 仅允许10%副本不可用
案例2:平滑更新(侧重稳定性)
yaml
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 每次仅新增1个副本
maxUnavailable: 0 # 确保所有副本始终可用
案例3:混合配置(平衡速度与稳定性)
yaml
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 20% # 按比例扩容,向上取整
maxUnavailable: 1 # 按数量控制,最多1个副本不可用
注意事项
- 生产环境中建议优先保证稳定性(
maxUnavailable设为较低值)。 - 测试环境可适当调高
maxSurge以加速迭代。 - 按比例配置时需注意副本总数,避免因取整规则导致更新停滞。
bash
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