# alien-ack-cluster 使用说明与灰度发布

集群：**alien-ack-cluster**（ACK 托管版，Kubernetes **v1.26.2**）。节点池 **default-nodepool** 当前 **3 节点**（截图中状态为 **Unknown** 时须先修复，否则 Pod 无法调度）。

Harbor：**39.106.135.88**（与 Jenkins 构建机同区域/VPC 为佳，避免跨公网拉镜像超时）。

---

## 一、上线前检查清单

### 1. 节点状态为 Ready

控制台节点为 **Unknown** 时，在任意能访问 API 的机器执行：

```bash
kubectl get nodes -o wide
kubectl describe node <节点名>
```

常见原因：

| 现象 | 处理 |
|------|------|
| NotReady + 超时 | 节点安全组未放行 **6443**、**10250**；节点与 API Server 网络不通 |
| Kubelet 未启动 | SSH 到 ECS，`systemctl status kubelet` |
| 磁盘/内存压力 | `df -h`、`free -h`，清理镜像或扩容 |
| 容器运行时 | 节点为 **containerd 1.6.20**，勿混用 docker 与 containerd 配置 |

修复后应显示 **Ready**，且 `kubectl get pods -n kube-system` 中 CoreDNS、kube-proxy 正常（控制台「集群巡检」曾提示 CoreDNS 异常时优先处理）。

### 2. 本地 kubectl 接入 ACK

1. 控制台 → **alien-ack-cluster** → **连接信息** → 复制 **公网/内网 kubeconfig**（内网 Jenkins 用内网地址）。  
2. 保存为文件，例如 `~/.kube/config-ack-alien`。  
3. Jenkins 凭据类型 **Secret file**，ID 如 `ack-kubeconfig-alien`。  
4. 流水线中：`withCredentials([file(credentialsId: 'ack-kubeconfig-alien', variable: 'KUBECONFIG')]) { sh 'kubectl get ns' }`。

### 3. Harbor 与 ACK 拉镜像

1. Harbor 项目 `alien` 设为 **私有**，创建 **机器人账号**（push + pull）。  
2. ACK 命名空间创建 **imagePullSecret**（见 `k8s/examples/secret-harbor.example.yaml`）。  
3. 各 Deployment `spec.template.spec.imagePullSecrets` 引用该 Secret。  
4. 在 **每台节点** 或仅依赖 K8S Secret：推荐只用 `imagePullSecrets`，无需节点 docker login。  
5. 将 Jenkins 机构建用的基础镜像 `my-openjdk8-ffmpeg:v1` 推送到 Harbor，例如：  
   `docker tag my-openjdk8-ffmpeg:v1 39.106.135.88/alien/base/openjdk8-ffmpeg:v1`  
   `docker push 39.106.135.88/alien/base/openjdk8-ffmpeg:v1`

---

## 二、推荐 K8S 资源模型

```text
Namespace: alien-produ
├── Deployment/gateway          (stable, 副本数 N)
├── Deployment/gateway-canary   (灰度, 副本数 1~2，仅 canary 策略时更新)
├── Service/gateway             → stable Pod
├── Service/gateway-canary      → canary Pod
├── Ingress/alien-gateway       → 主路由 + Nginx 灰度注解
└── ConfigMap/Secret              → bootstrap、Jasypt（勿把明文密码提交 Git）
```

Java 微服务端口与现网 compose 一致（gateway **8000**，store **50014**，…），见各 `deployment-*.yaml`。

**配置中心**：ACK 上 Nacos 若仍用 39.106.135.88 上的实例，须在 Pod 环境变量或 `bootstrap-prod.yml` 中写 **可达的 K8S Service 地址或 SLB**，不能写 Docker 容器名 `nacos`（除非 Nacos 也迁进同一集群）。

---

## 三、灰度发布（推荐：Nginx Ingress 金丝雀）

ACK 控制台 → **应用** → **Ingress** 需已安装 **Nginx Ingress Controller**（应用市场「Nginx Ingress Controller」或「ALB Ingress」；下文以 **Nginx Ingress 注解** 为例，与仓库示例一致）。

### 原理

```mermaid
flowchart LR
  User[客户端] --> Ing[Ingress alien-gateway]
  Ing -->|权重 90%| SvcStable[Service gateway]
  Ing -->|权重 10%| SvcCanary[Service gateway-canary]
  SvcStable --> DepStable[Deployment gateway]
  SvcCanary --> DepCanary[Deployment gateway-canary]
```

- **stable**：当前线上版本，副本数较多。  
- **canary**：新版本，副本数少。  
- **Ingress** 通过注解 `canary` + `canary-weight` 按百分比分流。  

### 操作步骤（与 Jenkins 参数联动）

1. **首次**：`kubectl apply -f k8s/examples/namespace.yaml`  
2. **首次**：`kubectl apply -f k8s/examples/deployment-gateway.yaml`（及 stable Service）  
3. **首次**：`kubectl apply -f k8s/examples/deployment-gateway-canary.yaml` + `service-gateway-canary.yaml`  
4. **首次**：`kubectl apply -f k8s/examples/ingress-gateway-canary.example.yaml`（改 host、TLS）  
5. Jenkins 构建新镜像 `39.106.135.88/alien/gateway:build-42`  
6. Job 选 **DEPLOY_STRATEGY=canary**，**CANARY_WEIGHT=10**：  
   - 仅更新 `gateway-canary` Deployment 镜像  
   - 将 Ingress 注解 `canary-weight` 设为 `10`  
7. 观察监控与错误率后，逐步提高 `20` → `50` → `100`  
8. **全量**：将 **stable** Deployment 镜像改为新版本，**canary-weight 置 0** 或删除 canary Deployment，避免长期双轨  

示例注解（完整见 `ingress-gateway-canary.example.yaml`）：

```yaml
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
```

### 与 RollingUpdate 的区别

| 方式 | K8S 内置 RollingUpdate | Ingress 灰度（本方案） |
|------|------------------------|-------------------------|
| 流量 | 逐 Pod 替换，旧版 Pod 逐渐减少 | 新旧版本 **同时** 接流量，可调比例 |
| 回滚 | `kubectl rollout undo` | 将 `canary-weight` 设为 `0` 或回滚 canary Deployment |
| Jenkins | `DEPLOY_STRATEGY=rolling` | `DEPLOY_STRATEGY=canary` |

---

## 四、三节点节点池容量建议

当前约 **25 核 / 45Gi** 集群总量（控制台资源监控）。7 个 Java 服务若各 **2 副本** + 灰度 **1 副本**，峰值 Pod 数约 **7×3=21**，需控制每 Pod **request**（示例 manifest 中 `512Mi`/`250m`），避免 Pending。

调度建议：

- 无状态服务：**podAntiAffinity** 尽量 spread 到 3 台（示例 deployment 已含软反亲和）  
- **gateway** 可 2 副本 + HPA（需 metrics-server；控制台若提示 APIService `metrics.k8s.io` 不可用，先装 metrics-server 再开 HPA）  
- **job**、定时任务类可 1 副本  

---

## 五、从 Docker Compose 迁到 ACK 的映射

| Compose（39.105.153.68 produ） | ACK |
|------------------------------|-----|
| `gateway-produ` 容器 | Deployment `gateway` |
| 卷挂载 jar | 镜像内打包 jar（本流水线 Dockerfile） |
| `common-network-produ` | ClusterIP Service + Ingress |
| 环境变量 Jasypt | Secret `alien-jasypt` 或 ACK 配置项 |
| 支付证书目录 | Secret volume `alien-pay-cert-store` 等 |

迁移动作顺序建议：**gateway → store → 其余**；每迁一个服务，Ingress 切一条 path 或子域名，保留 compose 回滚路径直至稳定。

---

## 六、阿里云 ACK 控制台常用入口

| 目标 | 路径 |
|------|------|
| 工作负载 / Deployment | 集群 → 工作负载 → 无状态 |
| 灰度 / Ingress | 集群 → 网络 → Ingress |
| 镜像拉取失败事件 | 工作负载 → Pod → 事件 |
| 日志 | 工作负载 → Pod → 日志；或接入 SLS |
| 节点池扩容 | 节点管理 → default-nodepool → 扩容 |

---

## 七、与 Jenkins produ 流水线联调

1. 手工 `kubectl apply` 示例 manifest 一次。  
2. 跑通 `gateway-k8s` Job（rolling，权重 100% 等价全量）。  
3. 再跑 `canary` + `CANARY_WEIGHT=5` 验证流量分裂。  
4. 其余 6 个服务复制 gateway 的 Ingress/Deployment 命名模式。  

问题排查：`kubectl describe pod -n alien-produ`、`kubectl logs -n alien-produ deploy/gateway-canary`。
