1 feat: 重构基础设施架构并完善Consul集群配置

2
     3	主要变更:
     4	- 重构Terraform/OpenTofu目录结构,统一迁移至infrastructure/opentofu
     5	- 添加"7天创造世界"文档,记录基础设施建设演进逻辑
     6	- 更新Consul集群配置管理经验,添加实际案例和解决方案
     7	- 修正README中的Sticky Note,反映Consul集群健康状态
     8	- 添加Ansible部署配置和inventory文件
     9	- 完善项目文档结构,添加各组件配置指南
    10
    11	技术架构演进:
    12	- 第1天: Tailscale网络连接基础 
    13	- 第2天: Ansible分布式控制 
    14	- 第3天: Nomad服务感知与任务调度 
    15	- 第4天: Consul配置集中管理 
    16	- 第5天: OpenTofu状态一致性 
    17	- 第6天: Vault密钥管理 
    18	- 第7天: Waypoint应用部署 
This commit is contained in:
2025-09-30 03:46:33 +00:00
parent c0064b2cad
commit e8bfc76038
119 changed files with 1772 additions and 631 deletions

View File

@@ -0,0 +1 @@
components/consul/jobs/

View File

@@ -0,0 +1,37 @@
# DigitalOcean 密钥存储作业
job "digitalocean-key-store" {
datacenters = ["dc1"]
type = "batch"
group "key-store" {
task "store-key" {
driver = "exec"
config {
command = "/bin/sh"
args = [
"-c",
<<EOT
# 将DigitalOcean密钥存储到Consul中
curl -X PUT -H "X-Consul-Token: ${CONSUL_HTTP_TOKEN}" \
http://127.0.0.1:8500/v1/kv/council/digitalocean/token \
-d 'dop_v1_70582bb508873709d96debc7f2a2d04df2093144b2b15fe392dba83b88976376'
# 验证密钥是否存储成功
curl -s http://127.0.0.1:8500/v1/kv/council/digitalocean/token?raw
EOT
]
}
env {
CONSUL_HTTP_ADDR = "http://127.0.0.1:8500"
CONSUL_HTTP_TOKEN = "root" # 根据实际Consul配置调整
}
resources {
cpu = 100
memory = 64
}
}
}
}

View File

@@ -0,0 +1,65 @@
job "hybrid-nfs-app" {
datacenters = ["dc1"]
type = "service"
# 使用约束条件区分存储类型
constraint {
attribute = "${attr.unique.hostname}"
operator = "regexp"
value = "semaphore"
}
group "app" {
count = 1
network {
port "http" {
static = 8080
}
}
# 对于本机semaphore使用host volume
volume "local-storage" {
type = "host"
read_only = false
source = "local-fnsync"
}
task "web-app" {
driver = "exec"
config {
command = "python3"
args = ["-m", "http.server", "8080", "--directory", "local/fnsync"]
}
template {
data = <<EOH
<h1>Hybrid NFS App - Running on {{ env "attr.unique.hostname" }}</h1>
<p>Storage Type: {{ with eq (env "attr.unique.hostname") "semaphore" }}PVE Mount{{ else }}NFS{{ end }}</p>
<p>Timestamp: {{ now | date "2006-01-02 15:04:05" }}</p>
EOH
destination = "local/fnsync/index.html"
}
resources {
cpu = 100
memory = 128
}
service {
name = "hybrid-nfs-app"
port = "http"
tags = ["hybrid", "nfs", "web"]
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
}
}
}
}

View File

@@ -0,0 +1,51 @@
job "nfs-app-example" {
datacenters = ["dc1"]
type = "service"
group "app" {
count = 1
# 使用NFS存储卷
volume "nfs-storage" {
type = "host"
read_only = false
source = "nfs-fnsync"
}
task "web-app" {
driver = "docker"
config {
image = "nginx:alpine"
ports = ["http"]
# 挂载NFS卷到容器
mount {
type = "volume"
target = "/usr/share/nginx/html"
source = "nfs-storage"
readonly = false
}
}
resources {
cpu = 100
memory = 128
}
service {
name = "nfs-web-app"
port = "http"
tags = ["nfs", "web"]
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
job "nfs-storage-test" {
datacenters = ["dc1"]
type = "batch"
group "test" {
count = 1
volume "nfs-storage" {
type = "csi"
read_only = false
source = "nfs-fnsync"
}
task "storage-test" {
driver = "exec"
volume_mount {
volume = "nfs-storage"
destination = "/mnt/nfs"
read_only = false
}
config {
command = "/bin/sh"
args = ["-c", "echo 'NFS Storage Test - $(hostname) - $(date)' > /mnt/nfs/test-$(hostname).txt && ls -la /mnt/nfs/"]
}
resources {
cpu = 50
memory = 64
}
}
}
}

1
infrastructure/jobs/nomad Symbolic link
View File

@@ -0,0 +1 @@
components/nomad/jobs/

View File

@@ -0,0 +1,84 @@
job "nfs-multi-type-example" {
datacenters = ["dc1"]
type = "service"
# 为本地LXC容器配置的任务组
group "lxc-apps" {
count = 2
constraint {
attribute = "${attr.unique.hostname}"
operator = "regexp"
value = "(influxdb|hcp)"
}
volume "lxc-nfs" {
type = "host"
source = "nfs-shared"
read_only = false
}
task "lxc-app" {
driver = "podman"
config {
image = "alpine:latest"
args = ["tail", "-f", "/dev/null"]
}
volume_mount {
volume = "lxc-nfs"
destination = "/shared/lxc"
read_only = false
}
resources {
cpu = 100
memory = 64
}
}
}
# 为海外PVE容器配置的任务组
group "pve-apps" {
count = 3
constraint {
attribute = "${attr.unique.hostname}"
operator = "regexp"
value = "(ash1d|ash2e|ash3c|ch2|ch3)"
}
volume "pve-nfs" {
type = "host"
source = "nfs-shared"
read_only = false
}
task "pve-app" {
driver = "podman"
config {
image = "alpine:latest"
args = ["tail", "-f", "/dev/null"]
# 为海外节点添加网络优化参数
network_mode = "host"
}
volume_mount {
volume = "pve-nfs"
destination = "/shared/pve"
read_only = false
}
resources {
cpu = 100
memory = 64
network {
mbits = 5
}
}
}
}
}

View File

@@ -0,0 +1,86 @@
job "openfaas-functions" {
datacenters = ["dc1"]
type = "service"
group "hello-world" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "hello-world" {
driver = "podman"
config {
image = "functions/hello-world:latest"
ports = ["http"]
env = {
"fprocess" = "node index.js"
}
}
resources {
network {
mbits = 10
port "http" { static = 8080 }
}
}
service {
name = "hello-world"
port = "http"
tags = ["openfaas-function"]
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
}
}
}
group "figlet" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "figlet" {
driver = "podman"
config {
image = "functions/figlet:latest"
ports = ["http"]
env = {
"fprocess" = "figlet"
}
}
resources {
network {
mbits = 10
port "http" { static = 8080 }
}
}
service {
name = "figlet"
port = "http"
tags = ["openfaas-function"]
check {
type = "http"
path = "/"
interval = "10s"
timeout = "2s"
}
}
}
}
}

View File

@@ -0,0 +1,176 @@
job "openfaas" {
datacenters = ["dc1"]
type = "service"
group "openfaas-gateway" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "openfaas-gateway" {
driver = "podman"
config {
image = "ghcr.io/openfaas/gateway:0.2.35"
ports = ["http", "ui"]
env = {
"functions_provider_url" = "http://${NOMAD_IP_http}:8080"
"read_timeout" = "60s"
"write_timeout" = "60s"
"upstream_timeout" = "60s"
"direct_functions" = "true"
"faas_nats_address" = "nats://localhost:4222"
"faas_nats_streaming" = "true"
"basic_auth" = "true"
"secret_mount_path" = "/run/secrets"
"scale_from_zero" = "true"
}
}
resources {
network {
mbits = 10
port "http" { static = 8080 }
port "ui" { static = 8081 }
}
}
service {
name = "openfaas-gateway"
port = "http"
check {
type = "http"
path = "/healthz"
interval = "10s"
timeout = "2s"
}
}
}
}
group "nats" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "nats" {
driver = "podman"
config {
image = "nats-streaming:0.25.3"
ports = ["nats"]
args = [
"-p",
"4222",
"-m",
"8222",
"-hbi",
"5s",
"-hbt",
"5s",
"-hbf",
"2",
"-SD",
"-cid",
"openfaas"
]
}
resources {
network {
mbits = 10
port "nats" { static = 4222 }
}
}
service {
name = "nats"
port = "nats"
check {
type = "tcp"
interval = "10s"
timeout = "2s"
}
}
}
}
group "queue-worker" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "queue-worker" {
driver = "podman"
config {
image = "ghcr.io/openfaas/queue-worker:0.12.2"
env = {
"gateway_url" = "http://${NOMAD_IP_http}:8080"
"faas_nats_address" = "nats://localhost:4222"
"faas_nats_streaming" = "true"
"ack_wait" = "5m"
"write_debug" = "true"
}
}
resources {
network {
mbits = 10
}
}
}
}
group "prometheus" {
count = 1
constraint {
attribute = "${node.unique.name}"
operator = "regexp"
value = "(master|ash3c|hcp)"
}
task "prometheus" {
driver = "podman"
config {
image = "prom/prometheus:v2.35.0"
ports = ["prometheus"]
volumes = [
"/opt/openfaas/prometheus.yml:/etc/prometheus/prometheus.yml"
]
}
resources {
network {
mbits = 10
port "prometheus" { static = 9090 }
}
}
service {
name = "prometheus"
port = "prometheus"
check {
type = "http"
path = "/-/healthy"
interval = "10s"
timeout = "2s"
}
}
}
}
}

View File

@@ -0,0 +1,78 @@
job "traefik" {
datacenters = ["dc1"]
type = "service"
update {
strategy = "canary"
max_parallel = 1
min_healthy_time = "10s"
healthy_deadline = "3m"
auto_revert = true
}
group "traefik" {
count = 3
restart {
attempts = 3
interval = "30m"
delay = "15s"
mode = "fail"
}
network {
port "http" {
static = 80
}
port "https" {
static = 443
}
port "api" {
static = 8080
}
}
task "traefik" {
driver = "podman"
config {
image = "traefik:latest"
ports = ["http", "https", "api"]
volumes = [
"/var/run/docker.sock:/var/run/docker.sock:ro", # 如果需要与Docker集成
"/root/mgmt/configs/traefik.yml:/etc/traefik/traefik.yml:ro",
"/root/mgmt/configs/dynamic:/etc/traefik/dynamic:ro"
]
}
env {
NOMAD_ADDR = "http://${attr.unique.network.ip-address}:4646"
CONSUL_HTTP_ADDR = "http://${attr.unique.network.ip-address}:8500"
}
resources {
cpu = 200
memory = 256
}
service {
name = "traefik"
port = "http"
tags = [
"traefik.enable=true",
"traefik.http.routers.api.rule=Host(`traefik.service.consul`)",
"traefik.http.routers.api.service=api@internal",
"traefik.http.routers.api.entrypoints=api",
"traefik.http.services.api.loadbalancer.server.port=8080"
]
check {
type = "http"
path = "/ping"
interval = "10s"
timeout = "2s"
}
}
}
}
}

1
infrastructure/jobs/vault Symbolic link
View File

@@ -0,0 +1 @@
components/vault/jobs/