木讷大叔爱运维

双机房场景下,1分钟交付Nginx跨区域变更!

图片
Image

需求

双机房或多机房场景下会存在多套Nginx,每次配置变更需要跨多套Nginx进行修改,这无疑会存在极大的变更风险。因此我们团队内部根据此种场景进行了一次头脑风暴,在不增加复杂度的前提下,提供一种双机房场景的Nginx管理实践,满足一次提交、多机房部署的需求,既能简化操作步骤、规避变更风险,又能将交付效率提升到1分钟级别。

架构

Image
基于以上架构图,我们进行如下解析:

Nginx管理规范

经过如下整改,我们将配置进行分离绑定但统一管理,以满足配置在不同区域可分别生效。

  • 基础目录conf,所有配置相关都存在于此目录下;
  • upstream.conf 按机房区域命名为:upstream_A.conf 、upstream_B.conf;
  • 每个机房的proxy_pass 必须保持一致,均来源于upstream.conf;
  • 每个机房的nginx.conf  分别绑定相应的upstream.conf;
  • 其他区域差异配置,参考upstream.conf做相应拆分;

Git管理规范

为满足精简操作的需求,我们每套Nginx 使用一个Git仓库,不区分机房,因此既需要上述的Nginx目录规范,也需要在Git侧遵循一定的纳管规范。

  • 配置文件以conf 为最小单元进行纳管;
  • conf 中只保留变更相关文件,其他Ningx依赖文件均按以下规则忽略;
  • 必须忽略nginx.conf,因为此文件绑定了upstream.conf,须在各自机房区域生效;
  • 必须忽略Ningx依赖文件,如koi、scgi、uwsgi等conf目录下的基础文件;

流水线编排

在双机房场景下,CMDB的重要性更加凸显,尤其在金融行业下业务、网络分区等场景下Nginx可能会达几十套,我们如何快速选择资产虽然并不是本次的重点,但是这反映出有序的运维建设对后续自动化是重要的!

流水线编排方面主要包含以下几点:

  • CMDB 快速选择多机房下Nginx IP;
  • pull 最新配置文件;
  • 配置文件检查;
  • 更新A机房第一台,等待验证;
  • 验证通过,更新A机房剩余所有及B机房所有;
  • 单IP、批量IP、单机房、多机房等不同情况的消息通知;

流水线中我们引入了验证等待环节,可用于团队间的二次复核,保证变更的准确性!

具体实施

Nginx配置初始化

首次Nginx配置需要使用Git进行纳管,主要操作如下:

1.备份conf,因为clone目标目录必须是空目录
cd /opt/openresty/nginx
 mv conf conf.bak
 git clone http://x.x.x.x/nginx/nginx.git conf
2.保存密码
 git config --global credential.helper store
3.基础文件从备份中复制回conf目录
 cp ../conf.bak/* .
4.由于nginx.conf未被git纳管,需要单独绑定区域upstream_A/B.conf 配置
5.检查配置文件并启动

Ngnix配置变更

每次变更操作只需在其中一台进行配置文件修改即可,剩余操作交给流水线一键更新。

#1.重要:每次变更前必须pull到最新
cd /app/openresty/nginx/conf
 git pull
#2.配置文件修改
 vim xxxx.conf
#3.push到远程git
 git add
 git status
 git commit -m "增加xxx配置"
 git push

流水线实现

流水线通过共享库中的原子模块对接cmdb,并通过两条子流水线在双机房场景下编排,将配置文件的变更压缩到1分钟级别交付,大大简化了中间操作步骤。

@Library('shared-library') _
pipeline {
 agent any
 options
 timestamps()
 stages {
  stage('A机房发布第一台'){
   steps {
    script {
     currentBuild.displayName = "#$(BUILD_NUMBER}-${params.ACTION}"
     currentBuild.description = "${params.NGINX_NAME}"
     hosts = cmdb.GetHosts("${NGINX_NAME}")

     println(hosts [0])
     build job: 'nginx_admin_A', parameters: [string(name: 'NGINX_NAME', value: "
S{NGINX_NAME}"), string(name: "HOST", value: "${hosts[0]}"), string(name: "ACTION", value: "${ACTION}")
     input message:"
等待第一台${hosts[0]}验证通过",ok: 'Pass'
    }
   }
  } 
  stage('A机房更新剩余所有'){
   steps {
    script {
     hosts = cmdb.GetHosts("
${NGINX_NAME}")
     println(hosts.tail().join(','))
     build job: 'nginx_admin_A', parameters: [string(name: 'NGINX_NAME', value: "
S{NGINX_NAME}"), string(name: "HOST", value: "${hosts.tail().join(',')}"), string(name: "ACTION",value:"${ACTION}")]
    }
   }
  }
  stage('B机房更新所有'){
   steps {
    script {
     build job: 'nginx_admin_B', parameters: [string(name:'NGINX_NAME', value: "
${NGINX_NAME}"), string(name: "HOST",value: ''), string(name: 'ACTION', value: "${ACTION}")]
    }
   }
  }
 }
} 

总结

也许会有小伙伴有疑问,为啥不用nginxWebUI开源项目或Nginx+Nacos的方案,但这两种方案由于会引入外部组件,在一定程度上增加架构的复杂度,适配性上也需要耗费精力去踩坑。而业务场景下Nginx作为唯一入口,我们需要更加安全、可控的解决方案!

添加好友,邀你入群,运维人的圈子,每日精彩分享,更有小伙伴们的热议!

图片

📢 近期话题:

C++之父的人生建议
复盘:Ai来了,为啥创作热情却低了!
Napkin:又一个运维人的Ai秘密武器!
运维必备!DeepSeek+Mermaid:1秒生成专业图表,告别手动绘图!
Ai智能助手,能否让信创操作系统插上飞行的翅膀!
运维大健康,PDCA来守护!
当运维有了战歌,是肉麻还是激情澎湃?
运维人必看!IT认证体系与技能进阶指南
雷池WAF:动态防护,让爬虫和扫描器无处遁形!
Python VS Go,运维永远绕不过的话题!
DeepSeek挖掘出ITSM在运维中的困局与破局!
智能运维新趋势:AIOps与GPT大模型的结合
运维细无声,让我们放松对变更、风险及基线的警惕!
信创操作系统迁移知多少!
证书管理工具再汇总!
CMDB多模型探索,痛并快乐着!
你懂运维,但不懂运维人的书单!
警惕!运维自动化之 “暗礁”
SRE的偏见看这里!

札记:“所有发行版都在淘汰的东西那就跟着淘汰!”

--优秀的运维小伙伴