设为首页 收藏本站
查看: 661|回复: 0

[经验分享] nginx+upsync+consul 构建动态nginx配置系统

[复制链接]

尚未签到

发表于 2018-11-8 06:57:50 | 显示全部楼层 |阅读模式
  参考:
  http://www.php230.com/weixin1456193048.html  【upsync模块说明、性能评测】
  https://www.jianshu.com/p/76352efc5657
  https://www.jianshu.com/p/c3fe55e6a5f2
  说明:
  动态nginx负载均衡的配置,可以通过Consul+Consul-template方式,但是这种方案有个缺点:每次发现配置变更都需要reload nginx,而reload是有一定损耗的。而且,如果你需要长连接支持的话,那么当reloadnginx时长连接所在worker进程会进行优雅退出,并当该worker进程上的所有连接都释放时,进程才真正退出(表现为worker进程处于worker process is shutting down)。因此,如果能做到不reload就能动态更改upstream,那么就完美了。
  目前的开源解决方法有3种:
  1、Tengine的Dyups模块
  2、微博的Upsync模块+Consul
  3、使用OpenResty的balancer_by_lua,而又拍云使用其开源的slardar(Consul + balancer_by_lua)实现动态负载均衡。
  这里我们使用的是upsync模块+consul 来实现动态负载均衡。操作笔记如下:
  consul的命令很简单,官方文档有详细的样例供参考,这里略过。
  实验环境:
  3台centos7.3机器
  cat /etc/hosts 如下:
  192.168.5.71  node71
  192.168.5.72  node72
  192.168.5.73  node73
  consul 我们使用3节点都是server角色。如果集群内某个节点宕机的话,集群会自动重新选主的。
  nginx-Upsync模块:新浪微博开源的,,它的功能是拉取 consul 的后端 server 的列表,并更新 Nginx 的路由信息。且reload对nginx性能影响很少。
1、安装nginx+ nginx-upsync-module(3台机器上都执行安装)
  nginx-upsync-module模块: https://github.com/weibocom/nginx-upsync-module
  nginx版本:1.13.8
  yum install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel -y
  cd /root/
  git clone https://github.com/weibocom/nginx-upsync-module.git
  # 建议使用git clone代码编译,刚开始我使用release的tar.gz 编译nginx失败了
  groupadd nginx
  useradd -g nginx -s /sbin/nologin nginx
  mkdir -p /var/tmp/nginx/client/
  mkdir -p /usr/local/nginx
  tar xf nginx-1.13.8.tar.gz
  cd /root/nginx-1.13.8
  ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=/root/nginx-upsync-module
  make && make install
  echo 'export PATH=/usr/local/nginx/sbin:$PATH' >> /etc/profile
  source /etc/profile
2、配置nginx虚拟主机
  在node1上配置虚拟主机:
  cat /usr/local/nginx/conf/nginx.conf 内容如下:
  user  nginx;
  worker_processes  4;
  events {
  worker_connections  1024;
  }
  http {
  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  tcp_nopush     on;
  keepalive_timeout  65;
  gzip  on;
  server {
  listen       80;
  server_name  192.168.5.71;
  location / {
  root   /usr/share/nginx/html;
  index  index.html index.htm;
  }
  }
  }
  创建网页文件:
  echo 'node71' > /usr/share/nginx/html/index.html
  在node3上启动虚拟主机:
  cat /usr/local/nginx/conf/nginx.conf 内容如下:
  user  nginx;
  worker_processes  4;
  events {
  worker_connections  1024;
  }
  http {
  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  tcp_nopush     on;
  keepalive_timeout  65;
  gzip  on;
  server {
  listen       80;
  server_name  192.168.5.73;
  location / {
  root   /usr/share/nginx/html;
  index  index.html index.htm;
  }
  }
  }
  创建网页文件:
  echo 'node73' > /usr/share/nginx/html/index.html
  在node2上配置虚拟主机:
  此处的node2作为LB负载均衡+代理服务器使用
  cat /usr/local/nginx/conf/nginx.conf 内容如下:
  user  nginx;
  worker_processes  1;
  error_log  logs/error.log  notice;
  pid        logs/nginx.pid;
  events {
  worker_connections  1024;
  }
  http {
  include       mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"'
  '$upstream_addr $upstream_status $upstream_response_time $request_time';
  access_log  logs/access.log  main;
  sendfile        on;
  tcp_nopush     on;
  keepalive_timeout  65;
  gzip  on;
  upstream pic_backend {
  # 兜底假数据
  # server 192.168.5.72:82;
  # upsync模块会去consul拉取最新的upstream信息并存到本地的文件中
  upsync 192.168.5.72:8500/v1/kv/upstreams/pic_backend upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
  upsync_dump_path /usr/local/nginx/conf/servers/servers_pic_backend.conf;
  }
  # LB对外信息
  server {
  listen 80;
  server_name  192.168.5.72;
  location = / {
  proxy_pass http://pic_backend;
  proxy_set_header  Host  $host;
  proxy_set_header  X-Real-IP  $remote_addr;
  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
  add_header    real $upstream_addr;
  }
  location = /upstream_show {
  upstream_show;
  }
  location = /upstream_status {
  stub_status on;
  access_log off;
  }
  }
  # 兜底的后端服务器
  server {
  listen       82;
  server_name  192.168.5.72;
  location / {
  root   /usr/share/nginx/html82/;
  index  index.html index.htm;
  }
  }
  }
  创建网页文件:
  mkdir /usr/share/nginx/html82 -p
  echo 'fake data in SLB_72' > /usr/share/nginx/html82/index.html
  创建upsync_dump_path(consul、upsync存放upstream主机信息使用到这个目录)
  mkdir /usr/local/nginx/conf/servers/
3、安装consul(3台机器上都执行安装)
  cd /root/
  mkdir /usr/local/consul/
  unzip consul_1.0.0_linux_amd64.zip
  mv consul /usr/local/consul/
  mkdir /etc/consul.d
  cd /usr/local/consul/
  echo 'export PATH=/usr/local/consul/:$PATH' >> /etc/profile
  source /etc/profile
  node71上:
  /usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node71 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.71 -client 0.0.0.0
  node72上:
  /usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node72 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.72 -client 0.0.0.0 -join 192.168.5.71
  意思是把本节点加入到192.168.5.71这个ip的节点中
  node73上:
  /usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node73 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.73 -client 0.0.0.0 -join 192.168.5.71
  意思是把本节点加入到192.168.5.71这个ip的节点中
  这样的话,就在3台主机前台启动了consul程序。
  可以在任一台主机上执行:
  consul members 列出当前集群的节点状态
DSC0000.jpg

  consul info  列出当前集群的节点详细信息  (输出信息太多,自己运行时候看去吧)
  访问consul自带的web界面
  http://192.168.5.71/upstream_show (3个节点都开了webui,因此我们访问任意节点都行)
DSC0001.jpg

  在任一节点上执行如下命令,即可添加2个key-value信息:
  curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
  curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
  在web界面,就可看到如下所示:
DSC0002.jpg

  删除的命令是:
  curl -X DELETE http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
  curl -X DELETE http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
  调整后端服务的参数:
  curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.71:80
4、测试consul+nginx调度
  在node1、node2、node3上都执行 /usr/local/nginx/sbin/nginx 启动nginx服务
  访问http://192.168.5.72/upstream_show
DSC0003.jpg

  访问http://192.168.5.72/upstream_status
DSC0004.jpg

  刚才我们在第三步的时候,执行了如下2条命令,自动在consul里面加了2行内容。
  curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
  curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
  我们node2的nginx在启动的时候,会去nginx.conf里面配置的consul地址去寻找对应的upstream信息。同时会dump一份upstream的配置到/usr/local/nginx/conf/servers目录下。
  [root@node72 /usr/local/nginx/conf/servers ]# cat servers_pic_backend.conf
  server 192.168.5.73:80 weight=10 max_fails=2 fail_timeout=10s;
  server 192.168.5.71:80 weight=10 max_fails=2 fail_timeout=10s;
  我们可以写个curl脚本测试下,如下
  for i in {1..100} ;do curl http://192.168.5.72/; done > /root/log
  grep -c node71 /root/log ;grep -c node73 /root/log
  可以看到curl是轮询请求到后端的node1和node3上去的。
DSC0005.jpg

  或者使用for i in {1..100} ;do curl -s -I http://192.168.5.72/|tail -2 |head -1; done
  
  如果要下线后端主机进行发布的话,只要把down参数置为1即可,类似如下:
  curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":1}'  http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
  如果发布完成并验证后,需要上线,可以再次把down参数置为0
  curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":0}'  http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
  如果调整在线调整后端服务的upstream参数:
  curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":0}'  http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
  说明:
  1、每次去拉取 consul 都会设置连接超时,由于 consul 在无更新的情况下默认会 hang 五分钟,所以响应超时配置时间应大于五分钟。大于五分钟之后,consul 依旧没有返回,便直接做超时处理。
  2、由于upsync模块会在pull新数据时候,自动在本地存一份upstream配置的副本。因此即便我们上面的3个consul进程全部宕掉了,nginx服务短时间内也不会受到影响。只要我们的监控完善及时将consul进程启动即可。
  此外,还可使用nginx +consulconsul-template这种架构来控制nginx的配置
  具体可以参考:
  https://www.jianshu.com/p/9976e874c099
  https://www.jianshu.com/p/a4c04a3eeb57?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
  https://www.cnblogs.com/MrCandy/p/7152312.html
  https://github.com/hashicorp/consul-template
  官方提供的nginx参考模板:https://github.com/hashicorp/consul-template/blob/master/examples/nginx.md


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-632076-1-1.html 上篇帖子: Nginx +WAF使用总结 下篇帖子: nginx+keepalived实现高可用。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表