Files
Deploy-Laboratory/docs/02-05-nginx-验证矩阵-一键部署.md
2026-03-21 04:36:06 +08:00

203 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 02-05 Nginx 验证矩阵Ingress / IngressRoute— 综合一键部署
> **定位**02 系列尾部,整合 02-0102-04 的综合一键部署。4 种组合(控制节点/工作节点 × Ingress/IngressRoute均有具体 Deployment + Service + 路由,节点 IP 访问(如 `http://入口IP/demo-m1/`)。
## 前置条件
- 已完成 `01-02-k3s-工作节点.md`Traefik 与 LB 可用)
- **M1**Deployment 需含 `nodeSelector: node-role.kubernetes.io/control-plane: ""` 及控制平面污点的 **toleration**(见下 YAML否则控制节点若有 `NoSchedule` 污点会导致 Pod 一直 Pending、访问 /demo-m1 报 "no available server";若控制节点无该标签,需先打标或改 M1 为 hostname同 M2
- **M2**Deployment 必须含 `nodeSelector: kubernetes.io/hostname: <控制节点名>`(示例 `ylc61`),按实际修改
- **M3**Deployment 含 `nodeSelector: node-role.kubernetes.io/worker: ""`,随机调度到任一工作节点;需工作节点有该标签
- **M4**Deployment 必须含 `nodeSelector: kubernetes.io/hostname: ylc64`(指定工作节点),按实际修改
## 部署说明Pod、路径
| 场景 | 路径 | 说明 |
| ---------------------- | ---------- | ----------------- |
| M1 控制节点 + Ingress | `/demo-m1` | nginx-m1随机一台控制节点 |
| M2 控制节点 + IngressRoute | `/demo-m2` | nginx-m2指定一台控制节点 |
| M3 工作节点 + Ingress | `/demo-m3` | nginx-m3随机一台工作节点 |
| M4 工作节点 + IngressRoute | `/demo-m4` | nginx-m4指定一台工作节点 |
## 完整配置(与 Ansible 共用)
配置位于 `ansible/files/nginx-matrix/`4 个文件对应 M1M4文档与 Ansible 共用此目录:
| 文件 | 场景 | 路径 | 节点 |
|------|------|------|------|
| 01-control-ingress.yaml | M1 控制+Ingress | /demo-m1 | nodeSelector control-plane + toleration |
| 02-control-ingressroute.yaml | M2 控制+IngressRoute | /demo-m2 | hostname 指定(默认 ylc61 |
| 03-worker-ingress.yaml | M3 工作+Ingress | /demo-m3 | nodeSelector worker随机 |
| 04-worker-ingressroute.yaml | M4 工作+IngressRoute | /demo-m4 | hostname 指定(默认 ylc64 |
按需修改 **M2**`ylc61`)、**M4**`ylc64`)的 hostname**M3** 需工作节点有 `node-role.kubernetes.io/worker` 标签。计算机名使用短主机名ylc61ylc64便于配合 Cloudflare CDN。
## 部署
```bash
kubectl apply -f ansible/files/nginx-matrix/ -R
kubectl get pod,svc,ing,ingressroute -n default -o wide
```
## 验证(用 IP 访问)
直接用入口节点 IP 访问(将 `192.168.2.61` 改为你的入口 IP按 01-02/01-07 已配 LB 时任选节点 IP
```bash
for path in demo-m1 demo-m2 demo-m3 demo-m4; do
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 3 "http://192.168.2.61/${path}/" 2>/dev/null || echo "---")
echo "/${path}/: ${code}"
done
```
预期4 个路径均返回 `200`,页面分别显示 **M1**、**M2**、**M3**、**M4**及对应说明、Backend: M1 等),便于区分是哪个后端。
### M1 仍显示 nginx 欢迎页时:进入容器排查
**若访问 /demo-m1 报 "no available server"**:多为 M1 Pod 未调度PendingService 无 endpoint。控制节点常有 `node-role.kubernetes.io/control-plane:NoSchedule` 污点Deployment 需加上述 **toleration** 才能调度。可用下面命令逐项检查:
```bash
# 1. M1 Pod 是否存在、是否 RunningPending 说明未调度)
kubectl get pod -n default -l app=nginx-m1 -o wide
# 2. M1 Service 是否有 endpoint无 endpoint 则 Traefik 报 no available server
kubectl get endpoints -n default nginx-m1
# 3. 若 Pod 为 Pending看调度失败原因Events 里会写 taint/未满足)
kubectl describe pod -n default -l app=nginx-m1
# 4. 确认控制节点标签与污点M1 需调度到带 control-plane 的节点,且 Deployment 需有对应 toleration
kubectl get nodes -o custom-columns=NAME:.metadata.name,LABEL:.metadata.labels.node-role\.kubernetes\.io/control-plane,TAINT:.spec.taints
```
若 Events 为 **`node(s) didn't match Pod's node affinity/selector`**:说明没有任何节点带 `node-role.kubernetes.io/control-plane` 标签,需给控制节点打标(控制节点一般为运行 k3s server 的那台,如 ylc61
```bash
# 先看节点名kubectl get nodes
# 再给控制节点打标(把 ylc61 换成实际控制节点名)
kubectl label node ylc61 node-role.kubernetes.io/control-plane= --overwrite
```
打标后 M1 Pod 会自动调度到该节点并 Running若仍 Pending再执行一次 `kubectl get pod -n default -l app=nginx-m1 -o wide``kubectl describe pod -n default -l app=nginx-m1` 看 Events。
下面为"M1 能访问但仍是默认页"时的容器内排查。在**已配置 KUBECONFIG 的机器**上执行(将 `KUBECONFIG` 改为实际路径,如 `/etc/rancher/k3s/k3s.yaml`
```bash
# 1. 看 html 目录下有哪些文件(是否包含我们挂的 index.html
kubectl exec -n default deployment/nginx-m1 -- ls -la /usr/share/nginx/html/
# 2. 看 index.html 内容(应是 M1 的 HTML若仍是 Welcome to nginx 说明挂载未生效)
kubectl exec -n default deployment/nginx-m1 -- cat /usr/share/nginx/html/index.html
# 3. 看 conf.d 下有哪些配置(是否有多个 server或 default.conf 被覆盖)
kubectl exec -n default deployment/nginx-m1 -- ls -la /etc/nginx/conf.d/
# 4. 看 default.conf 内容(应含 root、index、X-Backend M1
kubectl exec -n default deployment/nginx-m1 -- cat /etc/nginx/conf.d/default.conf
# 5. 看 nginx 最终生效的 server 配置(确认谁在监听 80、root 指向哪)
kubectl exec -n default deployment/nginx-m1 -- nginx -T 2>&1 | grep -A 200 "server {"
```
**根据输出可判断**:若 `index.html` 仍是默认欢迎页 → ConfigMap/volumeMount 未生效或未覆盖到该路径;若 `conf.d/` 下有多于一个 `*.conf``default.conf` 不是我们的内容 → 配置被覆盖或未挂载;若 `nginx -T` 里 80 端口的 `root` 不是 `/usr/share/nginx/html` 或没有我们的 `location` → 被其他 server 块优先。把上述命令的输出贴出后,即可针对性改 manifest 或挂载方式。
**为何 M1M4 都是单文件subPath挂载却只有 M1 不正常?**
Manifest 里四份写法一致,若只有 M1 仍显示默认页,多半是集群里 nginx-m1 的 Deployment/ReplicaSet 曾用旧 spec 部署过,导致当前 Pod 未带 volumeMount。根因未查清时最稳妥是**删除 M1 部署再重新部署**(见下)。
**单文件部署(按目录 apply 全部 M1M4**
```bash
# 在仓库根目录执行时:
kubectl apply -f ansible/files/nginx-matrix/ -R
# 若当前在 ansible/ 目录下,改用:
kubectl apply -f files/nginx-matrix/ -R
```
**M1 未生效时:删除部署再重新部署(推荐)**
先删 M1 的 Deployment再 apply 01这样会新建唯一的 ReplicaSet不会留下旧 spec 的 Pod。
```bash
# 1. 只删 M1 的 DeploymentService/Ingress/Middleware/ConfigMap 保留,稍后 apply 会复用或更新)
kubectl delete deployment nginx-m1 -n default
# 2. 重新部署 M1在 ansible/ 目录下)
kubectl apply -f files/nginx-matrix/01-control-ingress.yaml
# 若在仓库根目录:
# kubectl apply -f ansible/files/nginx-matrix/01-control-ingress.yaml
# 3. 等 Pod Running 后验证
kubectl get pod -n default -l app=nginx-m1
kubectl exec -n default deployment/nginx-m1 -- cat /usr/share/nginx/html/index.html
kubectl exec -n default deployment/nginx-m1 -- cat /etc/nginx/conf.d/default.conf
```
使用 Ansible 部署时playbook 会自动跑一遍上述诊断并打印「M1 容器内诊断结果」,便于直接查看。
## Ansible 一键部署
可使用 Ansible playbook 自动完成复制 manifests、apply、等待 Pod 就绪及 curl 验证:
- **Playbook**`ansible/playbooks/nginx-matrix-deploy.yml`
- **Manifests 位置**`ansible/files/nginx-matrix/`M1 control-plane / M2 M4 节点名 ylc61、ylc64M3 worker按实际修改 M2/M4 节点名)
- **执行(在 ansible/ 目录下)**
```bash
cd ansible
ansible-playbook -i inventory.ini playbooks/nginx-matrix-deploy.yml
```
若 manifests 目录未找到,可改为在仓库根目录执行:
```bash
ansible-playbook -i ansible/inventory.ini ansible/playbooks/nginx-matrix-deploy.yml
```
Playbook 会:拷贝 manifests 到控制节点 → **先删除全部 nginx 矩阵 Deployment**nginx-m1m4若存在`kubectl apply``rollout restart` M1M4 → 等待 Pod 就绪 → 输出 16 个目标4 节点 × 4 路径)的 curl 矩阵。先删再 apply 可避免旧 ReplicaSet 导致任一 Mx 仍显示默认页。
## 删除
**手动 kubectl apply 的**:用同一目录删除
```bash
kubectl delete -f ansible/files/nginx-matrix/ -R
```
**Ansible playbook 部署的**:在仓库根或 ansible 同级的机器上,用 manifests 删除(需配置 KUBECONFIG
```bash
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml # 或从控制节点拷贝 kubeconfig
kubectl delete -f ansible/files/nginx-matrix/ -R
```
若控制节点上 `/tmp/nginx-matrix/` 仍存在,也可在控制节点执行:
```bash
sudo kubectl delete -f /tmp/nginx-matrix/ -R
```
**按资源名删除**(适用于 manifests 已不可用)
```bash
kubectl delete deployment,svc,ingress -n default nginx-m1 nginx-m2 nginx-m3 nginx-m4
kubectl delete ingressroute -n default nginx-m2 nginx-m4
kubectl delete middleware -n default stripprefix-m1 stripprefix-m2 stripprefix-m3 stripprefix-m4
kubectl delete configmap -n default nginx-m1-html nginx-m2-html nginx-m3-html nginx-m4-html
```
## 下一步
- `03-01-k3s-traefik-dashboard.md`Dashboard
- `03-02-k3s-traefik-acme.md`
- 返回 `00-00-构建总览.md` 按导航继续
## 相关文档
- `02-01``02-04`:分篇说明(路径 /demo-m1m4、nodeSelector 与本文一致)
- `03-02-k3s-traefik-acme.md`
- `06-01-k3s-networkpolicy-故障排查.md`