使用consul和consul-template统一管理nginx配置文件

本文介绍了如何通过Consul实现分布式系统的服务发现和配置管理,结合Consul-template实现实时更新Nginx配置,避免单点修改带来的风险。文章详细描述了Consul、Consul-template的使用方法,以及如何通过Python脚本和Ansible批量更新配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:为应对较大流量及高并发的业务场景,需要多台nginx做代理转发,针对这种情况,如果对nginx的站点配置文件进行修改,需要一台一台的去操作,如果有遗漏修改的很有可能造成生产事故,为避免这种情况的发生,本文介绍使用consul和consul-template实现对nginx配置文件进行统一管理,也是目前作者本人所在公司使用的一种解决方案。

consul介绍

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等)。使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

consul-template介绍

Consul-Template是一个守护进程,用于实时查询Consul集群信息
Consul-Template可以更新文件系统上任意数量的指定模板,生成配置文件更新完成以后,可以选择运行shell命令执行更新操作,重新加载Nginx。
Consul-Template可以查询Consul中的服务目录、Key、Key-values等。
这种强大的抽象功能和查询语言模板可以使Consul-Template特别适合动态的创建配置文件

操作详解

agent安装

首先需要在所有的nginx服务器节点安装consul agent,并注册到consul集群

nginx upstream.conf文件管理

编写脚本,将consul-template作为守护进程启动

脚本文件名自定义(consul-init),需要可执行权限,然后执行 consul-init start

#!/bin/bash
# Source function library.
. /etc/init.d/functions
RETVAL=0
PROG="consul-template"
PID_FILE=/var/run/${PROG}.pid
check_status() {
    pgrep -n ${PROG}
    RETVAL=$?
    echo $RETVAL
    return $RETVAL
}

start(){
  if check_status > /dev/null; then
    echo "Service is already running"
    exit 0
  fi
  consul-template -config /data/config/upstreams/upstream.conf &
  RETVAL=$?
  PID=`pgrep -f ${PROG}`
  echo "${PID}" > ${PID_FILE}
  return $RETVAL
}

stop(){
    killproc -p ${PID_FILE} -d 10
    RETVAL=$?
    [ $RETVAL = 0 ] && rm -f ${PID_FILE}
    return $RETVAL
}

reload(){
  if [ -n $PID_FILE ];then
    PID=`cat ${PID_FILE}`
    kill -HUP $PID
  else
    echo "Service is not running"
  fi
}
case "$1" in
    start)
        start
        ;;
    stop)
       stop
       ;;
    reload)
       reload
       ;;
esac
upstream.conf文件配置(即 consul-template -config /**/upstream.conf)
consul {
  address = "127.0.0.1:8500"
  retry {
    enabled = true
    attempts = 12
    backoff = "250ms"
    max_backoff = "1m"
  }
  ssl {

  }
}
reload_signal = "SIGHUP"
kill_signal = "SIGINT"
max_stale = "10s"
log_level = "warn"
pid_file = "/var/run/consul-template.pid"
wait {
  min = "5s"
  max = "10s"
}
syslog {
  enabled = true
  facility = "LOCAL5"
}
deduplicate {
}
exec {
  splay = "5s"
  env {
    pristine = false
  }
  reload_signal = ""
  kill_signal = "SIGINT"
  kill_timeout = "2s"
}

template {
  source = "/data/config/upstreams/upstreams.ctmpl"
  destination = "/opt/openresty/nginx/conf/servers/upstreams/upstreams.conf"
  create_dest_dirs = true
  command = "systemctl reload nginx"
  command_timeout = "30s"
  error_on_missing_key = false
  perms = 0600
  left_delimiter  = "{{"
  right_delimiter = "}}"
  wait {
    min = "2s"
    max = "10s"
  }
}

upstream模板文件配置(upstreams.ctmpl)

首先需要在consul中配置好对应的key/value
在这里插入图片描述

upstream {{key "test/backend_name"}} {
{{range ls "test/upstream"}}
  server {{.Value}} max_fails=3 fail_timeout=60 weight=1;
 {{end}}
}

以上完成后,可以执行 consul-init start ,正常启动后,可以去目的目录里面查看是否正常生成了upstream.conf文件,文件内容及为consul中事先配置好的内容,增删key,upstream中会动态更新

站点配置文件管理

借助python脚本(flushnginx),实现对站点配置文件的批量更新

#!/opt/python3/bin/python3.6
#!/usr/bin/env python
#-*- coding:utf-8 -*-

#dingzk

import os,sys,yaml,re
def fn(_dict, depth):
    for k, v in _dict.items():
        if depth == 1:
            yield k, v
        else:
            yield from ((k, *q) for q in fn(v, depth - 1))

if __name__=="__main__":
    if len(sys.argv) != 2:
        print("参数错误")
    else:
        cfgfile = "/data/config/template.yaml"
        cfgregion = "external"
        cfgname = sys.argv[1]
        if os.path.exists(cfgfile):
            f = open(cfgfile, encoding='utf-8')
            cfg = yaml.load(f,Loader=yaml.FullLoader)
            for i in cfg[cfgregion]['config']:
                source = i['source']
                destination = i['destination']
                if cfgname == "all":
                    print(source,destination)
                    status = True
                    if os.system('consul-template -template %s:%s -once'  % (source,destination)) > 0:
                        print("配置文件生成失败")
                        sys.exit()
                else:
                    if re.search(cfgname,source):
                        print(source,"---->",destination)
                        status = True
                        if os.system('consul-template -template %s:%s -once'  % (source,destination)) > 0:
                            print("配置文件生成失败")
                            sys.exit()
                        break
                    else:
                        status = False
            if status:
                if os.system('/opt/openresty/nginx/sbin/nginx -t') == 0:
                    os.system('systemctl reload nginx')
                    print("更新成功")
                else:
                    print("配置文件测试失败")
            else:
                print("配置文件不存在")
        else:
            print("yaml文件不存在")

维护一个template.yaml文件,里面包含配置文件模板及目标文件路径

---
external:
    config:
        - source: "/data/config/test.ctmpl"
          destination: "/opt/openresty/nginx/conf/servers/test.conf"

配置文件模板

server {
	listen	80;
	server_anme	test.com.cn;
}

执行脚本

python flushnginx test

在这里插入图片描述

使用ansible批量执行来更新配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值