535 lines
16 KiB
Markdown
535 lines
16 KiB
Markdown
# Management Infrastructure
|
||
|
||
## 🚨 关键问题记录
|
||
|
||
### Nomad Consul KV 模板语法问题
|
||
|
||
**问题描述:**
|
||
Nomad 无法从 Consul KV 读取配置,报错:`Missing: kv.block(config/dev/cloudflare/token)`
|
||
|
||
**根本原因:**
|
||
1. **Nomad 客户端未配置 Consul 连接** - Nomad 无法访问 Consul KV
|
||
2. **模板语法正确** - `{{ key "path/to/key" }}` 是正确语法
|
||
3. **Consul KV 数据存在** - `config/dev/cloudflare/token` 确实存在
|
||
|
||
**解决方案:**
|
||
1. **临时方案** - 硬编码 token 到配置文件中
|
||
2. **长期方案** - 配置 Nomad 客户端连接 Consul
|
||
|
||
**核心诉求:**
|
||
- **集中化存储** → Consul KV 存储所有敏感配置
|
||
- **分散化部署** → Nomad 从 Consul 读取配置部署到多节点
|
||
- **直接读取** → Nomad 模板系统直接从 Consul KV 读取配置
|
||
|
||
**当前状态:**
|
||
- ✅ Consul KV 存储正常
|
||
- ✅ Traefik 服务运行正常
|
||
- ❌ Nomad 无法读取 Consul KV(需要配置连接)
|
||
|
||
**下一步:**
|
||
1. 配置 Nomad 客户端连接 Consul
|
||
2. 恢复模板语法从 Consul KV 读取配置
|
||
3. 实现真正的集中化配置管理
|
||
|
||
---
|
||
|
||
## 🎯 Traefik 配置架构:配置与应用分离的最佳实践
|
||
|
||
### ⚠️ 重要:避免低逼格操作
|
||
|
||
**❌ 错误做法(显得很low):**
|
||
- 修改Nomad job文件来添加新域名
|
||
- 重新部署整个Traefik服务
|
||
- 把配置嵌入在应用定义中
|
||
|
||
**✅ 正确做法(优雅且专业):**
|
||
|
||
### 配置文件分离架构
|
||
|
||
**1. 配置文件位置:**
|
||
- **动态配置**: `/root/mgmt/components/traefik/config/dynamic.yml`
|
||
- **应用配置**: `/root/mgmt/components/traefik/jobs/traefik-cloudflare-git4ta-live.nomad`
|
||
|
||
**2. 关键特性:**
|
||
- ✅ **热重载**: Traefik配置了`file`提供者,支持`watch: true`
|
||
- ✅ **自动生效**: 修改YAML配置文件后自动生效,无需重启
|
||
- ✅ **配置分离**: 配置与应用完全分离,符合最佳实践
|
||
|
||
**3. 添加新域名的工作流程:**
|
||
```bash
|
||
# 只需要编辑配置文件
|
||
vim /root/mgmt/components/traefik/config/dynamic.yml
|
||
|
||
# 添加新的路由配置
|
||
routers:
|
||
new-service-ui:
|
||
rule: "Host(`new-service.git-4ta.live`)"
|
||
service: new-service-cluster
|
||
entryPoints:
|
||
- websecure
|
||
tls:
|
||
certResolver: cloudflare
|
||
|
||
# 保存后立即生效,无需重启!
|
||
```
|
||
|
||
**4. 架构优势:**
|
||
- 🚀 **零停机时间**: 配置变更无需重启服务
|
||
- 🔧 **灵活管理**: 独立管理配置和应用
|
||
- 📝 **版本控制**: 配置文件可以独立版本管理
|
||
- 🎯 **专业标准**: 符合现代DevOps最佳实践
|
||
|
||
**记住:配置与应用分离是现代基础设施管理的核心原则!**
|
||
|
||
---
|
||
|
||
## 架构概览
|
||
|
||
### 集中化 + 分散化架构
|
||
|
||
**集中化存储:**
|
||
- **Consul KV** → 存储所有敏感配置(tokens、证书、密钥)
|
||
- **Consul Service Discovery** → 服务注册和发现
|
||
- **Consul Health Checks** → 服务健康检查
|
||
|
||
**分散化部署:**
|
||
- **亚洲节点** → `warden.tailnet-68f9.ts.net` (北京)
|
||
- **亚洲节点** → `ch4.tailnet-68f9.ts.net` (韩国)
|
||
- **美洲节点** → `ash3c.tailnet-68f9.ts.net` (美国)
|
||
|
||
### 服务端点
|
||
|
||
- `https://consul.git-4ta.live` → Consul UI
|
||
- `https://traefik.git-4ta.live` → Traefik Dashboard
|
||
- `https://nomad.git-4ta.live` → Nomad UI
|
||
- `https://vault.git-4ta.live` → Vault UI
|
||
- `https://waypoint.git-4ta.live` → Waypoint UI
|
||
- `https://authentik.git-4ta.live` → Authentik 身份认证
|
||
|
||
### 技术栈
|
||
|
||
- **Nomad** → 工作负载编排
|
||
- **Consul** → 服务发现和配置管理
|
||
- **Traefik** → 反向代理和负载均衡
|
||
- **Cloudflare** → DNS 和 SSL 证书管理
|
||
- **Waypoint** → 应用部署平台
|
||
- **Authentik** → 身份认证和授权管理
|
||
|
||
---
|
||
|
||
## 部署状态
|
||
|
||
### ✅ 已完成
|
||
- [x] Cloudflare token 存储到 Consul KV
|
||
- [x] 泛域名解析 `*.git-4ta.live` 配置
|
||
- [x] Traefik 配置和部署
|
||
- [x] SSL 证书自动获取
|
||
- [x] 所有服务端点配置
|
||
- [x] Vault 迁移到 Nomad 管理
|
||
- [x] Vault 高可用三节点部署
|
||
- [x] Waypoint 服务器部署和引导
|
||
- [x] Waypoint 认证 token 获取和存储
|
||
- [x] Nomad jobs 配置备份到 Consul KV
|
||
- [x] Authentik 容器部署和SSH密钥配置
|
||
- [x] Traefik 配置架构优化(配置与应用分离)
|
||
|
||
### ⚠️ 待解决
|
||
- [ ] Nomad 客户端 Consul 连接配置
|
||
- [ ] 恢复从 Consul KV 读取配置
|
||
- [ ] 实现真正的集中化配置管理
|
||
|
||
---
|
||
|
||
## 快速开始
|
||
|
||
### 检查服务状态
|
||
```bash
|
||
# 检查所有服务
|
||
curl -k -I https://consul.git4ta.tech
|
||
curl -k -I https://traefik.git4ta.tech
|
||
curl -k -I https://nomad.git4ta.tech
|
||
curl -k -I https://waypoint.git4ta.tech
|
||
```
|
||
|
||
### 部署 Traefik
|
||
```bash
|
||
cd /root/mgmt
|
||
nomad job run components/traefik/jobs/traefik-cloudflare-git4ta-live.nomad
|
||
```
|
||
|
||
### 管理 Traefik 配置(推荐方式)
|
||
```bash
|
||
# 添加新域名只需要编辑配置文件
|
||
vim /root/mgmt/components/traefik/config/dynamic.yml
|
||
|
||
# 保存后自动生效,无需重启!
|
||
# 这就是配置与应用分离的优雅之处
|
||
```
|
||
|
||
### 检查 Consul KV
|
||
```bash
|
||
consul kv get config/dev/cloudflare/token
|
||
consul kv get -recurse config/
|
||
```
|
||
|
||
### 备份管理
|
||
```bash
|
||
# 查看备份列表
|
||
consul kv get backup/nomad-jobs/index
|
||
|
||
# 查看最新备份信息
|
||
consul kv get backup/nomad-jobs/20251004/metadata
|
||
|
||
# 恢复备份
|
||
consul kv get backup/nomad-jobs/20251004/data > restore.tar.gz
|
||
tar -xzf restore.tar.gz
|
||
```
|
||
|
||
---
|
||
|
||
## 重要文件
|
||
|
||
- `components/traefik/config/dynamic.yml` → **Traefik 动态配置文件(推荐使用)**
|
||
- `components/traefik/jobs/traefik-cloudflare-git4ta-live.nomad` → Traefik Nomad 作业配置
|
||
- `README-Traefik.md` → **Traefik 配置管理指南(必读)**
|
||
- `infrastructure/opentofu/environments/dev/` → Terraform 基础设施配置
|
||
- `deployment/ansible/inventories/production/hosts` → 服务器清单
|
||
- `README-Vault.md` → Vault 配置和使用说明
|
||
- `README-Waypoint.md` → Waypoint 配置和使用说明
|
||
- `README-Backup.md` → 备份管理和恢复说明
|
||
- `nomad-jobs/vault-cluster.nomad` → Vault Nomad 作业配置
|
||
- `waypoint-server.nomad` → Waypoint Nomad 作业配置
|
||
|
||
---
|
||
|
||
## 🔧 服务初始化说明
|
||
|
||
### Vault 初始化
|
||
|
||
**当前状态:** Vault使用本地file存储,需要初始化
|
||
|
||
**初始化步骤:**
|
||
```bash
|
||
# 1. 检查vault状态
|
||
curl -s http://warden.tailnet-68f9.ts.net:8200/v1/sys/health
|
||
|
||
# 2. 初始化vault(如果返回"no available server")
|
||
vault operator init -address=http://warden.tailnet-68f9.ts.net:8200
|
||
|
||
# 3. 保存unseal keys和root token
|
||
# 4. 解封vault
|
||
vault operator unseal -address=http://warden.tailnet-68f9.ts.net:8200 <unseal-key-1>
|
||
vault operator unseal -address=http://warden.tailnet-68f9.ts.net:8200 <unseal-key-2>
|
||
vault operator unseal -address=http://warden.tailnet-68f9.ts.net:8200 <unseal-key-3>
|
||
```
|
||
|
||
**🔑 Vault 密钥信息 (2025-10-04 最终初始化):**
|
||
```
|
||
Unseal Key 1: 5XQ6vSekewZj9SigcIS8KcpnsOyEzgG5UFe/mqPVXkre
|
||
Unseal Key 2: vmLu+Ry+hajWjQhX3YVnZG72aZRn5cowcUm5JIVtv/kR
|
||
Unseal Key 3: 3eDhfnHZnG9OT6RFOhpoK/aO5TghPypz4XPlXxFMm52F
|
||
Unseal Key 4: LWGkYB7qD3GPPc/nRuqKmMUiQex8ygYF1BkSXA1Tov3J
|
||
Unseal Key 5: rIidFy7d/SxcPOCrNy569VZ86I56oMQxqL7qVgM+PYPy
|
||
|
||
Root Token: hvs.OgVR2hEihbHM7qFxtFr7oeo3
|
||
```
|
||
|
||
**配置说明:**
|
||
- **存储**: file (本地文件系统)
|
||
- **路径**: `/opt/nomad/data/vault-storage` (持久化存储)
|
||
- **端口**: 8200
|
||
- **UI**: 启用
|
||
- **重要**: 已配置持久化存储,重启后密钥不会丢失
|
||
|
||
### Waypoint 初始化
|
||
|
||
**当前状态:** Waypoint正常运行,可能需要重新初始化
|
||
|
||
**初始化步骤:**
|
||
```bash
|
||
# 1. 检查waypoint状态
|
||
curl -I https://waypoint.git-4ta.live
|
||
|
||
# 2. 如果需要重新初始化
|
||
waypoint server init -server-addr=https://waypoint.git-4ta.live
|
||
|
||
# 3. 配置waypoint CLI
|
||
waypoint auth login -server-addr=https://waypoint.git-4ta.live
|
||
```
|
||
|
||
**配置说明:**
|
||
- **存储**: 本地数据库 `/opt/waypoint/waypoint.db`
|
||
- **端口**: HTTP 9701, gRPC 9702
|
||
- **UI**: 启用
|
||
|
||
### Consul 服务注册
|
||
|
||
**已注册服务:**
|
||
- ✅ **vault**: `vault.git-4ta.live` (tags: vault, secrets, kv)
|
||
- ✅ **waypoint**: `waypoint.git-4ta.live` (tags: waypoint, ci-cd, deployment)
|
||
- ✅ **consul**: `consul.git-4ta.live` (tags: consul, service-discovery)
|
||
- ✅ **traefik**: `traefik.git-4ta.live` (tags: traefik, proxy, load-balancer)
|
||
- ✅ **nomad**: `nomad.git-4ta.live` (tags: nomad, scheduler, orchestrator)
|
||
|
||
**健康检查:**
|
||
- **vault**: `/v1/sys/health`
|
||
- **waypoint**: `/`
|
||
- **consul**: `/v1/status/leader`
|
||
- **traefik**: `/ping`
|
||
- **nomad**: `/v1/status/leader`
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 🎯 Nomad 运维最佳实践:声明式 vs 命令式
|
||
|
||
### ⚠️ 重要:不要跑到后厨去!
|
||
|
||
**❌ 错误做法(命令式,显得很low):**
|
||
```bash
|
||
# 跑到后厨去操作
|
||
ssh influxdb "systemctl status promtail"
|
||
ssh influxdb "ps aux | grep loki"
|
||
nomad alloc logs <allocation-id>
|
||
nomad alloc status <allocation-id>
|
||
pkill loki # 把厨师杀了!
|
||
```
|
||
|
||
**✅ 正确做法(声明式,专业且优雅):**
|
||
```bash
|
||
# 只负责点菜,让系统做菜
|
||
nomad job status monitoring-stack
|
||
nomad job run /path/to/job.nomad
|
||
```
|
||
|
||
### 🍳 饭店比喻:理解声明式系统
|
||
|
||
**声明式系统的核心思想:**
|
||
- **你点菜** → 告诉系统你想要什么
|
||
- **系统做菜** → 系统自己决定如何实现
|
||
- **你不要跑到后厨** → 不要干预中间过程
|
||
|
||
**就像点鸡蛋炒饭:**
|
||
- ✅ **声明式**:告诉服务员"我要鸡蛋炒饭"
|
||
- ❌ **命令式**:跑到后厨"先放油,再打鸡蛋,再放饭"
|
||
|
||
**Nomad 是声明式系统:**
|
||
- 你只需要声明 job 的期望状态
|
||
- Nomad 自己管理 allocation 的生命周期
|
||
- 你不应该干预中间过程
|
||
|
||
### 🔧 正确的运维流程
|
||
|
||
**1. 配置修改:**
|
||
```bash
|
||
# 修改 job 配置
|
||
vim /root/mgmt/infrastructure/monitor/monitoring-stack.nomad
|
||
|
||
# 重新提交 job
|
||
nomad job run /root/mgmt/infrastructure/monitor/monitoring-stack.nomad
|
||
```
|
||
|
||
**2. 状态检查:**
|
||
```bash
|
||
# 查看 job 状态
|
||
nomad job status monitoring-stack
|
||
|
||
# 查看 deployment 状态
|
||
nomad deployment status <deployment-id>
|
||
```
|
||
|
||
**3. 问题排查:**
|
||
```bash
|
||
# 查看 job 日志
|
||
nomad job logs monitoring-stack
|
||
|
||
# 不要直接操作 allocation!
|
||
```
|
||
|
||
### 🚫 绝对不要做的事情
|
||
|
||
**不要直接操作 allocation:**
|
||
- ❌ `nomad alloc stop <id>`
|
||
- ❌ `nomad alloc restart <id>`
|
||
- ❌ `ssh` 到节点检查进程
|
||
- ❌ `pkill` 任何进程
|
||
- ❌ 手动操作 systemd 服务
|
||
|
||
**为什么不能这样做:**
|
||
- **破坏原子性** → 新旧状态混合
|
||
- **破坏声明式** → 干预系统内部流程
|
||
- **导致资源冲突** → allocation 状态不一致
|
||
- **就像跑到后厨把厨师杀了** → 完全破坏流程
|
||
|
||
### 🎯 原子性操作的重要性
|
||
|
||
**原子性操作:**
|
||
- **停止** → 完全停止所有 allocation
|
||
- **修改** → 修改配置
|
||
- **重启** → 用新配置重新启动
|
||
|
||
**非原子性操作的后果:**
|
||
- 新旧状态混合
|
||
- 资源冲突
|
||
- 状态锁定
|
||
- 需要手动干预才能恢复
|
||
|
||
**正确的原子性操作:**
|
||
```bash
|
||
# 停止 job(原子性)
|
||
nomad job stop monitoring-stack
|
||
|
||
# 修改配置
|
||
vim monitoring-stack.nomad
|
||
|
||
# 重新启动(原子性)
|
||
nomad job run monitoring-stack.nomad
|
||
```
|
||
|
||
### 📝 运维哲学
|
||
|
||
**声明式运维的核心原则:**
|
||
1. **只关心最终状态** → 不关心中间过程
|
||
2. **让系统自己管理** → 不要干预内部流程
|
||
3. **通过配置驱动** → 不要直接操作资源
|
||
4. **相信系统的能力** → 不要过度干预
|
||
|
||
**记住:**
|
||
- **你点菜,系统做菜**
|
||
- **不要跑到后厨去**
|
||
- **相信声明式系统的力量**
|
||
|
||
### 🎯 点菜宝系统:基础设施即代码的哲学
|
||
|
||
**点菜宝系统的本质:**
|
||
- **专门的终端/APP** - 标准化点菜流程
|
||
- **全流程监控** - 每个环节都可追溯
|
||
- **审计透明** - 港交所问询函都能应对
|
||
- **可回溯** - 整个流程有完整记录
|
||
|
||
**基础设施即代码(Infrastructure as Code)的核心:**
|
||
- **配置文件是王道** - 把配置搞定,系统就应该自动工作
|
||
- **不要越俎代庖** - 不要手动干预系统内部流程
|
||
- **可审计性** - 每个变更都有记录,可追溯
|
||
- **标准化流程** - 就像点菜宝一样,标准化操作
|
||
|
||
**运维人员的正确角色:**
|
||
- **点菜宝操作员** - 通过标准化界面操作
|
||
- **配置管理员** - 管理配置文件
|
||
- **流程记录员** - 记录每个操作和变更
|
||
- **不是厨师** - 不跑到后厨去炒菜
|
||
|
||
**真正的价值在于:**
|
||
- **可审计性** - 每个操作都有记录
|
||
- **可追溯性** - 能回溯到任何时间点
|
||
- **标准化** - 流程规范,符合上市要求
|
||
- **透明性** - 财务和操作完全透明
|
||
|
||
**专注的核心工作:**
|
||
- 配置文件管理
|
||
- 标准化操作流程
|
||
- 完整的变更记录
|
||
- 让系统自己工作
|
||
|
||
### 🎯 服务员的KPI:理解意图是第一优先级
|
||
|
||
**❌ 错误的服务员行为:**
|
||
- 听到几个关键词就立即行动
|
||
- 不确认完整需求就噼里啪啦操作
|
||
- 没有耐心听完客人的话
|
||
- 以为敲命令越多越好
|
||
|
||
**✅ 正确的服务员行为:**
|
||
- **耐心倾听** - 等客人说完整个需求
|
||
- **确认理解** - "先生,您是要...对吗?"
|
||
- **询问细节** - "有什么特殊要求吗?"
|
||
- **等待确认** - 得到确认后再行动
|
||
|
||
**正确的KPI标准:**
|
||
- ✅ **完全理解客人的意图** - 这是第一优先级
|
||
- ❌ **不是敲命令越多越好** - 这是错误的KPI
|
||
|
||
**服务流程:**
|
||
1. **耐心听完** - 不打断客人的话
|
||
2. **确认理解** - "我理解您要的是..."
|
||
3. **询问细节** - "还有什么需要注意的吗?"
|
||
4. **等待确认** - 得到确认后再行动
|
||
|
||
---
|
||
|
||
## 🚀 快速故障排查三板斧
|
||
|
||
### 🎯 系统故障时的标准排查流程
|
||
|
||
**当系统出现问题时,按以下顺序快速排查:**
|
||
|
||
#### **第一板斧:检查Prometheus健康状态 (30秒)**
|
||
```bash
|
||
# 1. 检查所有节点状态
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:9090/api/v1/query?query=up" | jq '.data.result[] | {instance: .metric.instance, up: .value[1]}'
|
||
|
||
# 2. 检查关键指标
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:9090/api/v1/query?query=node_load1" | jq '.data.result[] | {instance: .metric.instance, load1: .value[1]}'
|
||
|
||
# 3. 检查服务状态
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:9090/api/v1/query?query=up{job=~\"nomad|consul|traefik\"}" | jq '.data.result[]'
|
||
```
|
||
|
||
#### **第二板斧:查看Loki日志 (1分钟)**
|
||
```bash
|
||
# 1. 查看错误日志
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:3100/loki/api/v1/query_range?query={level=\"error\"}&start=$(date -d '1 hour ago' +%s)000000000&end=$(date +%s)000000000" | jq '.data.result[]'
|
||
|
||
# 2. 查看关键服务日志
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:3100/loki/api/v1/query_range?query={unit=~\"nomad|consul|traefik\"}&start=$(date -d '1 hour ago' +%s)000000000&end=$(date +%s)000000000" | jq '.data.result[]'
|
||
|
||
# 3. 查看特定节点日志
|
||
curl -s "http://influxdb.tailnet-68f9.ts.net:3100/loki/api/v1/query_range?query={hostname=\"节点名\"}&start=$(date -d '1 hour ago' +%s)000000000&end=$(date +%s)000000000" | jq '.data.result[]'
|
||
```
|
||
|
||
#### **第三板斧:Grafana可视化分析 (2分钟)**
|
||
```bash
|
||
# 1. 访问热点图Dashboard
|
||
# http://influxdb.tailnet-68f9.ts.net:3000/d/5e81473e-f8e0-4f1e-a0c6-bbcc5c4b87f0/loki-e697a5-e5bf97-e783ad-e782b9-e59bbe-demo
|
||
|
||
# 2. 查看指标相关性
|
||
# - 日志级别热点图:发现异常时间点
|
||
# - 节点日志密度:定位问题节点
|
||
# - 关键服务热点图:确认服务状态
|
||
# - ERROR/CRIT热点图:黑匣子分析
|
||
```
|
||
|
||
### 🎯 排查原则
|
||
|
||
**1. 时间优先:**
|
||
- 30秒内确认哪些节点/服务异常
|
||
- 1分钟内查看相关错误日志
|
||
- 2分钟内通过可视化分析根因
|
||
|
||
**2. 数据驱动:**
|
||
- 先看指标,再看日志
|
||
- 用数据说话,不要猜测
|
||
- 通过相关性分析找根因
|
||
|
||
**3. 系统化思维:**
|
||
- 不要跑到后厨去(不要直接操作节点)
|
||
- 通过可观测性工具分析
|
||
- 相信声明式系统的能力
|
||
|
||
### 📊 可观测性基础设施
|
||
|
||
**✅ 已完成的监控体系:**
|
||
- **Prometheus**: 13个节点指标收集
|
||
- **Loki**: 12个节点日志聚合
|
||
- **Grafana**: 热点图Dashboard + API访问
|
||
- **覆盖范围**: CPU, 内存, 磁盘, 网络, 负载, 服务状态
|
||
|
||
**🔑 API访问凭证:**
|
||
- **Grafana Token**: `glsa_Lu2RW7yPMmCtYrvbZLNJyOI3yE1LOH5S_629de57b`
|
||
- **保存位置**: `/root/mgmt/security/grafana-api-credentials.md`
|
||
|
||
---
|
||
|
||
**最后更新:** 2025-10-12 09:00 UTC
|
||
**状态:** 可观测性基础设施完成,快速故障排查能力已建立 |