基本框架

This commit is contained in:
2026-03-21 04:36:06 +08:00
commit de1be1dbe5
125 changed files with 10302 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
# 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`