st0627 发表于 2018-12-29 08:52:48

keepalived简单描述和其功能的实现

一、相关概念:
  在 keepalived中,一个是master,其他的都是backup
  vrrp:实现ip地址的高可用性,将除地址之外其他的功能也转移
  通过状态的改变,keepalived检测到,执行相应的状态下定义的脚本,脚本中有服务的 关闭和开启的命令,来实现服务的转移。
  keepalived:不仅提供地址的转移功能,服务启动和关闭,还有监控功能
  keepalived 两个核心组件:VRRP stack 和 checkers(用来监控服务)、还有对外围监控脚本调用的实现
  节点之间只通过优先级来确定资源在哪个节点上运行,需要起始配置
  虚拟地址转移之后如何启动服务:配置脚本
  转移信息状态,有个通知机制,可以发短信或者邮件给管理员(需配置邮件服务器)
  适用:用不到共享存储,节点少的
  keepalived支持多节点,但是节点中启动服务的只能有一个节点(一主多从)
  让每个节点都活动起来(运行两组资源)
  vrrp认证:1、明文认证、配置好预共享密钥2、md5 sha1 散列
二、keepalived工作:
1、配置
  主配置文件:/etc/keepalived/keepalived.conf
  服务脚本:/etc/rc.d/init.d/keepalived
  global_defs {
  notification_email {
  acassen@firewall.loc      收件人1
  failover@firewall.loc      收件人2
  sysadmin@firewall.       收件人 3
  }
  notification_email_from Alexandre.Cassen@firewall.loc    发件人
  smtp_server 192.168.200.1   发邮件的服务器
  smtp_connect_timeout 30   联系邮件服务器的超时时间
  router_id LVS_DEVEL 路由器的ID
  }
  邮件管理器是自动安装好的
  Rhel5 : sendmail
  Rhel6:postfix
  vrrp_instance VI_1 {   VI_1虚拟路由名称,自己取的
  state MASTER状态,使初始状态为master
  interface eth0   通告选举通过哪个接口进行
  virtual_router_id 51虚拟路由ID,单主就设置一个虚拟路由ID,双主就两个(不能大于255)
  priority 100初始优先级
  advert_int 1 初始化通告几个
  authentication { 认证机制
  auth_type PASS 明文认证
  auth_pass 1111 密码,可以随机生成
  }
  virtual_ipaddress { 虚拟IP地址,给了3个,很可能只用一个
  192.168.200.16
  192.168.200.17
  192.168.200.18
  }
  }
2、 在主节点上配置好,给从节点上复制一份
  Scp/etc/keepalived/keepalived.confroot@172.16.249.212:/etc/keepalived/
3、在从节点上改刚复制过来的配置文件
  vrrp_instance VI_1 {
  state BACKUP   上一个为master,那这个就为backup
  interface eth0
  virtual_router_id 51
  priority 99 这个优先级要低于主的优先级
  }
4、启动主节点:
  启动之前:先观察日志信息:tail-f/var/log/messages
  部分信息:
  Apr 28 14:20:05 node1 yum: Installed: keepalived-1.2.7-3.el6.x86_64
  Apr 28 14:51:48 node1 Keepalived: Starting Keepalived v1.2.7 (02/21,2013)
  Apr 28 14:51:48 node1 Keepalived: Starting Healthcheck child process, pid=5192
  Apr 28 14:51:48 node1 Keepalived: Starting VRRP child process, pid=5193
  在主节点上查看 IP地址已经启动起来了:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:40:af:c6 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.208/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0   配置的172.16.39.100 已经启动起来了
  inet6 fe80::20c:29ff:fe40:afc6/64 scope link
  valid_lft forever preferred_lft forever
  启动从节点:
  Servicekeepalived start
  从服务节点上 keepalived服务也启动了
  观察从节点的IP地址:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  没有虚拟IP地址。
测试:
  关闭主节点keepalived服务,在从服务器上检测虚拟IP地址是否被抢占过来。
  1、主上面:
  # service keepalived stop
  Stopping keepalived:                                       
  2、查看从节点的IP地址:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  查看已经显示将 172.16.39.100 抢占过来了。
  3、再启动主节点:
  # service keepalived start
  Starting keepalived:                                       
  查看从节点的IP地址:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  又被刚才的主节点抢占过去了
  *原因:因为之前我们配置的那个主节点的优先级(100)高于次节点的优先级(99),所以主节点上线后,就会把从节点上的IP地址抢占回来。
三、在keepalived配置文件中设置函数:
  格式:
  vrrp_script {    设置函数
  }
  Vrrp_instanceXXX {   追踪
  Track_script {
  XXX
  }
  }
1、模拟一个节点宕机:
  ①:在 /etc/keepalived/keepalived.conf配置文件中定义脚本来实现:
  vrrp_script chk_mantaince_down {   定义vrrp脚本
  script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
  interval 1
  weight -2
  }
  在 vrrp 主节点的配置段中加入脚本用来检测:
  vrrp_instance VI_1 {
  track_script {    添加追踪脚本
  chk_mantaince_down
  }
  }
  ②:复制配置文件到从节点上,然后如上,修改优先级priority和节点状态state
二、验证:
  ①:重启两个节点的keepalived服务: service keepalived restart
  ②:在主节点的/etc/keepalived/目录中,创建 down 文件(touch down),则主节点的IP地址就转移到从节点了。
  验证:
  主节点:
  # touch down
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:40:af:c6 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.208/16 brd 172.16.255.255 scope global eth0
  inet6 fe80::20c:29ff:fe40:afc6/64 scope link
  valid_lft forever preferred_lft forever
  从节点:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  

  

  1、如何在状态转换时进行通知?
  2、如何配置ipvs ?
  virutalserver
  realserver
  healthcheck
  3、如何对某特定服务做高可用?
  4、如何实现基于多虚拟路由的master/master模型?
  

1、如何在状态转换时进行通知?
  状态转换时进行通知: 要依赖自己编的通知脚本
  配置文件中有两类配置指令:
  notify_master“” 带引号的为加参数的脚本路径
  notify_backup   转换成backup通知函数
  notify_fault 当为fault时,执行fault函数
  vrrp_sync_group {   定义一个组
  }
  vrrp_instance {   定义函数
  }
  

  

  ------------------------------下面是一个notify.sh脚本的简单示例:----------------------------------------------
  #!/bin/bash
  # Author: MageEdu
  # description: An example of notify script
  #
  vip=172.16.39.100
  contact='root@localhost'   真正使用时:这个为互联网上可用的邮件地址
  notify() {
  mailsubject="`hostname` to be $1: $vip floating"
  mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"
  echo $mailbody | mail -s "$mailsubject" $contact
  }
  case "$1" in
  master)
  notify master
  exit 0
  ;;
  backup)
  notify backup
  exit 0
  ;;
  fault)
  notify fault
  exit 0
  ;;
  *)
  echo 'Usage: `basename $0` {master|backup|fault}'
  exit 1
  ;;
  esac
  ①:我们在主节点的 /etc/keepalived/目录下创建脚本叫 notify.sh
  ②:脚本内容如上。加执行权限: chmod +x notify.sh
  ③:在主配置文件中生效起来:
  vrrp_instanceVI_1{
  notify_master“/etc/keepalived/notify.shmaster”
  一个节点转换成master就执行如上脚本
  notify_backup“/etc/keepalived/notify.shbackup”
  一个节点转换成backup就执行如上脚本
  notify_fault“/etc/keepalived/notify.shfault”
  一个节点转换成fault就执行如上脚本
  }
  ④:我们仍然是在主节点上配置好,复制 keepalived.confnotify.sh到backup节点上,修改状态state和优先级priority
  l
  验证:
  在主节点上: touch down 、让主节点降低2个优先级,则从100变成98,则从节点的优先级99大于98则,IP地址转移到从节点上。
  主节点:
  # touch down
  查看邮件:
  # mail
  "/var/spool/mail/root": 4 messages 4 new
  N1 root                  Mon Apr 28 16:1318/721   "node1.corosync.com to be master: 172.16.39.100 floating"
  N2 root                  Mon Apr 28 16:1518/721   "node1.corosync.com to be backup: 172.16.39.100 floating"
  邮件中显示主节点从master 变成了 backup
  从节点上:
  查看IP地址:
  # ip addr show
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  查看从节点的邮件:
  # mail
  N1 root                  Mon Apr 28 17:2718/721   "node2.corosync.com to be backup: 172.16.39.100 floating"
  N2 root                  Mon Apr 28 17:2918/721   "node2.corosync.com to be master: 172.16.39.100 floating"
  邮件中显示已经从 backup转换成master
  2、配置 ipvs 实现集群服务
  virutalserver
  realserver
  healthcheck
  Virtualserver   定义 virutal server
  1、定义集群服务
  2、定义基于防火墙标记的集群服务
  3、定义将多个虚拟服务器定义成组,再把虚拟组定义成集群服务
  4、负载均衡的算法   lb_algorr | wrr | lc | wlc | lblc | sh | dh
  5、负载均衡的方式   lb_kindDR | NAT | TUN
  6、定义持久连接时长    persistence_timeout
  7、监听tcp端口上       ProtocolTCP
  8、所以节点全挂了,要返回一个“维护信息” sorry_server
  

  virtual_server 172.16.100.1 80 {
  delay_loop 6
  lb_algo rr
  lb_kind DR
  persistence_timeout 300
  protocol TCP
  sorry_server 127.0.0.1 80
  real_server 172.16.100.11 80 {
  }
  }
  

  realserver   定义realserver
  real_server   
  {
  weight
  notify_up   | < QUOTED - STRING>脚本路径 或者有参数的脚本
  notify_down   | < QUOTED - STRING>
  #HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC_CHECK
  }
  SL_GET |HTTP_GET {
  url {
  path /
  digest ff20ad2481f97b1754ef3e12ecd3a9cc
  }
  url {
  path /mrtg/
  digest 9b3a0c85a887a256d6939da88aabd8cd
  }
  connect_port    期望连接后端realserver中的哪个端口
  bindto    检测哪个地址
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 3
  }
  TCP_CHECK {
  connect_timeout
  connect_port
  bindto
  }
  

  

  示例:    定义VIP 和 real_server
  virtual_server 172.16.39.100 80 {
  delay_loop 6
  lb_algo rr
  lb_kind DR
  nat_mask 255.255.0.0
  persistence_timeout 0
  protocol TCP
  real_server 172.16.249.101 80 {
  weight 1
  HTTP_GET {
  url {
  path /
  status_code 200
  }
  }
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 3
  }
  real_server 172.16.249.102 80 {
  weight 1
  HTTP_GET {
  url {
  path /
  status_code 200
  }
  }
  connect_timeout 3
  nb_get_retry 3
  delay_before_retry 3
  }
  }
  ①:在主节点上配置好,发送到从节点上,修改状态,和优先级
  ②: 查看 ipvs规则
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.39.100:80 rr
  由此,看来已经生效了。
  

  --------------注意-----------------------:
  virtual_router_id 10   在有多个人在一个局域网中使用VM时。需要改id
  ③:我们在后端 172.16.249.101 开启httpd 服务
  # service httpd restart
  Stopping httpd:                                          
  Starting httpd: httpd: apr_sockaddr_info_get() failed for node.corosync.com
  httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
  ④:查看主节点的 ipvs 规则:
  # ipvsadm -L -n
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port         Forward Weight ActiveConn InActConn
  TCP172.16.39.100:80 rr
  -> 172.16.249.101:80            Route   1      0          0
  已经生效了。
  

  5、如何对某特定服务做高可用?
  实现对 nginx 高可用
  把 nginx 定义成一个资源
  1、监控服务
  vrrp_script {
  }
  2、在vrrp实例中追踪服务
  Track_script {
  }
  实现思路:
  对服务的高可用,除了争夺IP之外,还应该准确的判断另外节点中的服务是不是还   在启动中。
  我们在状态转换时,设置的通过配置文件中通过服务判断的不同会启动不同的脚 本,notify_masternotify_backup   notify_fault 不同状态会启动后面跟的自己定义 的脚本。
  在状态转换后,我们不仅发邮件都用户,还同时根据状态来启动或者重启或者关闭 服务、
  

  例如:状态从主节点转换成从节点后,发邮件给用户,然后关闭服务,启动从节点上的服务。
  1、编写脚本
  下面是一个notify.sh脚本的简单示例:
  #!/bin/bash
  # Author: MageEdu
  # description: An example of notify script
  #
  vip=172.16.100.1
  contact='root@localhost'
  notify() {
  mailsubject="`hostname` to be $1: $vip floating"
  mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"
  echo $mailbody | mail -s "$mailsubject" $contact
  }
  case "$1" in
  master)
  notify master
  /etc/rc.d/init.d/httpd start转变为主节点时: 打开服务
  exit 0
  ;;
  backup)
  notify backup
  /etc/rc.d/init.d/httpd stop 转变成从节点时:关闭服务
  exit 0
  ;;
  fault)
  notify fault
  /etc/rc.d/init.d/httpd stop 失败时:关闭服务
  exit 0
  ;;
  *)
  echo 'Usage: `basename $0` {master|backup|fault}'
  exit 1
  ;;
  esac
  2、在全局段中添加函数
  vrrp_script chk_httpd {
  script "killall -0 httpd"
  interval 1
  weight 2
  }
  3、在虚拟路由或者虚拟IP中追踪这个函数(启动这个函数)
  track_script {
  chk_httpd   或者说启动这个函数,因为你定义的函数可以不启动,你要启 } w动就写入到track_script中
  

  

  测试:
  ①:两个节点都重启:service keepalived restart
  

  主节点
  # ss -tnl | grep 80
  LISTEN   0      128                      :::80                      :::*
  Httpd服务已然开启
  从节点:
  # ss -tunl | grep 80没有任何信息
  

  6、如何实现基于多虚拟路由的master/master模型?
  建立两个虚拟IP或者多虚拟路由的意义:
  利用DNS中添加两个A记录,可以实现多个虚拟IP直接接受前端用户的访问。
  这样做,是为了利用原本不提供服务的从节点。这样做之后,原本前端虚拟路由只能最大承载1000个传递的话,做多虚拟路由的话,或者说做双虚拟路由的话,可以承载2000个传递。
  如果一个前端虚拟IP或者虚拟路由挂掉之后,两个虚拟路由就会加到一个节点上,那么此时就有弊端了,如果前期转发请求多的话,那一个节点是应付不了的,所以有理也有弊。
  

  建立两个:
  vrrp_instanceXX{
  }
  

  -------------------思路---------------------------:
  Master / master 模型意义:
  正常情况下:keepalived中一主多从,我们就拿,一主双从来讲。
  一主双从中:只能一个keepalived做为主节点提供服务,另外一个只能等着主 节点出问题,来夺取IP。
  多虚拟路由的master/master模型:就是将主从节点全部活动起来提供服务、
  实现:
  主节点上:
  配置文件中,定义两个vrrp_instanceXX{ } 一个定义为 master,一个定 义为BACKUP,master的优先级大于下面 backup的优先级。
  从节点上:
  配置文件中,定义两个vrrp_instanceXX{ } 一个定义为 master,一个定 义为BACKUP,master的优先级大于下面 backup的优先级。
  说明:
  1、对于VI_1和VI_2来说,两个节点要互为主从关系;
  主节点:
  vrrp_instance VI_1 {
  interface eth0
  state MASTER# BACKUP for slave routers
  priority 101# 100 for BACKUP
  virtual_router_id 51
  garp_master_delay 1
  }
  vrrp_instance VI_2 {
  interface eth0
  state BACKUP# BACKUP for slave routers 第二个虚拟路由设为BACKUP
  priority 100# 100 for BACKUP
  virtual_router_id59   修改这个id,不要和第一个虚拟路由相同
  garp_master_delay 1
  }
  从节点:
  vrrp_instance VI_1 {
  interface eth0
  state BACKUP# BACKUP for slave routers
  priority 100# 100 for BACKUP
  virtual_router_id 51
  garp_master_delay 1
  }
  vrrp_instance VI_2 {
  interface eth0
  state MASTER# BACKUP for slave routers 从节点设置第二个虚拟路由为MASTER
  priority 101# 100 for BACKUP
  virtual_router_id59   改的和上一个节点的中第二个虚拟路由的相同
  garp_master_delay 1
  }
  

  

  

  测试:
  主节点1:
  # ip a
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:40:af:c6 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.208/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0
  inet6 fe80::20c:29ff:fe40:afc6/64 scope link
  valid_lft forever preferred_lft forever
  该节点上虚拟IP为172.16.39.100
  主节点2:
  # ip a
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:01:46:91 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.165/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.200/32 scope global eth0
  inet6 fe80::20c:29ff:fe01:4691/64 scope link
  valid_lft forever preferred_lft forever
  该节点上虚拟IP为 172.16.39.200
  

  停掉主节点2:
  Servicekeepalived   stop
  查看主节点1上的IP:
  # ip a
  2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:40:af:c6 brd ff:ff:ff:ff:ff:ff
  inet 172.16.249.208/16 brd 172.16.255.255 scope global eth0
  inet 172.16.39.100/32 scope global eth0
  inet 172.16.39.200/32 scope global eth0
  inet6 fe80::20c:29ff:fe40:afc6/64 scope link
  valid_lft forever preferred_lft forever
  两个虚拟IP都在主节点1上了。



页: [1]
查看完整版本: keepalived简单描述和其功能的实现