插件窝 干货文章 docker中如何通过nginx+confd动态生成配置

docker中如何通过nginx+confd动态生成配置

Confd Nginx 配置 etcd 715    来源:    2025-04-21

使用Nginx + Confd实现动态配置管理

在Docker环境中,通过Nginx和Confd可以实现动态配置管理,这对于需要频繁更新配置的微服务架构特别有用。下面我将详细介绍实现方法。

基本概念

  • Confd: 一个轻量级的配置管理工具,可以从etcd、Consul等后端获取配置并生成配置文件
  • Nginx: 高性能的Web服务器和反向代理服务器

实现步骤

1. 准备工作

确保你已经安装Docker并了解基本的Docker操作。

2. 创建Docker网络

docker network create nginx-net

3. 启动后端存储服务(以etcd为例)

docker run -d --name etcd --network nginx-net \
  -p 2379:2379 -p 2380:2380 \
  quay.io/coreos/etcd:v3.4.0 \
  /usr/local/bin/etcd \
  --advertise-client-urls http://0.0.0.0:2379 \
  --listen-client-urls http://0.0.0.0:2379

4. 创建Nginx+Confd的Docker镜像

创建Dockerfile:

FROM nginx:latest

# 安装confd
RUN apt-get update && apt-get install -y wget && \
    wget https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64 && \
    mv confd-0.16.0-linux-amd64 /usr/local/bin/confd && \
    chmod +x /usr/local/bin/confd && \
    mkdir -p /etc/confd/{conf.d,templates}

# 添加confd配置
COPY confd/ /etc/confd/

# 添加启动脚本
COPY start.sh /start.sh
RUN chmod +x /start.sh

CMD ["/start.sh"]

创建confd配置文件(confd/conf.d/nginx.toml):

[template]
src = "nginx.conf.tmpl"
dest = "/etc/nginx/conf.d/default.conf"
keys = [
    "/upstreams",
    "/services"
]
reload_cmd = "/usr/sbin/nginx -s reload"

创建confd模板(confd/templates/nginx.conf.tmpl):

upstream backend {
    {{range gets "/upstreams/*"}}
    server {{.Value}};
    {{end}}
}

server {
    listen 80;

    location / {
        proxy_pass http://backend;
    }

    {{range gets "/services/*"}}
    location {{.Key | base | replace "/services/" "/"}} {
        proxy_pass http://{{.Value}};
    }
    {{end}}
}

创建启动脚本(start.sh):

#!/bin/bash

# 启动confd
confd -backend etcd -node http://etcd:2379 -interval 10 &

# 启动nginx
exec nginx -g "daemon off;"

构建镜像:

docker build -t nginx-confd .

5. 运行Nginx+Confd容器

docker run -d --name nginx-confd --network nginx-net \
  -p 80:80 \
  nginx-confd

6. 动态更新配置

通过etcd API添加或修改配置:

# 添加上游服务器
curl -X PUT http://localhost:2379/v2/keys/upstreams/server1 -d value="192.168.1.10:8080"
curl -X PUT http://localhost:2379/v2/keys/upstreams/server2 -d value="192.168.1.11:8080"

# 添加服务路由
curl -X PUT http://localhost:2379/v2/keys/services/api -d value="api-service:8080"
curl -X PUT http://localhost:2379/v2/keys/services/auth -d value="auth-service:8081"

Confd会检测到这些变化并自动更新Nginx配置,然后触发Nginx重载。

高级配置

1. 使用环境变量

修改启动脚本,支持环境变量配置:

#!/bin/bash

# 设置默认值
ETCD_HOST=${ETCD_HOST:-etcd}
ETCD_PORT=${ETCD_PORT:-2379}
INTERVAL=${CONFD_INTERVAL:-10}

# 启动confd
confd -backend etcd -node http://${ETCD_HOST}:${ETCD_PORT} -interval ${INTERVAL} &

# 启动nginx
exec nginx -g "daemon off;"

2. 健康检查

在Docker Compose或Kubernetes中配置健康检查:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 30s
  timeout: 10s
  retries: 3

3. 多模板支持

可以创建多个模板文件,分别管理不同部分的配置。

注意事项

  1. 确保etcd服务可用,Confd才能正常工作
  2. 配置变更频率不宜过高,避免频繁重载Nginx
  3. 对于生产环境,建议添加适当的错误处理和日志记录
  4. 考虑使用HTTPS和认证保护etcd API

替代方案

如果你不想使用etcd,Confd也支持其他后端:

  • Consul: -backend consul -node consul:8500
  • AWS SSM: -backend ssm
  • 环境变量: -backend env

通过这种方式,你可以实现Nginx配置的动态管理,非常适合微服务架构和动态扩展的场景。