目录

Etcd + Confd 动态配置 nginx 站点

运行环境为 Debian 11docker

1. 安装 nginx-proxy (该方案无直接安装 nginx 方便)

使用 docker 下载 nginx-proxy

docker pull nginxproxy/nginx-proxy:alpine
docker network create nginx-proxy
docker-compose.yml
version: '2'

services:
  nginx-proxy:
    image: nginxproxy/nginx-proxy:alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    environment:
      - ENABLE_IPV6=true
    volumes:
      - ./conf.d:/etc/nginx/conf.d
      - ./vhost.d:/etc/nginx/vhost.d:ro
      - ./certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      - nginx-proxy

networks:
  nginx-proxy:
    external: true

2. 安装 nginx

直接安装源里的 nginx

apt install nginx

3. 运行 etcd

参考 使用 docker 运行 etcd

可以把 etcd keeper 一并运行,方便以图形化的界面管理 etcd 的值。

4. 运行 confd

参考资料: 官网

1. 下载

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/sbin/confd
chmod +x /usr/local/sbin/confd

2. 配置

创建目录

mkdir -p /etc/confd/{conf.d,templates}

新建默认配置文件 /etc/confd/confd.toml

backend = "etcdv3"
confdir = "/etc/confd"
log-level = "debug"
interval = 600
nodes = [
  "http://127.0.0.1:2379"
]

新建模板配置文件 /etc/confd/conf.d/nginx-demo-web.toml

[template]
 
src = "nginx-demo-web.tmpl"
 
dest = "/etc/nginx/sites-enabled/demo_sites"
 
keys = [
  "/demo-web"
]
 
owner = "root"
mode = "0644"
 
check_cmd = "nginx -t"
reload_cmd = "nginx -s reload"

新建模板文件 /etc/confd/templates/nginx-demo-web.tmpl

{{ range gets "/demo-web/*" }}
upstream upstream_{{ replace (base .Key) "." "_" -1 }} {
{{ $server_dir := printf "%s/*" .Key }} {{ range gets $server_dir }}
    server {{ base .Key }}; {{ end }}
}
 
server {
    # listen 80;
    listen 443 ssl http2;
 
    server_name {{ base .Key }};
 
    ssl_certificate /etc/nginx/certs/demo.example.com.crt;
    ssl_certificate_key /etc/nginx/certs/demo.example.com.key;
 
    index index.html index.htm index.nginx-debian.html;
 
    client_max_body_size 20M;
 
    location / {
        #try_files $uri $uri/ =404;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Real-PORT          $remote_port;
        proxy_set_header X-Forwarded-Proto    $scheme;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_pass                            http://upstream_{{ replace (base .Key) "." "_" -1 }};
    }
}
 
{{ end }}

3. 注册服务

新建文件 /etc/systemd/system/confd.service

[Unit]
Description=Confd
Wants=network-online.target
After=network-online.target
 
[Service]
ExecStart=/usr/local/sbin/confd
Restart=always
 
[Install]
WantedBy=default.target

运行

systemctl daemon-reload
systemctl start confd

4. 测试

增加站点示例

打开 etcd keeper ,在 etcd 中增加如下示例节点

/demo-web/demo1.example.com/127.0.0.1:8080
/demo-web/demo1.example.com/127.0.0.1:8081
/demo-web/demo2.example.com/127.0.0.1:8082
/demo-web/demo2.example.com/127.0.0.1:8083

过一会儿可以看到生成 /etc/nginx/sites-enabled/demo_sites 文件,文件里的内容便是上面配置的网站。

TODO: 与 nginx-proxy 整合

整合之后,既可以通过 etcd 动态配置外部 web server,也能代理 docker 里面的 web server。