Files
Qiniu/technical/k8s/k8s-04-deployment-and-replicaset.md
T

793 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [k8s, deployment, replicaset, devops]
create time: 2026-07-07 15:48
---
# Deployment 与 ReplicaSet
## 概述
Deployment 是 Kubernetes 中最常用的无状态工作负载控制器,它在 ReplicaSet 之上提供了声明式更新、滚动发布、版本回滚等高级能力。日常开发中,绝大多数无状态服务(Web API、微服务后端、定时任务 Worker)都通过 Deployment 来管理 Pod 的生命周期。理解 Deployment 与 ReplicaSet 的协作关系,是掌握 Kubernetes 应用交付模型的基础。
## ReplicaSet 详解
### 什么是 ReplicaSet
ReplicaSet(简称 RS)的核心职责只有一件事:**确保指定数量的 Pod 副本始终处于运行状态**。如果某个 Pod 意外退出或被删除,RS 会立即创建新的 Pod 来弥补差额;如果 Pod 数量超过期望值,RS 会删除多余的 Pod。
```yaml
# 一个独立的 ReplicaSet 示例(通常不直接创建,由 Deployment 自动管理)
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
namespace: default
spec:
replicas: 3 # 期望副本数
selector:
matchLabels:
app: nginx # Label Selector:通过标签匹配 Pod
template:
metadata:
labels:
app: nginx # Pod 必须携带此标签才能被 RS 管理
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
```
### Label Selector 机制
RS 通过 **Label Selector** 来发现和管理 Pod,而非维护一个固定的 Pod 列表。这意味着:
- 手动创建的 Pod 只要标签匹配,也会被 RS 纳入管理(数量超出则删除,不足则新建)
- 修改某个 Pod 的标签可以将其从 RS 管理中"摘除",这在调试时非常有用
```bash
# 将一个 Pod 从 RS 中移除(不删除 Pod,仅修改标签使其脱离管理)
kubectl label pod nginx-rs-xxxx app=detached --overwrite
# 此时 RS 会发现少了一个副本,自动新建一个 Pod 来补足
```
> [!tip] 调试技巧
> 需要排查某个 Pod 问题时,先把它从 RS 中"摘出来"(修改标签),这样 RS 不会因为 Pod 异常而自动重建,你可以从容排查。
### ReplicaSet vs ReplicationController
ReplicationController(RC)是 RS 的前身,两者核心区别在于 Selector 语义:
| 对比维度 | ReplicationController | ReplicaSet |
|----------|----------------------|------------|
| Selector 类型 | 仅支持等式(`env=prod`) | 支持等式 + 集合(`env in (prod, staging)`) |
| 标签匹配灵活性 | 低 | 高 |
| 推荐程度 | 已废弃,不建议使用 | 推荐使用 |
| 滚动更新 | 需要 `kubectl rolling-update`(客户端执行) | 由 Deployment 在服务端协调 |
RC 已经是遗留概念,新资源应统一使用 ReplicaSet。不过实践中你几乎不会直接创建 RS,而是通过 Deployment 间接管理。
## Deployment 核心机制
### 声明式管理
Deployment 采用声明式模型:你只需描述"期望状态"(desired state),Kubernetes 控制面会持续将其与"实际状态"(actual state)做对比,自动执行必要的操作来弥合差距。这个循环叫做 **Reconcile Loop**(调谐循环)。
```mermaid
graph LR
A["用户提交 Deployment<br/>(desired state)"] --> B["Deployment Controller"]
B --> C{"desired == actual ?"}
C -->|No| D["创建/删除/更新<br/>ReplicaSet / Pod"]
D --> B
C -->|Yes| E["状态稳定<br/>不做任何操作"]
```
工作流程:
1. 用户通过 `kubectl apply` 提交 Deployment YAML,声明 `replicas: 3`、`image: nginx:1.25` 等期望状态
2. Deployment Controller 观察到当前没有匹配的 RS,创建一个新的 RS
3. RS Controller 观察到 Pod 数量为 0,创建 3 个 Pod
4. 持续监控:如果某个 Pod 崩溃,RS Controller 检测到 actual < desired,立即补充新 Pod
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
spec:
replicas: 3 # 声明:我想要 3 个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25 # 声明:我想用这个镜像
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
```
### 滚动更新(Rolling Update)
滚动更新是 Deployment 最核心的价值。当你修改了 Pod 模板(比如升级镜像版本),Deployment 不会一次性杀掉所有旧 Pod,而是**逐批替换**,在更新过程中始终保持服务可用。
#### 关键参数
| 参数 | 默认值 | 含义 |
|------|--------|------|
| `maxSurge` | 25% | 更新过程中允许超出 `replicas` 的最大 Pod 数量 |
| `maxUnavailable` | 25% | 更新过程中允许不可用的最大 Pod 数量 |
> [!info] 参数计算
> 对于 `replicas: 4`、`maxSurge: 25%`、`maxUnavailable: 25%` 的配置:
> - maxSurge = ceil(4 * 0.25) = 1,最多可以有 5 个 Pod 同时存在
> - maxUnavailable = floor(4 * 0.25) = 1,至少保证 3 个 Pod 可用
>
> 这意味着每批替换 1 个 Pod,共需 4 批完成更新。
#### 滚动更新过程
```mermaid
sequenceDiagram
participant U as 用户
participant D as Deployment Controller
participant RS1 as ReplicaSet v1
participant RS2 as ReplicaSet v2
U->>D: kubectl apply(image: nginx:1.26)
D->>RS2: 创建新 RS(image: 1.26, replicas: 0)
D->>RS2: scale up +1(新建 1 个新 Pod)
Note over RS1,RS2: maxSurge=1, 新 Pod 启动
D->>RS1: scale down -1(销毁 1 个旧 Pod)
Note over RS1,RS2: maxUnavailable=1, 保证可用
D->>RS2: scale up +1
D->>RS1: scale down -1
Note over RS1,RS2: 重复直到 RS1=0, RS2=4
D->>RS1: 保留 RS1(revision=1, 可回滚)
```
逐批替换的过程(以 `replicas: 4` 为例):
| 阶段 | RS v1 (旧) | RS v2 (新) | 总 Pod 数 | 可用 Pod |
|------|-----------|-----------|----------|---------|
| 初始 | 4 | 0 | 4 | 4 |
| 第 1 批 | 4 → 3 | 0 → 1 | 5 | 4 |
| 第 2 批 | 3 → 2 | 1 → 2 | 4 | 4 |
| 第 3 批 | 2 → 1 | 2 → 3 | 4 | 4 |
| 第 4 批 | 1 → 0 | 3 → 4 | 4 | 4 |
#### 滚动更新配置
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 4
strategy:
type: RollingUpdate # 更新策略
rollingUpdate:
maxSurge: 1 # 最多多 1 个 Pod
maxUnavailable: 1 # 最多少 1 个 Pod
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
readinessProbe: # 重要:就绪探针决定新 Pod 何时接收流量
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 10
```
> [!warning] readinessProbe 的重要性
> 滚动更新依赖 `readinessProbe` 判断新 Pod 是否就绪。如果没有配置就绪探针,新 Pod 一创建就被视为 Ready,可能导致流量打到尚未初始化完成的 Pod 上,造成请求失败。
### 回滚策略
Kubernetes 为每次 Deployment 变更自动记录 revision(版本号),支持快速回滚到任意历史版本。
```bash
# 查看 rollout 历史
kubectl rollout history deployment nginx-deploy
# 输出示例:
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
# 3 <none>
# 查看某个 revision 的详细信息
kubectl rollout history deployment nginx-deploy --revision=2
# 回滚到上一个版本
kubectl rollout undo deployment nginx-deploy
# 回滚到指定版本
kubectl rollout undo deployment nginx-deploy --to-revision=1
# 查看 rollout 状态(是否完成、耗时等)
kubectl rollout status deployment nginx-deploy
```
#### revisionHistoryLimit 配置
默认保留 10 个历史 revision。过多的历史 RS 会占用 etcd 资源,过少则可能丢失回滚能力。
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
revisionHistoryLimit: 5 # 只保留最近 5 个 revision
# 设为 0 则禁用回滚(不推荐)
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
kubernetes.io/change-cause: "升级到 nginx 1.26" # 记录变更原因,显示在 rollout history 中
spec:
containers:
- name: nginx
image: nginx:1.26
```
> [!tip] 记录变更原因
> 在 Pod template 的 `annotations` 中添加 `kubernetes.io/change-cause`,这样 `kubectl rollout history` 会显示每次变更的原因,方便排查。
### 扩缩容
#### 手动扩缩容
```bash
# 命令行直接扩缩
kubectl scale deployment nginx-deploy --replicas=5
# 条件扩缩(只有当前副本数为 3 时才执行)
kubectl scale deployment nginx-deploy --replicas=5 --current-replicas=3
```
也可以直接修改 YAML 中的 `replicas` 字段后 `kubectl apply`。
#### HPA 自动扩缩
Horizontal Pod Autoscaler(HPA)根据 CPU、内存或自定义指标自动调整 Deployment 的副本数。
```yaml
# 前置条件:集群中需要安装 Metrics Server
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deploy # 目标 Deployment
minReplicas: 2 # 最小副本数
maxReplicas: 10 # 最大副本数
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # CPU 使用率超过 60% 时扩容
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80 # 内存使用率超过 80% 时扩容
behavior:
scaleUp:
stabilizationWindowSeconds: 60 # 扩容稳定窗口:60s 内取最大值
policies:
- type: Pods
value: 4 # 每次最多扩 4 个 Pod
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300 # 缩容稳定窗口:300s,防止抖动
policies:
- type: Percent
value: 10 # 每次最多缩 10%
periodSeconds: 60
```
```bash
# 创建 HPA
kubectl apply -f hpa.yaml
# 或用命令行快速创建
kubectl autoscale deployment nginx-deploy --cpu-percent=60 --min=2 --max=10
# 查看 HPA 状态
kubectl get hpa nginx-hpa
```
> [!warning] HPA 与手动 scale 冲突
> 如果同时使用 HPA 和手动 `kubectl scale`,HPA 会在下一次指标采集时覆盖手动设置。两者不应混用。
## Deployment 更新策略
Deployment 支持两种更新策略,通过 `spec.strategy.type` 指定:
| 对比维度 | RollingUpdate | Recreate |
|----------|--------------|----------|
| 更新方式 | 逐批替换 Pod | 先杀全部旧 Pod,再创建全部新 Pod |
| 更新期间可用性 | 始终可用(前提:正确配置探针) | 有短暂不可用窗口 |
| 资源占用 | 可能临时需要更多资源(maxSurge > 0 时) | 只需要新版本的资源 |
| 适用场景 | 大多数无状态服务 | 不能有两个版本同时运行的场景 |
| 典型用例 | Web 服务、API 后端 | 涉及全局独占资源(如本地文件锁、全局数据库迁移) |
```yaml
# Recreate 策略示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-app
spec:
replicas: 3
strategy:
type: Recreate # 全量替换,更新期间服务不可用
selector:
matchLabels:
app: legacy
template:
metadata:
labels:
app: legacy
spec:
containers:
- name: app
image: legacy-app:2.0
```
> [!info] 什么时候用 Recreate?
> 当新旧版本不能共存时使用 Recreate,比如:应用使用了本地文件锁、需要执行不可逆的数据库 Schema 迁移、或者旧版本会干扰新版本的初始化。大多数情况下 RollingUpdate 是更好的选择。
## 金丝雀发布与蓝绿部署
Deployment 本身不直接支持金丝雀发布和蓝绿部署,但可以通过组合多个 Deployment + Service 来实现。
### 金丝雀发布(Canary Release)
核心思路:同时运行两个版本的 Deployment,通过控制副本比例来控制流量分配。
```yaml
# 主 Deployment:稳定版本,占 90% 流量
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-stable
spec:
replicas: 9 # 9 个副本
selector:
matchLabels:
app: myapp
track: stable
template:
metadata:
labels:
app: myapp
track: stable # 核心标签 app: myapp 相同,Service 可以选中
spec:
containers:
- name: app
image: myapp:v1.0
---
# 金丝雀 Deployment:新版本,占 10% 流量
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1 # 1 个副本
selector:
matchLabels:
app: myapp
track: canary
template:
metadata:
labels:
app: myapp
track: canary
spec:
containers:
- name: app
image: myapp:v2.0
```
```yaml
# Service 通过 app: myapp 同时选中两个 Deployment 的 Pod
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
selector:
app: myapp # 不指定 track,两个版本都会被选中
ports:
- port: 80
targetPort: 8080
```
流量分配:9 个旧版本 Pod + 1 个新版本 Pod = 约 10% 流量到达新版本。验证无误后,逐步调整副本比例(如 `canary: 5, stable: 5`),最终全部切换到新版本。
```mermaid
graph LR
Client --> Service
Service -->|~90%| Pod1["Pod v1.0 x9"]
Service -->|~10%| Pod2["Pod v2.0 x1"]
```
### 蓝绿部署(Blue-Green Deployment)
核心思路:同时运行蓝(当前版本)和绿(新版本)两套完整的 Deployment,通过切换 Service 的 selector 来瞬间完成流量切换。
```yaml
# 蓝色 Deployment(当前生产版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: myapp:v1.0
---
# 绿色 Deployment(新版本,先部署但不接收流量)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: myapp:v2.0
```
```yaml
# Service:切换 selector.version 即可瞬间切换流量
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
selector:
app: myapp
version: blue # 当前指向蓝色,切换为 green 即完成上线
ports:
- port: 80
targetPort: 8080
```
```bash
# 切换流量到绿色版本
kubectl patch service myapp-svc -p '{"spec":{"selector":{"version":"green"}}}'
# 回滚:切换回蓝色版本
kubectl patch service myapp-svc -p '{"spec":{"selector":{"version":"blue"}}}'
```
蓝绿部署的优点是切换瞬间完成(无中间状态),缺点是需要双倍资源。适合对上线/回滚速度要求极高的场景。
## Pod 模板字段详解
`spec.template.spec` 是 Pod 模板的核心,以下是常用字段的逐一说明:
```yaml
spec:
template:
metadata:
labels: # Pod 标签,用于 Service Selector 和 ReplicaSet 匹配
app: myapp
version: v1
annotations: # 非标识性元数据,供工具或控制器使用
kubernetes.io/change-cause: "初始部署"
spec:
# ---- 容器定义 ----
containers:
- name: app # 容器名称,Pod 内唯一
image: myapp:v1.0 # 镜像地址
imagePullPolicy: IfNotPresent # Always / IfNotPresent / Never
ports:
- containerPort: 8080 # 容器监听端口(声明性质,不强制)
env: # 环境变量
- name: APP_ENV
value: "production"
- name: DB_PASSWORD
valueFrom:
secretKeyRef: # 从 Secret 读取敏感信息
name: db-secret
key: password
resources: # 资源请求与限制
requests: # 调度依据:节点至少需要这么多资源
cpu: 100m
memory: 128Mi
limits: # 上限:超出会被 OOM Kill 或 CPU 限流
cpu: 500m
memory: 256Mi
readinessProbe: # 就绪探针:决定 Pod 是否接收流量
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe: # 存活探针:失败则重启容器
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
startupProbe: # 启动探针:慢启动应用专用,通过前忽略 liveness
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
# ---- 初始化容器 ----
initContainers: # 在主容器启动前顺序执行
- name: init-db-migration
image: myapp:v1.0
command: ["./migrate.sh"]
# ---- 卷挂载 ----
volumes:
- name: config-vol
configMap:
name: app-config # 挂载 ConfigMap 作为文件
- name: data-vol
emptyDir: {} # 临时卷,Pod 删除后数据丢失
# ---- 调度相关 ----
nodeSelector: # 简单节点选择
disk: ssd
affinity: # 高级亲和性规则
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values: ["linux"]
tolerations: # 容忍污点
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
# ---- 其他 ----
terminationGracePeriodSeconds: 30 # 优雅终止等待时间
serviceAccountName: myapp-sa # 使用的 ServiceAccount
```
> [!tip] imagePullPolicy 最佳实践
> - 使用 `:latest` 标签时,必须设置 `imagePullPolicy: Always`,否则可能使用本地缓存的旧镜像
> - 使用固定版本标签(如 `:v1.2.3`)时,`IfNotPresent` 更高效,避免重复拉取
> - `Never` 仅用于本地开发环境(如 minikube 中直接使用本地构建的镜像)
## 常见陷阱与最佳实践
### 更新卡住排查
滚动更新卡住是常见问题,通常由以下原因导致:
```bash
# 1. 查看 Deployment 状态
kubectl rollout status deployment nginx-deploy
# 可能输出:Waiting for rollout to finish: 2 out of 4 new replicas have been updated...
# 2. 查看 Deployment 的 Conditions
kubectl get deployment nginx-deploy -o yaml | grep -A 20 conditions:
# 常见条件:
# - Progressing: False(更新未推进)
# - Available: True/False(是否有足够可用 Pod)
# 3. 查看新 ReplicaSet 的事件
kubectl describe rs nginx-deploy-xxxxxx # 查看新 RS 的 Events
# 常见原因:
# - FailedScheduling:资源不足,没有节点能满足 requests
# - ImagePullBackOff:镜像拉取失败(镜像名错、私有仓库无凭证)
# - CrashLoopBackOff:新容器启动后立即崩溃
# 4. 查看 Pod 事件
kubectl get pods -l app=nginx --sort-by=.metadata.creationTimestamp
kubectl describe pod nginx-deploy-xxxxxx-yyyyy
```
常见原因和解决方案:
| 症状 | 原因 | 解决方案 |
|------|------|---------|
| ImagePullBackOff | 镜像不存在或无权限 | 检查镜像名称、imagePullSecrets |
| CrashLoopBackOff | 应用启动失败 | 查看 Pod 日志 `kubectl logs` |
| Pending | 资源不足或节点不满足约束 | 检查 `kubectl describe pod` 中的 Events |
| readinessProbe 一直失败 | 健康检查路径或端口错误 | 确认探针配置与应用实际端口一致 |
> [!warning] 超时回滚
> Deployment 有一个 `progressDeadlineSeconds` 参数(默认 600 秒),如果更新在该时间内未完成,Deployment 会标记为 `Progressing=False`。注意:这**不会自动回滚**,只是标记状态。需要手动执行 `kubectl rollout undo` 或编写自动化脚本。
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
progressDeadlineSeconds: 300 # 5 分钟内未完成更新则标记失败
minReadySeconds: 10 # Pod Ready 后等待 10 秒才视为 Available
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26
```
### imagePullPolicy 导致的镜像缓存问题
```bash
# 场景:修改了 YAML 中的 image 字段但没改 tag,apply 后 Pod 没有更新
# 原因:imagePullPolicy 默认为 IfNotPresent,本地已有旧镜像就不会重新拉取
# 解决方案 1:始终使用不同的 tag(推荐)
image: myapp:v1.0.1 # 而不是 myapp:latest
# 解决方案 2:强制设置 imagePullPolicy
imagePullPolicy: Always
# 解决方案 3:使用 SHA256 digest(最精确)
image: myapp@sha256:abc123...
```
### Deployment vs StatefulSet 选择
| 特性 | Deployment | StatefulSet |
|------|-----------|-------------|
| Pod 名称 | 随机(`nginx-5d6b8f7c9-abc12`) | 有序(`web-0`, `web-1`, `web-2`) |
| Pod 启动顺序 | 并行 | 有序(0 → 1 → 2) |
| Pod 终止顺序 | 并行(默认) | 逆序(2 → 1 → 0) |
| 网络标识 | 不稳定 | 稳定(`web-0.ng-svc`) |
| 持久存储 | 共享或无 | 每个 Pod 独立 PVC |
| 适用场景 | 无状态服务 | 有状态服务(数据库、MQ、ZooKeeper) |
| 滚动更新 | 替换 Pod | 逐个更新 |
> [!info] 选择原则
> 如果你的应用满足以下任意条件,应考虑 StatefulSet:
> - 需要稳定的网络标识(如 ZooKeeper 集群节点互相发现)
> - 需要持久化的、与 Pod 绑定的存储(如 MySQL 数据目录)
> - 需要有序的部署/扩缩/更新
>
> 其余场景一律使用 Deployment。
### 其他最佳实践
1. **始终配置资源请求和限制**:没有 requests 的 Pod 会被调度器视为零消耗,可能导致多个 Pod 被调度到同一节点,引发资源争抢。
2. **始终配置 readinessProbe**:没有就绪探针,新 Pod 创建后立即被标记为 Ready,流量可能打到未初始化完成的 Pod。
3. **不要直接管理 Deployment 创建的 ReplicaSet**:RS 的生命周期由 Deployment 控制器管理,手动修改 RS(如 scale)会被 Deployment 覆盖。
4. **使用 `kubectl apply` 而非 `kubectl create`**:apply 支持声明式管理,可以幂等执行,适合 GitOps 工作流。
5. **合理设置 minReadySeconds**:该参数让 Pod Ready 后再等待一段时间才被视为 Available,可以用来检测"启动后很快崩溃"的场景。
```yaml
# 推荐的最小 Deployment 模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
revisionHistoryLimit: 5
progressDeadlineSeconds: 300
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 保证更新期间始终有足够的可用 Pod
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
terminationGracePeriodSeconds: 30
containers:
- name: myapp
image: myapp:v1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
```
## 延伸阅读
- [[k8s-03-pod]] — Pod 的生命周期、调度机制、资源管理
- [[k8s-05-service-and-networking]] — Service 类型、Ingress、网络策略
- [Kubernetes 官方文档 - Deployments](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/)
- [Kubernetes 官方文档 - ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/)
- [Kubernetes 官方文档 - HPA](https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/)