部署指南-2A-集群K8s-阿里云ACK方案

集群服务 Kubernetes 部署 - 阿里云 ACK 方案

适用场景:企业级生产环境、高可用、自动扩缩容、微服务架构

本文档:使用阿里云 ACK(托管 Kubernetes)部署完整应用


目录

  1. 核心概念
  2. 整体架构
  3. 准备工作
  4. 创建ACK集群
  5. 配置kubectl
  6. 创建镜像仓库
  7. 部署中间件
  8. 部署应用
  9. 配置Ingress和HTTPS
  10. CI/CD自动化部署
  11. 监控告警
  12. 金丝雀发布
  13. 常见问题

一、核心概念

1.1 什么是 Kubernetes(K8s)?

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              K8s 是什么?                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  K8s = Kubernetes(K + 8个字母 + s)= 容器编排平台                              │
│                                                                                 │
│  解决什么问题?                                                                  │
│  ─────────────────────────────────────────────────────────────────              │
│                                                                                 │
│  传统部署:                           K8s 部署:                                │
│  • 应用挂了 → 人工发现 → 人工重启    • 应用挂了 → 自动发现 → 自动重启          │
│  • 流量暴增 → 人工扩容 → 1小时       • 流量暴增 → 自动扩容 → 30秒              │
│  • 版本更新 → 停服维护 → 用户抱怨    • 版本更新 → 滚动更新 → 零停机            │
│  • 服务器宕机 → 用户无法访问         • 服务器宕机 → 自动迁移 → 用户无感知       │
│                                                                                 │
│  核心能力:                                                                      │
│  ─────────────────────────────────────────────────────────────────              │
│  • 自动调度:决定容器运行在哪台服务器                                            │
│  • 自动扩缩:根据负载自动增减容器数量                                            │
│  • 自动恢复:容器挂了自动重启                                                    │
│  • 滚动更新:不停服更新版本                                                      │
│  • 服务发现:自动找到服务地址                                                    │
│  • 负载均衡:流量均匀分配                                                        │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

1.2 什么是 ACK?

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              ACK 是什么?                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ACK = Alibaba Cloud Kubernetes = 阿里云托管的 K8s 服务                         │
│                                                                                 │
│  自建 K8s vs ACK 托管:                                                         │
│  ─────────────────────────────────────────────────────────────────              │
│                                                                                 │
│  ┌─────────────────────┬────────────────────┬────────────────────┐             │
│  │       对比项         │      自建 K8s      │      ACK 托管       │             │
│  ├─────────────────────┼────────────────────┼────────────────────┤             │
│  │ Master 节点          │ 你搭建、你维护      │ 阿里云管理(免费)  │             │
│  │ 高可用               │ 你配置 3 个 Master │ 阿里云保证          │             │
│  │ 版本升级             │ 你手动升级         │ 控制台一键升级      │             │
│  │ 安全补丁             │ 你自己打           │ 阿里云自动打        │             │
│  │ 故障处理             │ 你 7×24 值班       │ 阿里云 SLA 保障     │             │
│  │ 学习成本             │ ⭐⭐⭐⭐⭐            │ ⭐⭐                  │             │
│  │ 运维成本             │ 高                 │ 低                  │             │
│  │ 费用                 │ Master 服务器费    │ Master 免费         │             │
│  └─────────────────────┴────────────────────┴────────────────────┘             │
│                                                                                 │
│  结论:90% 场景用 ACK 托管版,省心省力!                                        │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

1.3 K8s 核心组件

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           K8s 架构图                                            │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   ┌───────────────────────────────────────────────────────────────────────┐    │
│   │                    控制面 Control Plane(ACK 托管)                    │    │
│   │                                                                       │    │
│   │  ┌─────────────┐  ┌─────────────┐  ┌───────────────┐  ┌───────────┐  │    │
│   │  │ API Server  │  │  Scheduler  │  │  Controller   │  │   etcd    │  │    │
│   │  │             │  │             │  │   Manager     │  │           │  │    │
│   │  │ 所有请求入口 │  │ 调度Pod到   │  │ 管理各种     │  │ 存储所有  │  │    │
│   │  │ kubectl命令 │  │ 哪个节点    │  │ 控制器       │  │ 集群状态  │  │    │
│   │  └─────────────┘  └─────────────┘  └───────────────┘  └───────────┘  │    │
│   │                                                                       │    │
│   └───────────────────────────────────────────────────────────────────────┘    │
│                                       │                                         │
│                                       ▼                                         │
│   ┌───────────────────────────────────────────────────────────────────────┐    │
│   │                    工作节点 Worker Node(你管理)                       │    │
│   │                                                                       │    │
│   │  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────────┐   │    │
│   │  │   kubelet   │  │ kube-proxy  │  │    Container Runtime        │   │    │
│   │  │             │  │             │  │                             │   │    │
│   │  │ 管理本节点   │  │ 管理网络    │  │ 运行容器(containerd)      │   │    │
│   │  │ 的Pod       │  │ 规则        │  │                             │   │    │
│   │  └─────────────┘  └─────────────┘  └─────────────────────────────┘   │    │
│   │                                                                       │    │
│   │  ┌─────────────────────────────────────────────────────────────────┐ │    │
│   │  │                          Pods                                   │ │    │
│   │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐           │ │    │
│   │  │  │ Pod 1   │  │ Pod 2   │  │ Pod 3   │  │ Pod 4   │           │ │    │
│   │  │  │ 后端    │  │ 后端    │  │ 前端    │  │ 前端    │           │ │    │
│   │  │  └─────────┘  └─────────┘  └─────────┘  └─────────┘           │ │    │
│   │  └─────────────────────────────────────────────────────────────────┘ │    │
│   └───────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

1.4 K8s 资源对象

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          K8s 核心资源对象                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ┌──────────────┬────────────────────────────────┬──────────────────────────┐  │
│  │    资源       │           是什么                │        什么时候用        │  │
│  ├──────────────┼────────────────────────────────┼──────────────────────────┤  │
│  │ Namespace    │ 命名空间,隔离资源              │ 区分环境(dev/test/prod)│  │
│  │ Pod          │ 最小部署单元,包含容器          │ 一般不直接创建           │  │
│  │ Deployment   │ 无状态应用部署                  │ Web服务、API(最常用)   │  │
│  │ StatefulSet  │ 有状态应用部署                  │ 数据库(建议用云服务)   │  │
│  │ Service      │ 服务发现,负载均衡              │ 暴露Pod访问入口          │  │
│  │ Ingress      │ HTTP/HTTPS入口网关              │ 对外暴露服务             │  │
│  │ ConfigMap    │ 配置信息                        │ 非敏感配置               │  │
│  │ Secret       │ 敏感信息                        │ 密码、密钥               │  │
│  │ PVC          │ 持久化存储声明                  │ 数据持久化               │  │
│  │ HPA          │ 自动扩缩容                      │ 根据CPU/内存自动扩缩     │  │
│  └──────────────┴────────────────────────────────┴──────────────────────────┘  │
│                                                                                 │
│  资源关系图:                                                                    │
│  ─────────────────────────────────────────────────────────────────              │
│                                                                                 │
│      用户请求                                                                   │
│          │                                                                      │
│          ▼                                                                      │
│      Ingress(入口网关,处理HTTPS)                                             │
│          │                                                                      │
│          ▼                                                                      │
│      Service(服务发现,负载均衡)                                              │
│          │                                                                      │
│          ▼                                                                      │
│      Deployment(管理Pod副本数、更新策略)                                      │
│          │                                                                      │
│          ▼                                                                      │
│      Pod(运行容器)                                                            │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

二、整体架构

┌─────────────────────────────────────────────────────────────────────────────────┐
│                        企业级 ACK 部署架构                                       │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   互联网用户                                                                     │
│       │                                                                         │
│       │ HTTPS                                                                   │
│       ▼                                                                         │
│   ┌─────────────────────────────────────────────────────────────────────────┐  │
│   │                    阿里云 SLB(负载均衡)                                 │  │
│   │                    公网IP + HTTPS证书                                    │  │
│   └─────────────────────────────────────────────────────────────────────────┘  │
│       │                                                                         │
│       ▼                                                                         │
│   ┌─────────────────────────────────────────────────────────────────────────┐  │
│   │                    Nginx Ingress Controller                              │  │
│   │                    路由分发、限流、熔断                                   │  │
│   └─────────────────────────────────────────────────────────────────────────┘  │
│       │                                                                         │
│       ├────────────────────────┬────────────────────────┐                      │
│       ▼                        ▼                        ▼                      │
│   ┌─────────────┐        ┌─────────────┐        ┌─────────────┐               │
│   │  前端 Pod   │        │  后端 Pod   │        │  后端 Pod   │               │
│   │  ×2 副本    │        │  ×3 副本    │        │  (自动扩缩) │               │
│   └─────────────┘        └─────────────┘        └─────────────┘               │
│                                  │                                              │
│                                  ▼                                              │
│   ┌─────────────────────────────────────────────────────────────────────────┐  │
│   │                         阿里云云服务                                      │  │
│   │  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐               │  │
│   │  │  RDS MySQL    │  │  Redis        │  │  OSS 存储     │               │  │
│   │  │  主从高可用    │  │  集群版       │  │  静态文件     │               │  │
│   │  └───────────────┘  └───────────────┘  └───────────────┘               │  │
│   └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

三、准备工作

3.1 注册阿里云账号

步骤:
1. 访问 https://www.aliyun.com
2. 点击「免费注册」
3. 完成实名认证(企业/个人)
4. 充值(建议 500 元起)

3.2 开通必要服务

服务入口用途
ACKhttps://cs.console.aliyun.comK8s 集群
ACRhttps://cr.console.aliyun.com镜像仓库
RDShttps://rdsnext.console.aliyun.comMySQL 数据库
Redishttps://kvstore.console.aliyun.com缓存
SLBhttps://slb.console.aliyun.com负载均衡
域名https://dc.console.aliyun.com域名管理

四、创建ACK集群

4.1 进入创建页面

路径:https://cs.console.aliyun.com → 集群列表 → 创建集群

4.2 选择集群类型

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           选择集群类型                                           │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ● ACK 托管版(推荐)                                                           │
│    └─ Master 免费托管,只需管理 Worker 节点                                      │
│                                                                                 │
│  ○ ACK 专有版                                                                   │
│    └─ 自建 Master,需要更多服务器                                               │
│                                                                                 │
│  ○ ACK Serverless                                                               │
│    └─ 无需管理节点,按 Pod 收费                                                 │
│                                                                                 │
│  【选择】ACK 托管版                                                              │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

4.3 集群配置

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           集群基础配置                                           │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  集群名称:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ prod-cluster                                                             │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│  【说明】命名规范:环境-cluster,如 dev-cluster、test-cluster、prod-cluster     │
│                                                                                 │
│  地域和可用区:                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 中国(香港)                    ← 【选择】免备案                          │   │
│  │ 华东1(杭州)                   ← 备案后可选,访问快                       │   │
│  │ 华北2(北京)                   ← 备案后可选                              │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  Kubernetes 版本:                                                               │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 1.28.x(最新稳定版)            ← 【选择】                                │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  专有网络:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ● 新建专有网络                  ← 【选择】首次使用                        │   │
│  │ ○ 使用已有专有网络              ← 有现成 VPC 可选                         │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  Pod 网络 CIDR:                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 172.16.0.0/16                   ← 【默认】Pod 使用的 IP 段               │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  Service CIDR:                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 10.96.0.0/16                    ← 【默认】Service 使用的 IP 段           │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

4.4 Worker 节点配置

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           Worker 节点配置                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  节点数量:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 3                               ← 【推荐】生产环境最少 3 个               │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│  【说明】                                                                        │
│  • 1 个节点:不推荐,无高可用                                                   │
│  • 2 个节点:可用,但扩展性差                                                   │
│  • 3 个节点:推荐,高可用                                                       │
│  • 5+ 节点:大型项目                                                            │
│                                                                                 │
│  实例规格:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ecs.c6.xlarge(4核8G)          ← 【推荐】生产环境起步配置                │   │
│  │ ecs.c6.2xlarge(8核16G)        ← 中大型项目                              │   │
│  │ ecs.g6.2xlarge(8核32G)        ← 内存密集型                              │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│  【说明】c6 = 计算型,g6 = 通用型,r6 = 内存型                                  │
│                                                                                 │
│  系统盘:                                                                        │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ESSD 云盘 120GB                 ← 【推荐】SSD 性能好                      │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  登录方式:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ● 密钥对                        ← 【推荐】更安全                          │   │
│  │ ○ 自定义密码                    ← 简单场景                                │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

4.5 组件配置

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           组件配置                                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  Ingress:                                                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ☑ 安装 Nginx Ingress Controller   ← 【必选】处理 HTTP/HTTPS 入口         │   │
│  │ ☐ 安装 ALB Ingress Controller     ← 可选,使用 ALB 负载均衡              │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  监控:                                                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ☑ 安装 Prometheus 监控           ← 【必选】监控指标                       │   │
│  │ ☑ 安装 metrics-server            ← 【必选】HPA 自动扩缩需要               │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  日志:                                                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ ☑ 安装日志服务组件               ← 【推荐】统一日志收集                   │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

4.6 确认创建

点击「创建集群」→ 等待 10-15 分钟 → 集群状态变为「运行中」

五、配置kubectl

5.1 安装 kubectl

Windows

# 下载 kubectl
curl -LO "https://dl.k8s.io/release/v1.28.0/bin/windows/amd64/kubectl.exe"

# 移动到 PATH 目录(如 C:\Windows\System32)
move kubectl.exe C:\Windows\System32\

# 验证
kubectl version --client

Mac

brew install kubectl
kubectl version --client

Linux

curl -LO "https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl /usr/local/bin/
kubectl version --client

5.2 获取 kubeconfig

路径:ACK 控制台 → 集群列表 → 点击集群名 → 连接信息 → 公网访问

5.3 保存配置

# 创建目录
mkdir -p ~/.kube

# 将复制的内容保存到 config 文件
# Windows: C:\Users\你的用户名\.kube\config
# Mac/Linux: ~/.kube/config

config 文件内容示例

apiVersion: v1
kind: Config
clusters:
- cluster:
    server: https://xxx.xxx.xxx.xxx:6443  # API Server 地址
    certificate-authority-data: LS0tLS1C...  # CA 证书
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1C...  # 客户端证书
    client-key-data: LS0tLS1C...  # 客户端密钥

5.4 验证连接

# 查看节点
kubectl get nodes

# 预期输出:
# NAME                      STATUS   ROLES    AGE   VERSION
# cn-hongkong.10.0.1.100   Ready    <none>   10m   v1.28.0
# cn-hongkong.10.0.1.101   Ready    <none>   10m   v1.28.0
# cn-hongkong.10.0.1.102   Ready    <none>   10m   v1.28.0

六、创建镜像仓库

6.1 进入 ACR 控制台

路径:https://cr.console.aliyun.com

6.2 创建个人版实例(免费)

路径:实例列表 → 创建个人版实例

6.3 创建命名空间

路径:仓库管理 → 命名空间 → 创建命名空间

命名空间名称:myproject
# 【说明】一般用项目名或公司名

6.4 创建镜像仓库

路径:仓库管理 → 镜像仓库 → 创建镜像仓库

仓库名称:backend
命名空间:myproject
仓库类型:私有
代码源:本地仓库

# 创建完成后,完整镜像地址为:
# registry.cn-hongkong.aliyuncs.com/myproject/backend

6.5 配置访问凭证

路径:访问凭证 → 设置固定密码

用户名:阿里云账号全名
密码:【设置一个】

6.6 Docker 登录

# 登录镜像仓库
docker login registry.cn-hongkong.aliyuncs.com
# 输入用户名和密码

# 构建并推送镜像
docker build -t registry.cn-hongkong.aliyuncs.com/myproject/backend:v1.0.0 .
docker push registry.cn-hongkong.aliyuncs.com/myproject/backend:v1.0.0

七、部署中间件

7.1 推荐使用云服务

┌─────────────────────────────────────────────────────────────────────────────────┐
│                        中间件选择建议                                            │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ┌──────────────┬────────────────────┬────────────────────┬──────────────────┐ │
│  │    中间件     │      K8s 部署       │      云服务         │      推荐        │ │
│  ├──────────────┼────────────────────┼────────────────────┼──────────────────┤ │
│  │ MySQL        │ 需维护、易丢数据    │ RDS 高可用、自动备份│ ⭐ 云服务        │ │
│  │ Redis        │ 单节点风险         │ 集群版、自动扩容   │ ⭐ 云服务        │ │
│  │ RabbitMQ     │ 可以               │ 云消息队列         │ 看需求           │ │
│  │ ElasticSearch│ 资源消耗大         │ 云搜索服务         │ ⭐ 云服务        │ │
│  └──────────────┴────────────────────┴────────────────────┴──────────────────┘ │
│                                                                                 │
│  【结论】数据库类用云服务!省心、安全、有保障                                     │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

7.2 购买 RDS MySQL

路径:https://rdsnext.console.aliyun.com → 创建实例

配置推荐:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 地域:           中国(香港)       ← 与 ACK 同地域                              │
│ 数据库类型:     MySQL 8.0                                                       │
│ 系列:           高可用版           ← 生产环境必选                               │
│ 存储类型:       ESSD 云盘                                                       │
│ 规格:           2核4G              ← 根据需求调整                               │
│ 存储空间:       50GB               ← 根据需求调整                               │
└─────────────────────────────────────────────────────────────────────────────────┘

创建后:
1. 设置数据库账号密码
2. 创建数据库
3. 配置白名单(添加 ACK 的 VPC 网段)
4. 记录连接地址:rm-xxx.mysql.rds.aliyuncs.com

7.3 购买 Redis

路径:https://kvstore.console.aliyun.com → 创建实例

配置推荐:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 地域:           中国(香港)       ← 与 ACK 同地域                              │
│ 版本:           Redis 7.0                                                       │
│ 架构:           集群版             ← 生产环境推荐                               │
│ 规格:           1GB                ← 根据需求调整                               │
└─────────────────────────────────────────────────────────────────────────────────┘

创建后:
1. 设置密码
2. 配置白名单
3. 记录连接地址:r-xxx.redis.rds.aliyuncs.com

八、部署应用

8.1 创建命名空间

文件位置:本地任意目录,如 ~/k8s/namespace.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:namespace.yaml
# 作用:创建命名空间,隔离不同环境/项目的资源
# 执行:kubectl apply -f namespace.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: v1
# ┌─────────────────────────────────────────────────────────────────────────────┐
# │ apiVersion: API 版本                                                        │
# │                                                                             │
# │ 常用版本:                                                                   │
# │ • v1           → 核心资源(Pod、Service、ConfigMap、Secret、Namespace)     │
# │ • apps/v1      → 应用资源(Deployment、StatefulSet、DaemonSet)            │
# │ • networking.k8s.io/v1 → 网络资源(Ingress、NetworkPolicy)                │
# │ • batch/v1     → 批处理资源(Job、CronJob)                                │
# │                                                                             │
# │ 如何知道用哪个版本?                                                         │
# │ kubectl api-resources | grep Deployment                                     │
# │ # 输出:deployments   apps/v1   true   Deployment                          │
# └─────────────────────────────────────────────────────────────────────────────┘

kind: Namespace
# ┌─────────────────────────────────────────────────────────────────────────────┐
# │ kind: 资源类型,首字母大写                                                   │
# └─────────────────────────────────────────────────────────────────────────────┘

metadata:
  name: prod
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ name: 命名空间名称                                                       │
  # │                                                                          │
  # │ 命名规范:                                                                │
  # │ • 只能用小写字母、数字、连字符(-)                                       │
  # │ • 不能用下划线、空格                                                      │
  # │                                                                          │
  # │ 【改】根据环境修改:                                                       │
  # │ • dev   → 开发环境                                                       │
  # │ • test  → 测试环境                                                       │
  # │ • staging → 预发布环境                                                   │
  # │ • prod  → 生产环境                                                       │
  # │ • myproject-prod → 项目名-环境                                           │
  # └─────────────────────────────────────────────────────────────────────────┘
  labels:
    env: production
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ labels: 标签,用于分类和选择资源                                      │
    # │                                                                      │
    # │ 常用标签:                                                            │
    # │ • env: production/staging/test/dev                                  │
    # │ • team: backend/frontend/devops                                     │
    # │ • app: myapp                                                        │
    # └─────────────────────────────────────────────────────────────────────┘

执行

kubectl apply -f namespace.yaml
# 输出:namespace/prod created

# 验证
kubectl get ns

8.2 创建 Secret

文件位置~/k8s/secret.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:secret.yaml
# 作用:存储敏感信息(数据库密码、API密钥等)
# 执行:kubectl apply -f secret.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ name: Secret 名称                                                        │
  # │ 【改】可以改成:mysql-secret、redis-secret、app-secret 等                │
  # └─────────────────────────────────────────────────────────────────────────┘
  namespace: prod
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ namespace: 所属命名空间                                                  │
  # │ 【改】与你的 Deployment 在同一个命名空间                                 │
  # └─────────────────────────────────────────────────────────────────────────┘

type: Opaque
# ┌─────────────────────────────────────────────────────────────────────────────┐
# │ type: Secret 类型                                                           │
# │                                                                             │
# │ 类型说明:                                                                   │
# │ • Opaque                      → 通用类型,存储任意数据(最常用)            │
# │ • kubernetes.io/tls           → TLS 证书(包含 tls.crt 和 tls.key)        │
# │ • kubernetes.io/dockerconfigjson → Docker 镜像仓库凭证                     │
# │ • kubernetes.io/basic-auth    → 用户名密码                                 │
# │ • kubernetes.io/ssh-auth      → SSH 密钥                                   │
# └─────────────────────────────────────────────────────────────────────────────┘

stringData:
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ stringData: 明文数据(会自动 Base64 编码存储)                            │
  # │                                                                          │
  # │ 也可以用 data 字段存储已编码的数据:                                      │
  # │ data:                                                                    │
  # │   MYSQL_PASSWORD: TXlQYXNzd29yZDEyMyE=  # base64 编码                   │
  # │                                                                          │
  # │ 编码命令:echo -n "MyPassword123!" | base64                              │
  # │ 解码命令:echo "TXlQYXNzd29yZDEyMyE=" | base64 -d                        │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  MYSQL_HOST: "rm-xxx.mysql.rds.aliyuncs.com"
  # 【改】你的 RDS 连接地址
  
  MYSQL_PORT: "3306"
  # 【改】一般不用改,MySQL 默认 3306
  
  MYSQL_DATABASE: "mydb"
  # 【改】你的数据库名
  
  MYSQL_USERNAME: "root"
  # 【改】数据库用户名
  
  MYSQL_PASSWORD: "MyPassword123!"
  # 【改】数据库密码,使用强密码!
  
  REDIS_HOST: "r-xxx.redis.rds.aliyuncs.com"
  # 【改】你的 Redis 连接地址
  
  REDIS_PORT: "6379"
  # 【改】一般不用改,Redis 默认 6379
  
  REDIS_PASSWORD: "RedisPassword123!"
  # 【改】Redis 密码

执行

kubectl apply -f secret.yaml
# 输出:secret/app-secrets created

# 验证(不会显示明文)
kubectl get secret app-secrets -n prod
kubectl describe secret app-secrets -n prod

8.3 创建 ConfigMap

文件位置~/k8s/configmap.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:configmap.yaml
# 作用:存储非敏感配置(日志级别、功能开关等)
# 执行:kubectl apply -f configmap.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: prod

data:
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ data: 配置数据,键值对形式                                               │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  # 简单键值对
  LOG_LEVEL: "INFO"
  # 【改】日志级别:DEBUG、INFO、WARN、ERROR
  
  SPRING_PROFILES_ACTIVE: "prod"
  # 【改】Spring 环境:dev、test、prod
  
  SERVER_PORT: "8080"
  # 一般不改,应用端口
  
  # 配置文件内容
  application-prod.yml: |
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ 用 | 符号可以存储多行文本(整个配置文件)                             │
    # └─────────────────────────────────────────────────────────────────────┘
    server:
      port: 8080
    logging:
      level:
        root: INFO
        com.yourcompany: DEBUG

执行

kubectl apply -f configmap.yaml

8.4 创建 Deployment

文件位置~/k8s/backend-deployment.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:backend-deployment.yaml
# 作用:部署后端应用,管理 Pod 副本、更新策略、资源限制
# 执行:kubectl apply -f backend-deployment.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ name: 资源名称(唯一标识)                                               │
  # │                                                                          │
  # │ 作用:                                                                    │
  # │ • 给资源一个唯一标识,用于 kubectl 命令操作                              │
  # │ • kubectl get deployment backend                                        │
  # │                                                                          │
  # │ 命名规则:                                                                │
  # │ • 只能用:小写字母、数字、连字符(-)                                    │
  # │ • 不能用:下划线、空格、大写字母                                         │
  # │ • 最长 63 个字符                                                         │
  # │ • 必须以字母或数字开头和结尾                                             │
  # │                                                                          │
  # │ 举例:                                                                    │
  # │ ✅ backend、user-service、order-api-v2                                  │
  # │ ❌ Backend(大写)、user_service(下划线)                               │
  # │                                                                          │
  # │ 【改】根据服务改:backend、frontend、user-service、order-service        │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  namespace: prod
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ namespace: 命名空间(逻辑隔离)                                          │
  # │                                                                          │
  # │ 作用:                                                                    │
  # │ • 逻辑隔离:把不同项目/环境的资源分开                                    │
  # │ • 权限控制:给不同团队分配不同命名空间的权限                             │
  # │ • 资源配额:限制每个命名空间使用的资源                                   │
  # │                                                                          │
  # │ 类比:命名空间 = 文件夹,资源 = 文件                                     │
  # │ • 不同文件夹可以有同名文件                                               │
  # │ • prod/backend 和 dev/backend 互不冲突                                  │
  # │                                                                          │
  # │ 常用命名空间:                                                            │
  # │ • default     → 默认(不指定时用这个)                                   │
  # │ • kube-system → K8s 系统组件                                             │
  # │ • prod        → 生产环境                                                 │
  # │ • dev         → 开发环境                                                 │
  # │ • test        → 测试环境                                                 │
  # │                                                                          │
  # │ 【改】根据环境改:dev、test、staging、prod                               │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  labels:
    app: backend
    version: v1
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ labels: 标签(分类和选择)                                               │
  # │                                                                          │
  # │ 作用:                                                                    │
  # │ • 分类资源:给资源打标签,方便筛选                                       │
  # │ • 关联资源:Service 通过 labels 找到对应的 Pod                          │
  # │ • 批量操作:按标签批量删除/查询                                          │
  # │                                                                          │
  # │ 格式:键值对(key: value)                                               │
  # │                                                                          │
  # │ 常用标签:                                                                │
  # │ • app: backend          → 应用名                                        │
  # │ • version: v1           → 版本                                          │
  # │ • env: prod             → 环境                                          │
  # │ • team: backend-team    → 团队                                          │
  # │                                                                          │
  # │ ════════════════════════════════════════════════════════════════════════│
  # │ 标签匹配规则(重要!)                                                    │
  # │ ════════════════════════════════════════════════════════════════════════│
  # │                                                                          │
  # │ Q: key 和 value 必须同时相等才算匹配吗?                                 │
  # │ A: 取决于匹配方式,有三种:                                              │
  # │                                                                          │
  # │ 1️⃣ 精确匹配(Equality-based):key 和 value 必须完全相等                │
  # │    ──────────────────────────────────────────────────────────────────   │
  # │    selector:                                                            │
  # │      matchLabels:                                                       │
  # │        app: backend        # app 必须等于 backend                       │
  # │        version: v1         # 且 version 必须等于 v1                     │
  # │                                                                          │
  # │    Pod 标签必须同时满足所有条件才匹配:                                   │
  # │    ✅ {app: backend, version: v1}           → 匹配                      │
  # │    ❌ {app: backend, version: v2}           → 不匹配(version不对)     │
  # │    ❌ {app: frontend, version: v1}          → 不匹配(app不对)         │
  # │    ❌ {app: backend}                        → 不匹配(缺少version)     │
  # │                                                                          │
  # │ 2️⃣ 集合匹配(Set-based):更灵活的匹配方式                              │
  # │    ──────────────────────────────────────────────────────────────────   │
  # │    selector:                                                            │
  # │      matchExpressions:                                                  │
  # │      - key: app                                                         │
  # │        operator: In                                                     │
  # │        values: [backend, api]     # app 是 backend 或 api              │
  # │      - key: version                                                     │
  # │        operator: NotIn                                                  │
  # │        values: [v0]               # version 不是 v0                     │
  # │      - key: env                                                         │
  # │        operator: Exists           # 只要有 env 标签就行                 │
  # │                                                                          │
  # │    operator 可选值:                                                      │
  # │    • In        → 值在列表中                                             │
  # │    • NotIn     → 值不在列表中                                           │
  # │    • Exists    → 只要有这个 key(不管 value)                           │
  # │    • DoesNotExist → 没有这个 key                                        │
  # │                                                                          │
  # │ 3️⃣ kubectl 命令行匹配                                                   │
  # │    ──────────────────────────────────────────────────────────────────   │
  # │    kubectl get pods -l app=backend              # 精确匹配              │
  # │    kubectl get pods -l app=backend,version=v1   # 多条件AND             │
  # │    kubectl get pods -l 'app in (backend,api)'   # 集合匹配              │
  # │    kubectl get pods -l 'env'                    # 存在性匹配            │
  # │    kubectl get pods -l '!env'                   # 不存在匹配            │
  # │                                                                          │
  # │ 总结:                                                                    │
  # │ • matchLabels:key 和 value 必须完全相等,多个标签是 AND 关系           │
  # │ • matchExpressions:更灵活,支持 In/NotIn/Exists 等操作                 │
  # └─────────────────────────────────────────────────────────────────────────┘

spec:
  # ════════════════════════════════════════════════════════════════════════════
  # spec: Deployment 的规格定义
  # ════════════════════════════════════════════════════════════════════════════
  
  replicas: 3
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ replicas: Pod 副本数                                                     │
  # │                                                                          │
  # │ 作用:指定运行多少个相同的 Pod 实例                                       │
  # │                                                                          │
  # │ 类型:整数                                                                │
  # │                                                                          │
  # │ 取值范围:0 ~ 无上限(受节点资源限制)                                    │
  # │                                                                          │
  # │ 常用配置:                                                                │
  # │ ┌────────────┬──────────┬──────────────────────────────────────────────┐│
  # │ │   环境      │  副本数   │               说明                          ││
  # │ ├────────────┼──────────┼──────────────────────────────────────────────┤│
  # │ │ 开发环境    │    1     │ 节省资源                                    ││
  # │ │ 测试环境    │    2     │ 基本高可用                                  ││
  # │ │ 预发布环境  │    2-3   │ 接近生产配置                                ││
  # │ │ 生产环境    │    3+    │ 保证高可用,至少 3 个                       ││
  # │ │ 高流量场景  │   10+    │ 根据压测结果设定                            ││
  # │ └────────────┴──────────┴──────────────────────────────────────────────┘│
  # │                                                                          │
  # │ 计算方法:                                                                │
  # │ • 副本数 = 预估 QPS / 单 Pod 承载 QPS                                   │
  # │ • 例:预估 1000 QPS,单 Pod 能承载 300 QPS                              │
  # │       → 1000 / 300 = 3.33 → 向上取整 = 4 个副本                        │
  # │ • 再加 1-2 个冗余,最终设置 5-6 个                                       │
  # │                                                                          │
  # │ 举例:                                                                    │
  # │ replicas: 1    # 开发环境,单副本                                        │
  # │ replicas: 3    # 生产环境,基本高可用                                    │
  # │ replicas: 10   # 高流量,10 个副本                                       │
  # │ replicas: 0    # 暂停服务(所有 Pod 会被删除)                           │
  # │                                                                          │
  # │ 【改】根据你的环境和流量调整                                             │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  selector:
    matchLabels:
      app: backend
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ selector: 选择器                                                         │
  # │                                                                          │
  # │ 作用:告诉 Deployment 管理哪些 Pod                                       │
  # │                                                                          │
  # │ ⚠️ 重要规则:                                                            │
  # │ • selector.matchLabels 必须与 template.metadata.labels 一致             │
  # │ • 否则 Deployment 无法找到并管理 Pod                                    │
  # │                                                                          │
  # │ 两种写法:                                                                │
  # │                                                                          │
  # │ 写法1:matchLabels(精确匹配,最常用)                                   │
  # │ ──────────────────────────────────────────────────────────────────────  │
  # │ selector:                                                                │
  # │   matchLabels:                                                           │
  # │     app: backend          # key=app,value=backend                      │
  # │     version: v1           # 多个标签是 AND 关系                         │
  # │                                                                          │
  # │ 写法2:matchExpressions(灵活匹配)                                      │
  # │ ──────────────────────────────────────────────────────────────────────  │
  # │ selector:                                                                │
  # │   matchExpressions:                                                      │
  # │   - key: app                                                             │
  # │     operator: In          # 操作符                                      │
  # │     values:                                                              │
  # │     - backend                                                            │
  # │     - api                 # app 是 backend 或 api                       │
  # │   - key: version                                                         │
  # │     operator: NotIn                                                      │
  # │     values:                                                              │
  # │     - v0                  # version 不是 v0                             │
  # │                                                                          │
  # │ operator 枚举值:                                                         │
  # │ ┌──────────────┬─────────────────────────────────────────────────────┐  │
  # │ │   操作符      │                    含义                             │  │
  # │ ├──────────────┼─────────────────────────────────────────────────────┤  │
  # │ │ In           │ 值在列表中(values 必填)                           │  │
  # │ │ NotIn        │ 值不在列表中(values 必填)                         │  │
  # │ │ Exists       │ 只要有这个 key(values 必须为空)                   │  │
  # │ │ DoesNotExist │ 没有这个 key(values 必须为空)                     │  │
  # │ └──────────────┴─────────────────────────────────────────────────────┘  │
  # │                                                                          │
  # │ 举例:                                                                    │
  # │ # 匹配 app=backend 或 app=api 的 Pod                                    │
  # │ selector:                                                                │
  # │   matchExpressions:                                                      │
  # │   - key: app                                                             │
  # │     operator: In                                                         │
  # │     values: [backend, api]                                               │
  # │                                                                          │
  # │ # 匹配有 env 标签的 Pod(不管值是什么)                                  │
  # │ selector:                                                                │
  # │   matchExpressions:                                                      │
  # │   - key: env                                                             │
  # │     operator: Exists                                                     │
  # └─────────────────────────────────────────────────────────────────────────┘
  
  strategy:
    type: RollingUpdate
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ strategy.type: 更新策略类型                                          │
    # │                                                                      │
    # │ 作用:定义如何更新 Pod                                               │
    # │                                                                      │
    # │ 枚举值(只有2个):                                                   │
    # │ ┌───────────────┬────────────────────────────────────────────────┐  │
    # │ │     类型       │                   说明                         │  │
    # │ ├───────────────┼────────────────────────────────────────────────┤  │
    # │ │ RollingUpdate │ 滚动更新(默认)                               │  │
    # │ │               │ • 逐步替换旧 Pod                               │  │
    # │ │               │ • 零停机                                       │  │
    # │ │               │ • 【生产环境必须用这个】                        │  │
    # │ ├───────────────┼────────────────────────────────────────────────┤  │
    # │ │ Recreate      │ 重建                                           │  │
    # │ │               │ • 先删除全部旧 Pod                             │  │
    # │ │               │ • 再创建全部新 Pod                             │  │
    # │ │               │ • ⚠️ 会停服!有一段时间无 Pod 可用             │  │
    # │ │               │ • 用于:单副本、不能多版本共存的应用           │  │
    # │ └───────────────┴────────────────────────────────────────────────┘  │
    # │                                                                      │
    # │ 举例:                                                                │
    # │ # 滚动更新(推荐)                                                   │
    # │ strategy:                                                            │
    # │   type: RollingUpdate                                                │
    # │   rollingUpdate:                                                     │
    # │     maxSurge: 1                                                      │
    # │     maxUnavailable: 0                                                │
    # │                                                                      │
    # │ # 重建(特殊场景)                                                   │
    # │ strategy:                                                            │
    # │   type: Recreate                                                     │
    # │   # 不需要 rollingUpdate 配置                                        │
    # └─────────────────────────────────────────────────────────────────────┘
    
    rollingUpdate:
      maxSurge: 1
      # ┌─────────────────────────────────────────────────────────────────┐
      # │ maxSurge: 最大浪涌数                                             │
      # │                                                                  │
      # │ 作用:更新时最多可以多创建几个 Pod                               │
      # │                                                                  │
      # │ 类型:整数 或 百分比字符串                                       │
      # │                                                                  │
      # │ 取值方式:                                                        │
      # │ ┌─────────────┬──────────────────────────────────────────────┐  │
      # │ │    写法      │                  说明                        │  │
      # │ ├─────────────┼──────────────────────────────────────────────┤  │
      # │ │ 1           │ 最多多 1 个 Pod                              │  │
      # │ │ 2           │ 最多多 2 个 Pod                              │  │
      # │ │ "25%"       │ 最多多 25%(向上取整)                       │  │
      # │ │ "50%"       │ 最多多 50%                                   │  │
      # │ │ "100%"      │ 最多多 100%(翻倍)                          │  │
      # │ └─────────────┴──────────────────────────────────────────────┘  │
      # │                                                                  │
      # │ 计算举例(replicas=4,maxSurge=1):                              │
      # │ • 更新时最多有 4 + 1 = 5 个 Pod 同时运行                        │
      # │ • 先创建 1 个新 Pod                                             │
      # │ • 新 Pod 就绪后,删除 1 个旧 Pod                                │
      # │ • 重复直到全部更新完成                                          │
      # │                                                                  │
      # │ 计算举例(replicas=10,maxSurge="25%"):                         │
      # │ • 25% × 10 = 2.5 → 向上取整 = 3                                 │
      # │ • 更新时最多有 10 + 3 = 13 个 Pod                               │
      # │                                                                  │
      # │ 推荐配置:                                                        │
      # │ • 小规模(1-5副本):maxSurge: 1                                 │
      # │ • 中规模(5-20副本):maxSurge: "25%"                            │
      # │ • 大规模(20+副本):maxSurge: "25%" 或 "10%"                    │
      # │                                                                  │
      # │ 举例:                                                            │
      # │ maxSurge: 1        # 推荐,稳妥                                  │
      # │ maxSurge: 2        # 更快更新                                   │
      # │ maxSurge: "25%"    # 按比例                                     │
      # │ maxSurge: "100%"   # 蓝绿部署效果                               │
      # └─────────────────────────────────────────────────────────────────┘
      
      maxUnavailable: 0
      # ┌─────────────────────────────────────────────────────────────────┐
      # │ maxUnavailable: 最大不可用数                                     │
      # │                                                                  │
      # │ 作用:更新时最多允许几个 Pod 不可用                              │
      # │                                                                  │
      # │ 类型:整数 或 百分比字符串                                       │
      # │                                                                  │
      # │ 取值方式:                                                        │
      # │ ┌─────────────┬──────────────────────────────────────────────┐  │
      # │ │    写法      │                  说明                        │  │
      # │ ├─────────────┼──────────────────────────────────────────────┤  │
      # │ │ 0           │ 不允许有 Pod 不可用【推荐】                   │  │
      # │ │ 1           │ 最多 1 个 Pod 不可用                         │  │
      # │ │ "25%"       │ 最多 25% 不可用(向下取整)                  │  │
      # │ │ "50%"       │ 最多 50% 不可用                              │  │
      # │ └─────────────┴──────────────────────────────────────────────┘  │
      # │                                                                  │
      # │ ⚠️ 重要约束:                                                   │
      # │ • maxSurge 和 maxUnavailable 不能同时为 0                       │
      # │ • 否则无法更新(既不能多创建,又不能删除)                       │
      # │                                                                  │
      # │ 计算举例(replicas=4,maxUnavailable=1):                        │
      # │ • 更新时最少有 4 - 1 = 3 个 Pod 可用                            │
      # │ • 先删除 1 个旧 Pod                                             │
      # │ • 创建 1 个新 Pod                                               │
      # │ • 等新 Pod 就绪后,再删除下一个旧 Pod                           │
      # │                                                                  │
      # │ 推荐配置:                                                        │
      # │ • 生产环境:maxUnavailable: 0(零停机)                          │
      # │ • 允许短暂降级:maxUnavailable: 1 或 "25%"                      │
      # │                                                                  │
      # │ 常见组合:                                                        │
      # │ ┌─────────────────────────────┬─────────────────────────────┐   │
      # │ │         配置                 │           效果              │   │
      # │ ├─────────────────────────────┼─────────────────────────────┤   │
      # │ │ maxSurge: 1                 │ 最稳妥,零停机              │   │
      # │ │ maxUnavailable: 0           │ 但更新较慢                  │   │
      # │ ├─────────────────────────────┼─────────────────────────────┤   │
      # │ │ maxSurge: "25%"             │ 平衡速度和稳定              │   │
      # │ │ maxUnavailable: "25%"       │                             │   │
      # │ ├─────────────────────────────┼─────────────────────────────┤   │
      # │ │ maxSurge: "100%"            │ 类似蓝绿部署                │   │
      # │ │ maxUnavailable: 0           │ 最快,资源消耗大            │   │
      # │ └─────────────────────────────┴─────────────────────────────┘   │
      # │                                                                  │
      # │ 【推荐】生产环境用 maxSurge: 1, maxUnavailable: 0               │
      # └─────────────────────────────────────────────────────────────────┘
  
  template:
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ template: Pod 模板                                                  │
    # │                                                                      │
    # │ 作用:定义 Pod 的具体内容(元数据 + 规格)                          │
    # │                                                                      │
    # │ 结构:                                                               │
    # │ template:                                                           │
    # │   metadata:     → Pod 的元数据(标签等)                            │
    # │   spec:         → Pod 的规格(容器、卷等)                          │
    # └─────────────────────────────────────────────────────────────────────┘
    
    metadata:
      labels:
        app: backend
        version: v1
      # ┌─────────────────────────────────────────────────────────────────┐
      # │ template.metadata.labels: Pod 的标签                             │
      # │                                                                  │
      # │ ⚠️ 重要:必须与上面 selector.matchLabels 一致                    │
      # │                                                                  │
      # │ 常用标签:                                                        │
      # │ • app: backend          → 应用名(必须)                        │
      # │ • version: v1           → 版本(推荐)                          │
      # │ • env: prod             → 环境                                  │
      # │ • team: backend-team    → 团队                                  │
      # │ • release: stable       → 发布状态                              │
      # │                                                                  │
      # │ 可选:添加 annotations(注解)                                   │
      # │ annotations:                                                    │
      # │   prometheus.io/scrape: "true"   # Prometheus 抓取              │
      # │   prometheus.io/port: "8080"     # 抓取端口                     │
      # └─────────────────────────────────────────────────────────────────┘
    
    spec:
      # ════════════════════════════════════════════════════════════════════
      # Pod 规格定义
      # ════════════════════════════════════════════════════════════════════
      
      containers:
      # ┌─────────────────────────────────────────────────────────────────────┐
      # │ containers: 容器列表                                                │
      # │                                                                      │
      # │ 作用:定义 Pod 中运行的容器(可以多个)                              │
      # │                                                                      │
      # │ 一个 Pod 多个容器的场景:                                            │
      # │ • Sidecar 模式:主容器 + 日志收集容器                               │
      # │ • Ambassador 模式:主容器 + 代理容器                                │
      # │ • Adapter 模式:主容器 + 格式转换容器                               │
      # │                                                                      │
      # │ 举例(单容器,最常见):                                             │
      # │ containers:                                                          │
      # │ - name: backend                                                     │
      # │   image: xxx                                                        │
      # │                                                                      │
      # │ 举例(多容器,Sidecar):                                            │
      # │ containers:                                                          │
      # │ - name: backend           # 主容器                                  │
      # │   image: backend:v1                                                 │
      # │ - name: log-collector     # Sidecar 容器                            │
      # │   image: fluentd:latest                                             │
      # └─────────────────────────────────────────────────────────────────────┘
      
      - name: backend
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ name: 容器名称                                                   │
        # │                                                                  │
        # │ 作用:容器的唯一标识                                             │
        # │                                                                  │
        # │ 命名规则:                                                        │
        # │ • 只能用小写字母、数字、连字符                                   │
        # │ • 同一 Pod 内必须唯一                                            │
        # │                                                                  │
        # │ 用途:                                                            │
        # │ • kubectl logs <pod> -c backend  # 指定查看哪个容器的日志       │
        # │ • kubectl exec -c backend        # 指定进入哪个容器             │
        # │                                                                  │
        # │ 【改】根据服务命名:backend、frontend、api、worker 等           │
        # └─────────────────────────────────────────────────────────────────┘
        
        image: registry.cn-hongkong.aliyuncs.com/myproject/backend:v1.0.0
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ image: 容器镜像地址                                              │
        # │                                                                  │
        # │ 格式:[仓库地址/][命名空间/]镜像名[:标签]                         │
        # │                                                                  │
        # │ 完整格式举例:                                                    │
        # │ ┌─────────────────────────────────────────────────────────────┐ │
        # │ │ registry.cn-hongkong.aliyuncs.com/myproject/backend:v1.0.0 │ │
        # │ │ ├─────────────────────────────┤ ├───────┤ ├─────┤ ├─────┤  │ │
        # │ │ │         仓库地址             │ │命名空间│ │镜像名│ │标签 │  │ │
        # │ └─────────────────────────────────────────────────────────────┘ │
        # │                                                                  │
        # │ 仓库地址举例:                                                    │
        # │ ┌─────────────────────────────────────┬───────────────────────┐ │
        # │ │            仓库地址                  │        说明           │ │
        # │ ├─────────────────────────────────────┼───────────────────────┤ │
        # │ │ (省略)                             │ Docker Hub 官方       │ │
        # │ │ registry.cn-hongkong.aliyuncs.com  │ 阿里云香港             │ │
        # │ │ registry.cn-hangzhou.aliyuncs.com  │ 阿里云杭州             │ │
        # │ │ ccr.ccs.tencentyun.com             │ 腾讯云                 │ │
        # │ │ ghcr.io                            │ GitHub                 │ │
        # │ │ gcr.io                             │ Google                 │ │
        # │ │ your-registry.com                  │ 私有仓库               │ │
        # │ └─────────────────────────────────────┴───────────────────────┘ │
        # │                                                                  │
        # │ 标签规范(推荐语义化版本):                                       │
        # │ ┌─────────────────┬──────────────────────────────────────────┐ │
        # │ │     标签         │              说明                        │ │
        # │ ├─────────────────┼──────────────────────────────────────────┤ │
        # │ │ v1.0.0          │ 语义化版本(推荐!)                      │ │
        # │ │ v1.0.0-alpha    │ 预发布版本                               │ │
        # │ │ v1.0.0-rc.1     │ 候选版本                                 │ │
        # │ │ latest          │ 最新版(❌不推荐,不可控)               │ │
        # │ │ abc123def       │ Git commit SHA(CI/CD 常用)             │ │
        # │ │ 20240101-1      │ 日期+序号                                │ │
        # │ │ main-abc123     │ 分支名+commit                            │ │
        # │ └─────────────────┴──────────────────────────────────────────┘ │
        # │                                                                  │
        # │ 【改】替换为你的镜像地址                                          │
        # └─────────────────────────────────────────────────────────────────┘
        
        imagePullPolicy: IfNotPresent
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ imagePullPolicy: 镜像拉取策略                                    │
        # │                                                                  │
        # │ 作用:决定何时从仓库拉取镜像                                      │
        # │                                                                  │
        # │ 枚举值(只有3个):                                               │
        # │ ┌────────────────┬─────────────────────────────────────────────┐│
        # │ │      值         │                  说明                       ││
        # │ ├────────────────┼─────────────────────────────────────────────┤│
        # │ │ Always         │ 每次启动 Pod 都拉取镜像                     ││
        # │ │                │ • latest 标签默认使用此策略                 ││
        # │ │                │ • 保证使用最新镜像                          ││
        # │ │                │ • 但启动较慢,依赖网络                      ││
        # │ ├────────────────┼─────────────────────────────────────────────┤│
        # │ │ IfNotPresent   │ 本地没有才拉取【推荐】                      ││
        # │ │                │ • 指定版本标签默认使用此策略                ││
        # │ │                │ • 启动快                                    ││
        # │ │                │ • 生产环境推荐                              ││
        # │ ├────────────────┼─────────────────────────────────────────────┤│
        # │ │ Never          │ 从不拉取,只用本地镜像                      ││
        # │ │                │ • 本地没有会报错                            ││
        # │ │                │ • 用于离线环境                              ││
        # │ └────────────────┴─────────────────────────────────────────────┘│
        # │                                                                  │
        # │ 默认行为:                                                        │
        # │ • 标签是 latest 或省略 → Always                                  │
        # │ • 标签是其他(如 v1.0.0)→ IfNotPresent                          │
        # │                                                                  │
        # │ 【推荐】使用具体版本标签 + IfNotPresent                           │
        # └─────────────────────────────────────────────────────────────────┘
        
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ ports: 容器端口配置                                              │
        # │                                                                  │
        # │ 作用:声明容器暴露的端口(仅声明,不会自动暴露到外部)            │
        # │                                                                  │
        # │ 字段说明:                                                        │
        # │ ┌─────────────────┬────────────────────────────────────────────┐│
        # │ │      字段        │                  说明                      ││
        # │ ├─────────────────┼────────────────────────────────────────────┤│
        # │ │ name            │ 端口名称(可选)                           ││
        # │ │                 │ • Service 可通过名称引用                   ││
        # │ │                 │ • 只能用小写字母、数字、连字符             ││
        # │ ├─────────────────┼────────────────────────────────────────────┤│
        # │ │ containerPort   │ 容器内端口号(必填)                       ││
        # │ │                 │ • 范围:1-65535                            ││
        # │ ├─────────────────┼────────────────────────────────────────────┤│
        # │ │ protocol        │ 协议(可选,默认 TCP)                     ││
        # │ │                 │ • 枚举值:TCP、UDP、SCTP                   ││
        # │ ├─────────────────┼────────────────────────────────────────────┤│
        # │ │ hostPort        │ 宿主机端口(可选,不推荐)                 ││
        # │ │                 │ • 直接映射到节点端口                       ││
        # │ │                 │ • 会限制 Pod 调度                          ││
        # │ └─────────────────┴────────────────────────────────────────────┘│
        # │                                                                  │
        # │ 常用端口举例:                                                    │
        # │ ┌──────────────────────┬─────────────────────────────────────┐  │
        # │ │       应用            │             端口                    │  │
        # │ ├──────────────────────┼─────────────────────────────────────┤  │
        # │ │ Spring Boot          │ 8080                                │  │
        # │ │ Node.js              │ 3000                                │  │
        # │ │ Go                   │ 8080                                │  │
        # │ │ Python Flask         │ 5000                                │  │
        # │ │ Nginx                │ 80、443                             │  │
        # │ │ MySQL                │ 3306                                │  │
        # │ │ Redis                │ 6379                                │  │
        # │ │ PostgreSQL           │ 5432                                │  │
        # │ └──────────────────────┴─────────────────────────────────────┘  │
        # │                                                                  │
        # │ 多端口举例:                                                      │
        # │ ports:                                                           │
        # │ - name: http                                                     │
        # │   containerPort: 8080                                            │
        # │   protocol: TCP                                                  │
        # │ - name: metrics       # Prometheus 指标端口                      │
        # │   containerPort: 9090                                            │
        # │   protocol: TCP                                                  │
        # │ - name: grpc          # gRPC 端口                                │
        # │   containerPort: 9000                                            │
        # │   protocol: TCP                                                  │
        # │                                                                  │
        # │ 【改】根据应用实际端口修改                                        │
        # └─────────────────────────────────────────────────────────────────┘
        
        env:
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ env: 环境变量配置                                                │
        # │                                                                  │
        # │ 作用:设置容器内的环境变量                                        │
        # │                                                                  │
        # │ 四种来源:                                                        │
        # │ ┌───────────────────────────────────────────────────────────┐   │
        # │ │ 1. 直接写值                                               │   │
        # │ │ ─────────────────────────────────────────────────────────│   │
        # │ │ - name: LOG_LEVEL                                        │   │
        # │ │   value: "INFO"                                          │   │
        # │ └───────────────────────────────────────────────────────────┘   │
        # │                                                                  │
        # │ ┌───────────────────────────────────────────────────────────┐   │
        # │ │ 2. 从 Secret 获取(敏感信息)                              │   │
        # │ │ ─────────────────────────────────────────────────────────│   │
        # │ │ - name: DB_PASSWORD                                      │   │
        # │ │   valueFrom:                                             │   │
        # │ │     secretKeyRef:                                        │   │
        # │ │       name: mysql-secret   # Secret 名称                 │   │
        # │ │       key: password        # Secret 中的 key             │   │
        # │ │       optional: false      # 是否可选,默认 false        │   │
        # │ └───────────────────────────────────────────────────────────┘   │
        # │                                                                  │
        # │ ┌───────────────────────────────────────────────────────────┐   │
        # │ │ 3. 从 ConfigMap 获取(配置信息)                           │   │
        # │ │ ─────────────────────────────────────────────────────────│   │
        # │ │ - name: LOG_LEVEL                                        │   │
        # │ │   valueFrom:                                             │   │
        # │ │     configMapKeyRef:                                     │   │
        # │ │       name: app-config     # ConfigMap 名称              │   │
        # │ │       key: log_level       # ConfigMap 中的 key          │   │
        # │ └───────────────────────────────────────────────────────────┘   │
        # │                                                                  │
        # │ ┌───────────────────────────────────────────────────────────┐   │
        # │ │ 4. 从 Pod 信息获取(fieldRef)                            │   │
        # │ │ ─────────────────────────────────────────────────────────│   │
        # │ │ - name: POD_NAME                                         │   │
        # │ │   valueFrom:                                             │   │
        # │ │     fieldRef:                                            │   │
        # │ │       fieldPath: metadata.name      # Pod 名称           │   │
        # │ │ - name: POD_IP                                           │   │
        # │ │   valueFrom:                                             │   │
        # │ │     fieldRef:                                            │   │
        # │ │       fieldPath: status.podIP       # Pod IP             │   │
        # │ │ - name: NODE_NAME                                        │   │
        # │ │   valueFrom:                                             │   │
        # │ │     fieldRef:                                            │   │
        # │ │       fieldPath: spec.nodeName      # 节点名称           │   │
        # │ │ - name: NAMESPACE                                        │   │
        # │ │   valueFrom:                                             │   │
        # │ │     fieldRef:                                            │   │
        # │ │       fieldPath: metadata.namespace # 命名空间           │   │
        # │ └───────────────────────────────────────────────────────────┘   │
        # │                                                                  │
        # │ fieldRef 可用字段:                                              │
        # │ • metadata.name        → Pod 名称                               │
        # │ • metadata.namespace   → 命名空间                               │
        # │ • metadata.uid         → Pod UID                                │
        # │ • metadata.labels['x'] → 获取标签值                             │
        # │ • spec.nodeName        → 节点名称                               │
        # │ • spec.serviceAccountName → ServiceAccount 名称                 │
        # │ • status.podIP         → Pod IP                                 │
        # │ • status.hostIP        → 节点 IP                                │
        # │                                                                  │
        # │ 变量引用(在 value 中引用其他变量):                             │
        # │ - name: FULL_URL                                                │
        # │   value: "http://$(HOST):$(PORT)/api"  # $(变量名)              │
        # └─────────────────────────────────────────────────────────────────┘
        
        - name: TZ
          value: "Asia/Shanghai"
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ TZ: 时区设置                                                     │
        # │                                                                  │
        # │ 作用:设置容器时区,保证日志时间正确                              │
        # │                                                                  │
        # │ 常用时区:                                                        │
        # │ • Asia/Shanghai    → 中国标准时间(北京时间)                    │
        # │ • Asia/Hong_Kong   → 香港时间                                    │
        # │ • UTC              → 世界协调时间                                │
        # │ • America/New_York → 美国东部时间                                │
        # └─────────────────────────────────────────────────────────────────┘
        
        - name: SPRING_PROFILES_ACTIVE
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: SPRING_PROFILES_ACTIVE
          # 从 ConfigMap 获取
        
        - name: SPRING_DATASOURCE_URL
          value: "jdbc:mysql://$(MYSQL_HOST):$(MYSQL_PORT)/$(MYSQL_DATABASE)?useSSL=false&serverTimezone=Asia/Shanghai"
          # ┌─────────────────────────────────────────────────────────────┐
          # │ $(VAR_NAME) 可以引用其他环境变量                              │
          # └─────────────────────────────────────────────────────────────┘
        
        - name: MYSQL_HOST
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: MYSQL_HOST
        
        - name: MYSQL_PORT
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: MYSQL_PORT
        
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: MYSQL_DATABASE
        
        - name: SPRING_DATASOURCE_USERNAME
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: MYSQL_USERNAME
        
        - name: SPRING_DATASOURCE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: MYSQL_PASSWORD
        
        - name: SPRING_REDIS_HOST
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: REDIS_HOST
        
        - name: SPRING_REDIS_PORT
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: REDIS_PORT
        
        - name: SPRING_REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: REDIS_PASSWORD
        
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ resources: 资源配置                                              │
        # │                                                                  │
        # │ 作用:限制容器使用的 CPU 和内存资源                              │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ requests(请求)                                                 │
        # │ ════════════════════════════════════════════════════════════════│
        # │ • 调度时保证的最小资源                                           │
        # │ • 节点剩余资源 >= requests 才能调度到该节点                      │
        # │ • 影响 Pod 调度位置                                             │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ limits(限制)                                                   │
        # │ ════════════════════════════════════════════════════════════════│
        # │ • 容器最多能用的资源                                             │
        # │ • CPU 超过 limits:被限流(throttled),变慢但不会被杀           │
        # │ • Memory 超过 limits:被 OOM Kill,容器重启                     │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ CPU 单位                                                         │
        # │ ════════════════════════════════════════════════════════════════│
        # │ ┌────────────┬────────────┬───────────────────────────────────┐ │
        # │ │    写法     │    含义     │              举例                 │ │
        # │ ├────────────┼────────────┼───────────────────────────────────┤ │
        # │ │ 1          │ 1 个 CPU核 │ 1 核                               │ │
        # │ │ 0.5        │ 0.5 个核   │ 半个核                             │ │
        # │ │ 1000m      │ 1000毫核=1核│ m = milli(千分之一)             │ │
        # │ │ 500m       │ 0.5 核     │ 500毫核                            │ │
        # │ │ 250m       │ 0.25 核    │ 250毫核                            │ │
        # │ │ 100m       │ 0.1 核     │ 100毫核                            │ │
        # │ └────────────┴────────────┴───────────────────────────────────┘ │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ Memory 单位                                                      │
        # │ ════════════════════════════════════════════════════════════════│
        # │ ┌────────────┬────────────┬───────────────────────────────────┐ │
        # │ │    写法     │    含义     │              举例                 │ │
        # │ ├────────────┼────────────┼───────────────────────────────────┤ │
        # │ │ Ki         │ Kibibyte   │ 1Ki = 1024 bytes                  │ │
        # │ │ Mi         │ Mebibyte   │ 1Mi = 1024 Ki ≈ 1MB               │ │
        # │ │ Gi         │ Gibibyte   │ 1Gi = 1024 Mi ≈ 1GB               │ │
        # │ │ Ti         │ Tebibyte   │ 1Ti = 1024 Gi ≈ 1TB               │ │
        # │ ├────────────┼────────────┼───────────────────────────────────┤ │
        # │ │ K          │ Kilobyte   │ 1K = 1000 bytes(不推荐)          │ │
        # │ │ M          │ Megabyte   │ 1M = 1000 K                       │ │
        # │ │ G          │ Gigabyte   │ 1G = 1000 M                       │ │
        # │ └────────────┴────────────┴───────────────────────────────────┘ │
        # │                                                                  │
        # │ ⚠️ 推荐用 Mi、Gi(二进制单位),避免用 M、G                     │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ 各类应用推荐配置                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ ┌─────────────────┬─────────────────┬─────────────────────────┐ │
        # │ │     应用类型     │    requests     │        limits           │ │
        # │ ├─────────────────┼─────────────────┼─────────────────────────┤ │
        # │ │ Spring Boot     │ cpu: 250m       │ cpu: 500m-1             │ │
        # │ │                 │ memory: 512Mi   │ memory: 1Gi-2Gi         │ │
        # │ ├─────────────────┼─────────────────┼─────────────────────────┤ │
        # │ │ Node.js         │ cpu: 100m       │ cpu: 500m               │ │
        # │ │                 │ memory: 128Mi   │ memory: 512Mi           │ │
        # │ ├─────────────────┼─────────────────┼─────────────────────────┤ │
        # │ │ Go              │ cpu: 100m       │ cpu: 500m               │ │
        # │ │                 │ memory: 64Mi    │ memory: 256Mi           │ │
        # │ ├─────────────────┼─────────────────┼─────────────────────────┤ │
        # │ │ Python          │ cpu: 100m       │ cpu: 500m               │ │
        # │ │                 │ memory: 256Mi   │ memory: 512Mi           │ │
        # │ ├─────────────────┼─────────────────┼─────────────────────────┤ │
        # │ │ Nginx           │ cpu: 50m        │ cpu: 200m               │ │
        # │ │                 │ memory: 64Mi    │ memory: 256Mi           │ │
        # │ └─────────────────┴─────────────────┴─────────────────────────┘ │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ 最佳实践                                                         │
        # │ ════════════════════════════════════════════════════════════════│
        # │ 1. requests 设为实际平均使用量(通过监控获取)                   │
        # │ 2. limits 设为 requests 的 1.5-2 倍                              │
        # │ 3. 不要设置过大的 limits(浪费资源)                             │
        # │ 4. 不要设置过小的 limits(频繁 OOM)                             │
        # │ 5. 建议设置 requests = limits(QoS 为 Guaranteed)              │
        # │                                                                  │
        # │ QoS 等级:                                                       │
        # │ • Guaranteed:requests = limits(最高优先级)                   │
        # │ • Burstable:requests < limits                                  │
        # │ • BestEffort:不设置 resources(最低优先级)                    │
        # │                                                                  │
        # │ 【改】根据实际监控数据调整                                       │
        # └─────────────────────────────────────────────────────────────────┘
        
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ readinessProbe: 就绪探针                                        │
        # │                                                                  │
        # │ 作用:判断 Pod 是否准备好接收流量                               │
        # │ • 检查成功:加入 Service 负载均衡,开始接收请求                 │
        # │ • 检查失败:从 Service 移除,不接收请求(但不重启)             │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ 三种检查方式                                                     │
        # │ ════════════════════════════════════════════════════════════════│
        # │                                                                  │
        # │ 方式1:HTTP GET(最常用)                                        │
        # │ ──────────────────────────────────────────────────────────────  │
        # │ readinessProbe:                                                 │
        # │   httpGet:                                                      │
        # │     path: /health          # 检查路径                           │
        # │     port: 8080             # 检查端口                           │
        # │     scheme: HTTP           # 协议,HTTP 或 HTTPS               │
        # │     httpHeaders:           # 可选,自定义请求头                 │
        # │     - name: Custom-Header                                       │
        # │       value: value                                              │
        # │                                                                  │
        # │ 返回状态码 200-399 为成功,其他为失败                           │
        # │                                                                  │
        # │ 方式2:TCP Socket                                                │
        # │ ──────────────────────────────────────────────────────────────  │
        # │ readinessProbe:                                                 │
        # │   tcpSocket:                                                    │
        # │     port: 8080             # 检查端口是否能连接                 │
        # │                                                                  │
        # │ 端口能连接为成功                                                │
        # │                                                                  │
        # │ 方式3:执行命令                                                  │
        # │ ──────────────────────────────────────────────────────────────  │
        # │ readinessProbe:                                                 │
        # │   exec:                                                         │
        # │     command:                                                    │
        # │     - cat                                                       │
        # │     - /tmp/healthy                                              │
        # │                                                                  │
        # │ 命令返回 0 为成功,非 0 为失败                                  │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ 参数详解                                                         │
        # │ ════════════════════════════════════════════════════════════════│
        # │ ┌──────────────────────┬──────┬─────────────────────────────┐  │
        # │ │        参数           │默认值│           说明               │  │
        # │ ├──────────────────────┼──────┼─────────────────────────────┤  │
        # │ │ initialDelaySeconds  │ 0    │ 容器启动后等待多少秒开始检查 │  │
        # │ │                      │      │ 【改】Spring Boot 设 30-60  │  │
        # │ ├──────────────────────┼──────┼─────────────────────────────┤  │
        # │ │ periodSeconds        │ 10   │ 检查间隔秒数                 │  │
        # │ ├──────────────────────┼──────┼─────────────────────────────┤  │
        # │ │ timeoutSeconds       │ 1    │ 检查超时秒数                 │  │
        # │ ├──────────────────────┼──────┼─────────────────────────────┤  │
        # │ │ successThreshold     │ 1    │ 连续成功几次算成功           │  │
        # │ │                      │      │ readiness 可设 1-3          │  │
        # │ ├──────────────────────┼──────┼─────────────────────────────┤  │
        # │ │ failureThreshold     │ 3    │ 连续失败几次算失败           │  │
        # │ └──────────────────────┴──────┴─────────────────────────────┘  │
        # │                                                                  │
        # │ 常用健康检查路径:                                               │
        # │ • Spring Boot: /actuator/health/readiness                       │
        # │ • Node.js: /health, /ready                                      │
        # │ • Go: /healthz, /ready                                          │
        # │ • 自定义: /ping, /status                                        │
        # └─────────────────────────────────────────────────────────────────┘
        
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ livenessProbe: 存活探针                                          │
        # │                                                                  │
        # │ 作用:判断容器是否还活着,需不需要重启                           │
        # │ • 检查成功:正常                                                │
        # │ • 检查失败:kubelet 会杀死容器并重启                            │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ readinessProbe vs livenessProbe 对比                            │
        # │ ════════════════════════════════════════════════════════════════│
        # │ ┌─────────────────┬───────────────────┬───────────────────────┐ │
        # │ │      探针        │   检查失败时       │       用途            │ │
        # │ ├─────────────────┼───────────────────┼───────────────────────┤ │
        # │ │ readinessProbe  │ 从 Service 移除   │ 是否可以接收流量      │ │
        # │ │                 │ 不再接收请求       │ 启动中、过载时不接收  │ │
        # │ │                 │ 不会重启           │                       │ │
        # │ ├─────────────────┼───────────────────┼───────────────────────┤ │
        # │ │ livenessProbe   │ 重启容器          │ 是否需要重启          │ │
        # │ │                 │                   │ 死锁、假死时重启      │ │
        # │ └─────────────────┴───────────────────┴───────────────────────┘ │
        # │                                                                  │
        # │ ⚠️ 重要注意事项:                                               │
        # │ 1. liveness 的 initialDelaySeconds 要 > readiness 的           │
        # │    • 避免应用还在启动就被 liveness 判定失败重启                 │
        # │    • 造成无限重启循环                                           │
        # │                                                                  │
        # │ 2. liveness 不要检查外部依赖(如数据库)                         │
        # │    • 数据库挂了,重启应用也没用                                 │
        # │    • 只检查应用自身状态                                         │
        # │                                                                  │
        # │ 3. readiness 可以检查外部依赖                                   │
        # │    • 数据库挂了,暂时不接收请求                                 │
        # │    • 等数据库恢复后再接收                                       │
        # │                                                                  │
        # │ 推荐配置:                                                       │
        # │ ┌─────────────────┬───────────────────┬───────────────────────┐ │
        # │ │      应用        │  initialDelay     │    periodSeconds      │ │
        # │ ├─────────────────┼───────────────────┼───────────────────────┤ │
        # │ │ Spring Boot     │ readiness: 30     │ 10                    │ │
        # │ │                 │ liveness: 60      │ 10                    │ │
        # │ ├─────────────────┼───────────────────┼───────────────────────┤ │
        # │ │ Node.js         │ readiness: 5      │ 5                     │ │
        # │ │                 │ liveness: 15      │ 10                    │ │
        # │ ├─────────────────┼───────────────────┼───────────────────────┤ │
        # │ │ Go              │ readiness: 3      │ 5                     │ │
        # │ │                 │ liveness: 10      │ 10                    │ │
        # │ └─────────────────┴───────────────────┴───────────────────────┘ │
        # └─────────────────────────────────────────────────────────────────┘
        
        # 还有一个可选探针:startupProbe(启动探针)
        # startupProbe:
        #   httpGet:
        #     path: /actuator/health
        #     port: 8080
        #   initialDelaySeconds: 0
        #   periodSeconds: 10
        #   timeoutSeconds: 5
        #   failureThreshold: 30     # 30 × 10 = 300秒 = 5分钟
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ startupProbe: 启动探针(K8s 1.18+)                             │
        # │                                                                  │
        # │ 作用:专门用于启动慢的应用                                      │
        # │ • 启动探针成功前,liveness 和 readiness 不会执行                │
        # │ • 启动探针成功后,才开始 liveness 和 readiness 检查             │
        # │                                                                  │
        # │ 适用场景:                                                       │
        # │ • 启动时间超过 1 分钟的应用                                     │
        # │ • 旧版应用,启动时间不确定                                      │
        # │                                                                  │
        # │ 例:failureThreshold: 30, periodSeconds: 10                     │
        # │ → 最多等待 30 × 10 = 300 秒(5分钟)                            │
        # └─────────────────────────────────────────────────────────────────┘
        
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 15"]
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ lifecycle: 生命周期钩子                                          │
        # │                                                                  │
        # │ 作用:在容器生命周期的特定时刻执行操作                           │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ preStop: 容器停止前执行                                          │
        # │ ════════════════════════════════════════════════════════════════│
        # │ • 在收到 SIGTERM 之前执行                                        │
        # │ • 用于优雅关闭                                                  │
        # │                                                                  │
        # │ 常用方式:                                                        │
        # │ ┌─────────────────────────────────────────────────────────────┐ │
        # │ │ # 方式1:执行命令(最常用)                                  │ │
        # │ │ preStop:                                                    │ │
        # │ │   exec:                                                     │ │
        # │ │     command: ["/bin/sh", "-c", "sleep 15"]                 │ │
        # │ │                                                             │ │
        # │ │ # 方式2:HTTP 请求                                          │ │
        # │ │ preStop:                                                    │ │
        # │ │   httpGet:                                                  │ │
        # │ │     path: /shutdown                                        │ │
        # │ │     port: 8080                                             │ │
        # │ └─────────────────────────────────────────────────────────────┘ │
        # │                                                                  │
        # │ 为什么要 sleep?                                                 │
        # │ • K8s 从 Service 移除 Pod 需要时间(Endpoint 更新延迟)          │
        # │ • sleep 期间不再接收新请求                                       │
        # │ • 等待已有请求处理完成                                          │
        # │ • 推荐 sleep 15-30 秒                                            │
        # │                                                                  │
        # │ ════════════════════════════════════════════════════════════════│
        # │ postStart: 容器启动后执行                                        │
        # │ ════════════════════════════════════════════════════════════════│
        # │ postStart:                                                       │
        # │   exec:                                                          │
        # │     command: ["/bin/sh", "-c", "echo started >> /var/log/app"] │
        # │                                                                  │
        # │ 用途:初始化操作、注册到服务发现等                               │
        # │ ⚠️ 注意:postStart 与容器 ENTRYPOINT 并行执行                   │
        # └─────────────────────────────────────────────────────────────────┘
      
      terminationGracePeriodSeconds: 30
      # ┌─────────────────────────────────────────────────────────────────────┐
      # │ terminationGracePeriodSeconds: 优雅终止等待时间                     │
      # │                                                                      │
      # │ 作用:定义 Pod 停止时的最大等待时间                                  │
      # │                                                                      │
      # │ 类型:整数(秒)                                                     │
      # │ 默认值:30                                                           │
      # │ 范围:0 - 无上限(但一般不超过 300 秒)                              │
      # │                                                                      │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ Pod 停止完整流程                                                     │
      # │ ════════════════════════════════════════════════════════════════════│
      # │                                                                      │
      # │  ┌────────────────────────────────────────────────────────────────┐ │
      # │  │ 1. kubectl delete pod xxx 或 Deployment 更新                   │ │
      # │  │    │                                                           │ │
      # │  │    ▼                                                           │ │
      # │  │ 2. Pod 状态变为 Terminating                                    │ │
      # │  │    │                                                           │ │
      # │  │    ▼                                                           │ │
      # │  │ 3. 从所有 Service 的 Endpoint 中移除(不再接收新请求)          │ │
      # │  │    │                                                           │ │
      # │  │    ▼(并行执行)                                                │ │
      # │  │ 4. 执行 preStop 钩子(如 sleep 15)                            │ │
      # │  │    │                                                           │ │
      # │  │    ▼(preStop 完成后)                                          │ │
      # │  │ 5. 发送 SIGTERM 信号给容器主进程                               │ │
      # │  │    │                                                           │ │
      # │  │    ▼(等待进程退出)                                            │ │
      # │  │ 6. 等待最多 terminationGracePeriodSeconds 秒                   │ │
      # │  │    │                                                           │ │
      # │  │    ▼(超时或进程退出)                                          │ │
      # │  │ 7. 发送 SIGKILL 强制终止                                       │ │
      # │  │    │                                                           │ │
      # │  │    ▼                                                           │ │
      # │  │ 8. Pod 被删除                                                  │ │
      # │  └────────────────────────────────────────────────────────────────┘ │
      # │                                                                      │
      # │ 设置建议:                                                           │
      # │ • terminationGracePeriodSeconds >= preStop 时间 + 应用关闭时间     │
      # │ • 例:preStop sleep 15 秒,应用关闭需要 10 秒                       │
      # │   → terminationGracePeriodSeconds 至少设 30                        │
      # │                                                                      │
      # │ 【改】根据应用实际关闭时间调整                                       │
      # └─────────────────────────────────────────────────────────────────────┘
      
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: backend
              topologyKey: kubernetes.io/hostname
      # ┌─────────────────────────────────────────────────────────────────────┐
      # │ affinity: 亲和性配置                                                 │
      # │                                                                      │
      # │ 作用:控制 Pod 调度到哪些节点                                        │
      # │                                                                      │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ 三种亲和性                                                           │
      # │ ════════════════════════════════════════════════════════════════════│
      # │                                                                      │
      # │ 1. nodeAffinity(节点亲和性)                                        │
      # │ ──────────────────────────────────────────────────────────────────  │
      # │ 作用:Pod 调度到特定节点                                             │
      # │                                                                      │
      # │ affinity:                                                            │
      # │   nodeAffinity:                                                      │
      # │     # 硬性要求:必须调度到有 GPU 的节点                              │
      # │     requiredDuringSchedulingIgnoredDuringExecution:                 │
      # │       nodeSelectorTerms:                                             │
      # │       - matchExpressions:                                            │
      # │         - key: gpu                                                   │
      # │           operator: Exists                                           │
      # │                                                                      │
      # │     # 软性偏好:尽量调度到 SSD 节点                                  │
      # │     preferredDuringSchedulingIgnoredDuringExecution:                │
      # │     - weight: 100                                                    │
      # │       preference:                                                    │
      # │         matchExpressions:                                            │
      # │         - key: disk-type                                             │
      # │           operator: In                                               │
      # │           values: [ssd]                                              │
      # │                                                                      │
      # │ 2. podAffinity(Pod 亲和性)                                         │
      # │ ──────────────────────────────────────────────────────────────────  │
      # │ 作用:Pod 和其他 Pod 调度到一起(同节点/同可用区)                   │
      # │ 场景:减少网络延迟(如前端和后端在同一节点)                         │
      # │                                                                      │
      # │ affinity:                                                            │
      # │   podAffinity:                                                       │
      # │     requiredDuringSchedulingIgnoredDuringExecution:                 │
      # │     - labelSelector:                                                 │
      # │         matchLabels:                                                 │
      # │           app: cache        # 和 cache Pod 在一起                   │
      # │       topologyKey: kubernetes.io/hostname                            │
      # │                                                                      │
      # │ 3. podAntiAffinity(Pod 反亲和性)【最常用】                         │
      # │ ──────────────────────────────────────────────────────────────────  │
      # │ 作用:Pod 和其他 Pod 不在一起(分散到不同节点)                      │
      # │ 场景:高可用,避免单点故障                                           │
      # │                                                                      │
      # │ affinity:                                                            │
      # │   podAntiAffinity:                                                   │
      # │     # 软性偏好:尽量分散到不同节点                                   │
      # │     preferredDuringSchedulingIgnoredDuringExecution:                │
      # │     - weight: 100                                                    │
      # │       podAffinityTerm:                                               │
      # │         labelSelector:                                               │
      # │           matchLabels:                                               │
      # │             app: backend                                             │
      # │         topologyKey: kubernetes.io/hostname                          │
      # │                                                                      │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ 调度类型                                                             │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ ┌──────────────────────────────────────────┬────────────────────┐   │
      # │ │                  类型                      │       说明         │   │
      # │ ├──────────────────────────────────────────┼────────────────────┤   │
      # │ │ requiredDuringSchedulingIgnored...       │ 硬性要求           │   │
      # │ │                                          │ 不满足不调度       │   │
      # │ ├──────────────────────────────────────────┼────────────────────┤   │
      # │ │ preferredDuringSchedulingIgnored...      │ 软性偏好           │   │
      # │ │                                          │ 尽量满足           │   │
      # │ │                                          │ weight: 1-100      │   │
      # │ └──────────────────────────────────────────┴────────────────────┘   │
      # │                                                                      │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ topologyKey 常用值                                                   │
      # │ ════════════════════════════════════════════════════════════════════│
      # │ ┌────────────────────────────────┬───────────────────────────────┐  │
      # │ │           topologyKey           │            含义               │  │
      # │ ├────────────────────────────────┼───────────────────────────────┤  │
      # │ │ kubernetes.io/hostname         │ 节点级别(同一节点)          │  │
      # │ │ topology.kubernetes.io/zone    │ 可用区级别(同一可用区)      │  │
      # │ │ topology.kubernetes.io/region  │ 地域级别(同一地域)          │  │
      # │ └────────────────────────────────┴───────────────────────────────┘  │
      # │                                                                      │
      # │ 【推荐】生产环境使用 podAntiAffinity,让 Pod 分散到不同节点         │
        # │ • podAffinity: 让某些 Pod 在一起(减少网络延迟)               │
        # └─────────────────────────────────────────────────────────────────┘

执行

kubectl apply -f backend-deployment.yaml

# 查看部署状态
kubectl get deployment -n prod
kubectl get pods -n prod

# 查看 Pod 详情(排查问题用)
kubectl describe pod <pod-name> -n prod

# 查看日志
kubectl logs -f <pod-name> -n prod

8.5 创建 Service

文件位置~/k8s/backend-service.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:backend-service.yaml
# 作用:为 Pod 提供固定访问入口和负载均衡
# 执行:kubectl apply -f backend-service.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: v1
kind: Service
metadata:
  name: backend-service
  # ┌─────────────────────────────────────────────────────────────────────────┐
  # │ name: Service 名称                                                       │
  # │ 【改】与 Deployment 名称对应:backend-service、frontend-service         │
  # │                                                                          │
  # │ 集群内访问方式:                                                          │
  # │ http://backend-service.prod.svc.cluster.local:8080                      │
  # │ 或简写:http://backend-service:8080(同命名空间内)                       │
  # └─────────────────────────────────────────────────────────────────────────┘
  namespace: prod

spec:
  selector:
    app: backend
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ selector: 选择哪些 Pod                                              │
    # │ 必须与 Deployment 的 template.metadata.labels 匹配                  │
    # └─────────────────────────────────────────────────────────────────────┘
  
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    protocol: TCP
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ ports: 端口配置                                                     │
    # │                                                                      │
    # │ • port: Service 端口(访问 Service 用这个端口)                     │
    # │ • targetPort: Pod 端口(转发到 Pod 的这个端口)                     │
    # │ • protocol: TCP 或 UDP                                              │
    # │                                                                      │
    # │ 例子:                                                               │
    # │ 访问 backend-service:8080 → 转发到 Pod:8080                        │
    # │                                                                      │
    # │ port 和 targetPort 可以不同:                                        │
    # │ port: 80                                                            │
    # │ targetPort: 8080                                                    │
    # │ → 访问 Service:80,转发到 Pod:8080                                  │
    # └─────────────────────────────────────────────────────────────────────┘
  
  type: ClusterIP
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ type: Service 类型                                                  │
    # │                                                                      │
    # │ ClusterIP(默认):                                                  │
    # │ • 只能集群内部访问                                                  │
    # │ • 分配一个虚拟 IP(ClusterIP)                                      │
    # │ • 【推荐】后端服务用这个,通过 Ingress 暴露                         │
    # │                                                                      │
    # │ NodePort:                                                           │
    # │ type: NodePort                                                      │
    # │ ports:                                                              │
    # │ - port: 8080                                                        │
    # │   targetPort: 8080                                                  │
    # │   nodePort: 30080    # 30000-32767 范围                             │
    # │ • 在每个节点开放一个端口                                            │
    # │ • 可通过 节点IP:30080 访问                                          │
    # │ • 适合测试,生产环境不推荐                                          │
    # │                                                                      │
    # │ LoadBalancer:                                                       │
    # │ type: LoadBalancer                                                  │
    # │ • 云厂商自动创建负载均衡器                                          │
    # │ • 有公网 IP                                                         │
    # │ • 费用较高,每个 Service 一个 SLB                                  │
    # │ • 单个服务暴露时可用                                                │
    # │                                                                      │
    # │ ExternalName:                                                       │
    # │ type: ExternalName                                                  │
    # │ externalName: rm-xxx.mysql.rds.aliyuncs.com                        │
    # │ • 映射到外部 DNS 名称                                               │
    # │ • 用于访问外部服务                                                  │
    # └─────────────────────────────────────────────────────────────────────┘

执行

kubectl apply -f backend-service.yaml

# 验证
kubectl get svc -n prod

九、配置Ingress和HTTPS

9.1 创建 Ingress

文件位置~/k8s/ingress.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:ingress.yaml
# 作用:对外暴露服务,处理 HTTPS,路由分发
# 执行:kubectl apply -f ingress.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: prod
  
  annotations:
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ annotations: 注解,用于配置 Ingress Controller 的行为               │
    # └─────────────────────────────────────────────────────────────────────┘
    
    kubernetes.io/ingress.class: nginx
    # 指定使用 Nginx Ingress Controller
    
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    # HTTP 自动重定向到 HTTPS
    
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
    # 【改】最大请求体大小,上传大文件需要调大
    
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    # 【改】超时时间,长连接或大文件需要调大
    
    # 以下是可选配置
    # nginx.ingress.kubernetes.io/rewrite-target: /$1
    # URL 重写,去掉路径前缀

spec:
  tls:
  - hosts:
    - example.com
    - www.example.com
    secretName: tls-secret
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ tls: HTTPS 配置                                                     │
    # │                                                                      │
    # │ • hosts: 需要 HTTPS 的域名                                          │
    # │   【改】替换为你的域名                                               │
    # │ • secretName: 存储证书的 Secret 名称                                │
    # │   需要先创建包含证书的 Secret(见下一节)                           │
    # └─────────────────────────────────────────────────────────────────────┘
  
  rules:
  - host: example.com
    # ┌─────────────────────────────────────────────────────────────────────┐
    # │ host: 域名                                                          │
    # │ 【改】替换为你的域名                                                 │
    # │                                                                      │
    # │ 可以配置多个域名:                                                   │
    # │ - host: api.example.com     # API 服务                              │
    # │ - host: admin.example.com   # 管理后台                              │
    # └─────────────────────────────────────────────────────────────────────┘
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ / 路径 → frontend-service                                       │
        # │                                                                  │
        # │ pathType 可选值:                                                │
        # │ • Prefix: 前缀匹配(推荐)                                      │
        # │   /user 匹配 /user、/user/123、/user/list                      │
        # │ • Exact: 精确匹配                                               │
        # │   /user 只匹配 /user,不匹配 /user/123                         │
        # │ • ImplementationSpecific: 由 Ingress Controller 决定           │
        # └─────────────────────────────────────────────────────────────────┘
      
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 8080
        # ┌─────────────────────────────────────────────────────────────────┐
        # │ /api 路径 → backend-service                                     │
        # │                                                                  │
        # │ 注意:路径匹配顺序                                               │
        # │ • 更长的路径优先匹配                                            │
        # │ • /api/v1 比 /api 优先                                         │
        # └─────────────────────────────────────────────────────────────────┘

  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

9.2 创建 TLS Secret

方式1:使用已有证书

# 如果你已经有证书文件(fullchain.pem 和 privkey.pem)
kubectl create secret tls tls-secret \
  --cert=fullchain.pem \
  --key=privkey.pem \
  -n prod

方式2:使用 Cert-Manager 自动申请(推荐)

# 安装 Cert-Manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# 等待安装完成
kubectl get pods -n cert-manager

创建证书颁发者~/k8s/cluster-issuer.yaml

# ═══════════════════════════════════════════════════════════════════════════════
# 文件名:cluster-issuer.yaml
# 作用:配置 Let's Encrypt 证书颁发者
# 执行:kubectl apply -f cluster-issuer.yaml
# ═══════════════════════════════════════════════════════════════════════════════

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod

spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    # Let's Encrypt 生产环境服务器
    
    email: your-email@example.com
    # 【改】你的邮箱,用于证书到期提醒
    
    privateKeySecretRef:
      name: letsencrypt-prod-key
    
    solvers:
    - http01:
        ingress:
          class: nginx
        # 使用 HTTP-01 验证方式

修改 Ingress 使用自动证书

# 在 ingress.yaml 的 annotations 中添加:
annotations:
  cert-manager.io/cluster-issuer: letsencrypt-prod
  # 指定使用 letsencrypt-prod 颁发者自动申请证书

执行

kubectl apply -f cluster-issuer.yaml
kubectl apply -f ingress.yaml

# 查看证书状态
kubectl get certificate -n prod

十、CI/CD自动化部署

10.1 使用阿里云云效

入口:https://devops.aliyun.com

步骤1:创建代码库

路径:云效 → Codeup → 新建代码库 / 导入仓库

步骤2:创建流水线

路径:云效 → Flow → 新建流水线 → 选择「Java + Docker + K8s部署」模板

步骤3:配置流水线阶段

阶段类型配置
1代码检出选择 Codeup 仓库,分支 main
2Java构建命令:mvn clean package -DskipTests
3镜像构建推送到 ACR
4K8s部署选择 ACK 集群、命名空间、Deployment

步骤4:配置触发

流水线设置 → 触发设置 → ☑ 代码提交触发 → 分支 main

10.2 部署 YAML

文件位置:项目根目录 k8s/deployment.yaml

# 云效会自动替换 ${IMAGE} 变量
image: ${IMAGE}

十一、监控告警

11.1 使用阿里云 ARMS(推荐)

路径:ACK 控制台 → 集群详情 → 运维管理 → Prometheus监控

优点:
• 与 ACK 深度集成
• 自动发现服务
• 内置大量 Dashboard
• 支持告警

11.2 查看监控

路径:ARMS → Prometheus监控 → Grafana → 选择 Dashboard

十二、金丝雀发布

12.1 什么是金丝雀发布

传统发布:一次性全部更新,有问题影响所有用户

金丝雀发布:
1. 先发布 10% 的 Pod 运行新版本
2. 观察监控、日志,确认没问题
3. 逐步增加新版本比例
4. 最终全部更新

12.2 使用 Ingress 实现

# ═══════════════════════════════════════════════════════════════════════════════
# 金丝雀发布配置
# ═══════════════════════════════════════════════════════════════════════════════

# 主版本 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress-stable
  namespace: prod
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-stable
            port:
              number: 8080

---
# 金丝雀版本 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress-canary
  namespace: prod
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
    # 10% 流量到金丝雀版本
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-canary
            port:
              number: 8080

十三、常见问题

13.1 Pod 启动失败

# 查看 Pod 状态
kubectl get pods -n prod

# 查看详情
kubectl describe pod <pod-name> -n prod

# 常见原因:
# ImagePullBackOff → 镜像拉取失败,检查镜像地址和凭证
# CrashLoopBackOff → 应用启动失败,查看日志
# Pending → 资源不足或调度失败

# 查看日志
kubectl logs <pod-name> -n prod

13.2 Service 无法访问

# 检查 Service
kubectl get svc -n prod
kubectl describe svc backend-service -n prod

# 检查 Endpoints(是否有 Pod 关联)
kubectl get endpoints backend-service -n prod

# 如果 Endpoints 为空,检查 selector 是否匹配

13.3 Ingress 无法访问

# 检查 Ingress
kubectl get ingress -n prod
kubectl describe ingress app-ingress -n prod

# 检查 Ingress Controller
kubectl get pods -n kube-system | grep ingress

# 检查 SLB
# ACK 控制台 → 负载均衡 → 查看监听状态

完整清单

阶段一:基础设施
☐ 1. 注册阿里云账号,实名认证
☐ 2. 开通 ACK、ACR、RDS、Redis 服务
☐ 3. 创建 ACK 集群(托管版)
☐ 4. 配置 kubectl
☐ 5. 创建 ACR 镜像仓库
☐ 6. 购买 RDS MySQL
☐ 7. 购买 Redis
☐ 8. 购买域名

阶段二:部署应用
☐ 9. 构建并推送镜像
☐ 10. 创建 Namespace
☐ 11. 创建 Secret
☐ 12. 创建 ConfigMap
☐ 13. 部署 Deployment
☐ 14. 创建 Service
☐ 15. 配置 Ingress
☐ 16. 配置 HTTPS 证书

阶段三:运维
☐ 17. 配置 CI/CD(云效)
☐ 18. 配置监控告警
☐ 19. 配置 HPA 自动扩缩

✅ 完成!访问 https://你的域名
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值