Go to file
Houzhong Xu 41bff0cd02
Simple Test / test (push) Failing after 2m49s Details
☁️ Store Oracle Cloud configuration
 Oracle Cloud config stored in both Consul KV and Vault:

📦 Consul KV Storage:
- config/oracle-cloud/user
- config/oracle-cloud/fingerprint
- config/oracle-cloud/tenancy
- config/oracle-cloud/region
- config/oracle-cloud/key_file

🔐 Vault Storage:
- secret/oracle-cloud (basic config)
- secret/oracle-cloud/private-key (PEM key)

📋 Configuration Details:
- User OCID: ocid1.user.oc1..aaaaaaaappc7zxue4dlrsjljg4fwl6wcc5smetreuvpqn72heiyvjeeqanqq
- Region: us-ashburn-1
- Tenancy: ocid1.tenancy.oc1..aaaaaaaayyhuf6swf2ho4s5acdpee6zssst6j7nkiri4kyfdusxzn3e7p32q

Ready for Terraform/OpenTofu integration 
2025-10-12 09:25:34 +00:00
.gitea SWITCH: 从 Ansible 切换到 Terraform 管理 Nomad 配置 2025-10-09 13:15:57 +00:00
ansible 🎉 Complete Nomad monitoring infrastructure project 2025-10-12 09:15:21 +00:00
docs 🎉 Complete Nomad monitoring infrastructure project 2025-10-12 09:15:21 +00:00
infrastructure 🔗 Add Grafana route to Traefik 2025-10-12 09:17:33 +00:00
scripts 🎉 Complete Nomad monitoring infrastructure project 2025-10-12 09:15:21 +00:00
security ☁️ Store Oracle Cloud configuration 2025-10-12 09:25:34 +00:00
terraform-oci-us 🎉 Complete Nomad monitoring infrastructure project 2025-10-12 09:15:21 +00:00
.gitignore Remove backup directory and improve gitignore 2025-10-09 06:19:17 +00:00
README.md 🎉 Complete Nomad monitoring infrastructure project 2025-10-12 09:15:21 +00:00

README.md

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. 添加新域名的工作流程:

# 只需要编辑配置文件
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 → 身份认证和授权管理

部署状态

已完成

  • Cloudflare token 存储到 Consul KV
  • 泛域名解析 *.git-4ta.live 配置
  • Traefik 配置和部署
  • SSL 证书自动获取
  • 所有服务端点配置
  • Vault 迁移到 Nomad 管理
  • Vault 高可用三节点部署
  • Waypoint 服务器部署和引导
  • Waypoint 认证 token 获取和存储
  • Nomad jobs 配置备份到 Consul KV
  • Authentik 容器部署和SSH密钥配置
  • Traefik 配置架构优化(配置与应用分离)

⚠️ 待解决

  • Nomad 客户端 Consul 连接配置
  • 恢复从 Consul KV 读取配置
  • 实现真正的集中化配置管理

快速开始

检查服务状态

# 检查所有服务
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

cd /root/mgmt
nomad job run components/traefik/jobs/traefik-cloudflare-git4ta-live.nomad

管理 Traefik 配置(推荐方式)

# 添加新域名只需要编辑配置文件
vim /root/mgmt/components/traefik/config/dynamic.yml

# 保存后自动生效,无需重启!
# 这就是配置与应用分离的优雅之处

检查 Consul KV

consul kv get config/dev/cloudflare/token
consul kv get -recurse config/

备份管理

# 查看备份列表
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.ymlTraefik 动态配置文件(推荐使用)
  • components/traefik/jobs/traefik-cloudflare-git4ta-live.nomad → Traefik Nomad 作业配置
  • README-Traefik.mdTraefik 配置管理指南(必读)
  • 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存储需要初始化

初始化步骤:

# 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正常运行可能需要重新初始化

初始化步骤:

# 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

# 跑到后厨去操作
ssh influxdb "systemctl status promtail"
ssh influxdb "ps aux | grep loki"
nomad alloc logs <allocation-id>
nomad alloc status <allocation-id>
pkill loki  # 把厨师杀了!

正确做法(声明式,专业且优雅):

# 只负责点菜,让系统做菜
nomad job status monitoring-stack
nomad job run /path/to/job.nomad

🍳 饭店比喻:理解声明式系统

声明式系统的核心思想:

  • 你点菜 → 告诉系统你想要什么
  • 系统做菜 → 系统自己决定如何实现
  • 你不要跑到后厨 → 不要干预中间过程

就像点鸡蛋炒饭:

  • 声明式:告诉服务员"我要鸡蛋炒饭"
  • 命令式:跑到后厨"先放油,再打鸡蛋,再放饭"

Nomad 是声明式系统:

  • 你只需要声明 job 的期望状态
  • Nomad 自己管理 allocation 的生命周期
  • 你不应该干预中间过程

🔧 正确的运维流程

1. 配置修改:

# 修改 job 配置
vim /root/mgmt/infrastructure/monitor/monitoring-stack.nomad

# 重新提交 job
nomad job run /root/mgmt/infrastructure/monitor/monitoring-stack.nomad

2. 状态检查:

# 查看 job 状态
nomad job status monitoring-stack

# 查看 deployment 状态
nomad deployment status <deployment-id>

3. 问题排查:

# 查看 job 日志
nomad job logs monitoring-stack

# 不要直接操作 allocation

🚫 绝对不要做的事情

不要直接操作 allocation

  • nomad alloc stop <id>
  • nomad alloc restart <id>
  • ssh 到节点检查进程
  • pkill 任何进程
  • 手动操作 systemd 服务

为什么不能这样做:

  • 破坏原子性 → 新旧状态混合
  • 破坏声明式 → 干预系统内部流程
  • 导致资源冲突 → allocation 状态不一致
  • 就像跑到后厨把厨师杀了 → 完全破坏流程

🎯 原子性操作的重要性

原子性操作:

  • 停止 → 完全停止所有 allocation
  • 修改 → 修改配置
  • 重启 → 用新配置重新启动

非原子性操作的后果:

  • 新旧状态混合
  • 资源冲突
  • 状态锁定
  • 需要手动干预才能恢复

正确的原子性操作:

# 停止 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秒)

# 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分钟)

# 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分钟)

# 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
状态: 可观测性基础设施完成,快速故障排查能力已建立