From 08ae659310d9bd28c3b84d51de6921b965a39b9a Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Fri, 25 Aug 2017 11:41:08 +0300 Subject: [PATCH] Add Keepalived tutorial --- Documentation/Documentation-Contents.md | 1 + .../Tutorials/Failover-with-Keepalived.md | 190 ++++++++++++++++++ Documentation/Tutorials/images/Keepalived.png | Bin 0 -> 21984 bytes 3 files changed, 191 insertions(+) create mode 100644 Documentation/Tutorials/Failover-with-Keepalived.md create mode 100644 Documentation/Tutorials/images/Keepalived.png diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index d944a68c3..710e038ee 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -37,6 +37,7 @@ These tutorials are for specific use cases and module combinations. - [Administration Tutorial](Tutorials/Administration-Tutorial.md) - [Avro Router Tutorial](Tutorials/Avrorouter-Tutorial.md) + - [Failover with Keepalived](Tutorials/Failover-with-Keepalived.md) - [Filter Tutorial](Tutorials/Filter-Tutorial.md) - [Galera Cluster Connection Routing Tutorial](Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md) - [Galera Gluster Read Write Splitting Tutorial](Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md) diff --git a/Documentation/Tutorials/Failover-with-Keepalived.md b/Documentation/Tutorials/Failover-with-Keepalived.md new file mode 100644 index 000000000..c261229c0 --- /dev/null +++ b/Documentation/Tutorials/Failover-with-Keepalived.md @@ -0,0 +1,190 @@ +# Failover with Keepalived + +## Introduction + +[Keepalived](http://www.keepalived.org/index.html) is a routing software for +load balancing and high-availability. It has several applications, but for this +tutorial the goal is to set up a simple IP failover between two servers running +MaxScale. If the main server fails the backup machine takes over, receiving any +new connections. The Keepalived settings used in this tutorial follow the +example given in [Simple keepalived failover setup on Ubuntu 14.04]( +https://raymii.org/s/tutorials/Keepalived-Simple-IP-failover-on-Ubuntu.html). + +Two hosts and one client machine are used, all in the same LAN. Hosts run +MaxScale and Keepalived. The backend servers may be running on one of the hosts, +e.g. in docker containers, or on separate machines for a more realistic setup. +Clients connect to the virtual IP (VIP), which is claimed by the current master +host. + +![](images/Keepalived.png) + +Once configured and running, the different Keepalived nodes continuously +broadcast their status to the network and listen for each other. If a node does +not receive a status message from another node with a higher priority than +itself, it will claim the VIP, effectively becoming the master. Thus, a node can +be put online or removed by starting and stopping the Keepalived service. + +If the current master node is removed (e.g. by stopping the service or pulling +the network cable) the remaining nodes will quickly elect a new master and +future traffic to the VIP will be directed to that node. Any connections to the +old master node will naturally break. If the old master comes back online, it +will again claim the VIP, breaking any connections to the backup machine. + +MaxScale has no knowledge of this even happening. Both MaxScales are running +normally, monitoring the backend servers and listening for client connections. +Since clients are connecting through the VIP, only the machine claiming the VIP +will receive incoming connections. The connections between MaxScale and the +backends are using real IPs and are unaffected by the VIP. + +## Configuration + +MaxScale does not require any specific configuration to work with Keepalived in +this simple setup, it just needs to be running on both hosts. The MaxScale +configurations should be similar to the extent that both look identical to +connecting clients. In practice the listening ports and related services should +be the same. Setting the service-level setting “version_string” to different +values on the MaxScale nodes is recommended, as it will be printed to any +connecting clients indicating which node was connected to. + +Keepalived requires specific setups on both machines. On the **primary host**, +the */etc/keepalived/keepalived.conf*-file should be as follows. + +``` +vrrp_instance VI_1 { + state MASTER + interface eth0 + virtual_router_id 51 + priority 150 + advert_int 1 + authentication { + auth_type PASS + auth_pass mypass + } + virtual_ipaddress { + 192.168.1.123 + } +} +``` + +The *state* must be MASTER on both hosts. *virtual_router_id* and *auth_pass* +must be identical on all hosts. The *interface* defines the network interface +used. This depends on the system, but often the correct value is *eth0*, +*enp0s12f3* or similar. *priority* defines the voting strength between different +Keepalived instances when negotiating on which should be the master. The +instances should have different values of priority. In this example, the backup +host(s) could have priority 149, 148 and so on. *advert_int* is the interval +between a host “advertising” its existence to other Keepalived host. One second +is a reasonable value. + +*virtual_ipaddress* (VIP) is the IP the different Keepalived hosts try to claim +and must be identical between the hosts. For IP negotiation to work, the VIP +must be in the local network address space and unclaimed by any other machine +in the LAN. An example *keepalived.conf*-file for a **backup host** is listed +below. + +``` +vrrp_instance VI_1 { + state MASTER + interface eth0 + virtual_router_id 51 + priority 100 + advert_int 1 + authentication { + auth_type PASS + auth_pass mypass + } + virtual_ipaddress { + 192.168.1.123 + } +} +``` + +Once the Keepalived service is running, recent log entries can be printed with +the command `service keepalived status`. + +``` +Aug 11 10:27:59 maxscale2 Keepalived_vrrp[27369]: VRRP_Instance(VI_1) Received higher prio advert +Aug 11 10:27:59 maxscale2 Keepalived_vrrp[27369]: VRRP_Instance(VI_1) Entering BACKUP STATE +Aug 11 10:27:59 maxscale2 Keepalived_vrrp[27369]: VRRP_Instance(VI_1) removing protocol VIPs. +``` + +## MaxScale health check + +So far, none of this tutorial has been MaxScale-specific and the health of the +MaxScale process has been ignored. To ensure that MaxScale is running on the +current master host, a *check script* should be set. Keepalived runs the script +regularly and if the script returns an error value, the Keepalived node will +assume that it has failed, stops broadcasting its state and relinquishes the +VIP. This allows another node to take the master status and claim the VIP. To +define a check script, modify the configuration as follows. The example is for +the primary node. See [Keepalived Check and Notify Scripts]( +https://tobrunet.ch/2013/07/keepalived-check-and-notify-scripts/) for more +information. + +``` +vrrp_script chk_myscript { + script "/home/scripts/is_maxscale_running.sh" + interval 2 # check every 2 seconds + fall 2 # require 2 failures for KO + rise 2 # require 2 successes for OK +} + +vrrp_instance VI_1 { + state MASTER + interface wlp2s0 + virtual_router_id 51 + priority 150 + advert_int 1 + authentication { + auth_type PASS + auth_pass mypass + } + virtual_ipaddress { + 192.168.1.13 + } + track_script { + chk_myscript + } +} +``` + +An example script, *is_maxscale_running.sh*, is listed below. The script uses +MaxAdmin to try to contact the locally running MaxScale and request a server +list, then check that the list has at least some expected elements. The timeout +command ensures the MaxAdmin call exits in reasonable time. The script detects +if MaxScale has crashed, is stuck or is totally overburdened and no longer +responds to connections. + +``` +#!/bin/bash +fileName="maxadmin_output.txt" +rm $fileName +timeout 2s maxadmin list servers > $fileName +to_result=$? +if [ $to_result -ge 1 ] +then + echo Timed out or error, timeout returned $to_result + exit 3 +else + echo MaxAdmin success, rval is $to_result + echo Checking maxadmin output sanity + grep1=$(grep server1 $fileName) + grep2=$(grep server2 $fileName) + + if [ "$grep1" ] && [ "$grep2" ] + then + echo All is fine + exit 0 + else + echo Something is wrong + exit 3 + fi +fi +``` + +``` +Aug 11 10:51:56 maxscale2 Keepalived_vrrp[20257]: VRRP_Script(chk_myscript) failed +Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) Entering FAULT STATE +Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) removing protocol VIPs. +Aug 11 10:51:57 maxscale2 Keepalived_vrrp[20257]: VRRP_Instance(VI_1) Now in FAULT state +``` diff --git a/Documentation/Tutorials/images/Keepalived.png b/Documentation/Tutorials/images/Keepalived.png new file mode 100644 index 0000000000000000000000000000000000000000..f500e5a176ad75c34f64bead2fd5ad02cb14d87b GIT binary patch literal 21984 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ℜ%UbUb|T>L`pwNqPIkD9)o^l=V1 z+wlH&DT2g-N9aQ{5dKUw+osd;^w(4ss0XUn5 z`W2`2ZX2V6#-#5O4L8|0zAR&Ya=tt}-e=k8wV>Li{mA9jHww3J(0)H{*Vf}%Q?#xc zM={2(WZYEn@X)nWr%u^qzb$6)lUlI-EW-qEqwk;d13sO9A82tW_Z3Gj5?Xog-oEMy_s!iSAN&k3dC$22>wP(nH8Vmts z1uBQEoOgNATrb`QhYlU;kB*Ms&;Gztw)gKZ-F7T$@{Efhg#o{WlJaS z`Ly(+w;FFrb@RamkwP;|^E4)Xw{e{}vDtqK!vkL1w^LqO{+;Q+l7)kV;=~W%@1m_uR7^C$7y+6}P*~*1+zu=j;r_ z^}L3X61kc?Kb$dCn&B}~bAt_M)0?=hJwlqiS6ED>Ahx((3JD8~bNiIepjJEgm!8sY z&wFnz&OK^sYI>HEldLhR+`6Iu{qnop8Gf)F(c_q<(81Uc(2}CoAS1!UZphQHU;f_z z()n92cXiAE4^a*T_u48CCR~_4d$#rF%{!h;O57=ylJ?a5Y?J@-&(F`>RV$-aMP}~g zm~flXqFKHB`02VI>1u~tDnU&^udkIcZi_EY_F!W;b1;1RKaaD1ofDo^O*(z~@@4rs z*5!H0T3hQuu`3eE_F#pGy@=QY=ChHR_K`EzyIO&L_Y_-CUiFfJ&-0*4 zmhs8ZV>8^1jEv&ETT5BLFW*!1>%x~gisp_HY~PC31tslKobuX>$u!$!*A!3zy?*Yi zSFg4#Tei%YVNQO}Ot&JgUn@UV=nJV&x}&R@H8!p|IM=flwl6E5&AOWycqyRqAC z+fT_IQxsI+$$ZKUsxwu({of-z`==(zN3XIMFIuG3{zT+>p`YMHO_hFj1Gxhi8ar|) zy;a)e>~c?ar=0B8uDG+OPF1OIJZi>%?$IktNlD#}H`|sm9NF(UX{CVC_X*E94P(AJ z-hJ|%J=$qCsNuJ=E-*HB?!_xtOpZwy-}}5LCizSRLo!2;l4X!f8{-K__tX;h__c+i z%nulEFh2-p*zNhw=va>W&R7>ah7DIg@2SepJ-i|DaM_Yi=gVqW+St^F%#tiJ)X@`p zXvyHFwm|YW!=Hm3^ES-yZcN=34LV6jl!s zUUIMRy-fOX^^Kl(^NXX7C!MrmJW$Bcwpf4OC6O)7H~3Dmab1^w@U>$1n!Q