Skip to content

Instantly share code, notes, and snippets.

@nickadam
Created November 13, 2022 19:04
Show Gist options
  • Select an option

  • Save nickadam/9339ce34b69fdd4c0f58e8d7df37f971 to your computer and use it in GitHub Desktop.

Select an option

Save nickadam/9339ce34b69fdd4c0f58e8d7df37f971 to your computer and use it in GitHub Desktop.
Install service to manage virtual IP using ucarp
#!/bin/bash
test -z "$1" || HOST_IP=$1
test -z "$2" || VIP=$2
test -z "$3" || VHID=$3
test -z "$4" || PASSWORD="${4}"
# set default VHID and PASSWORD if not set
test ! -z "$VHID" || VHID=20
test ! -z "$PASSWORD" || PASSWORD=ucarp
# make sure ucarp is installed
if ! which ucarp >/dev/null
then
echo "Install ucarp"
exit 1
fi
# check vars
if [ -z "$VIP" ] || [ -z "$HOST_IP" ]
then
echo "Execute with host IP and VIP arguments"
exit 1
fi
# get the interface name if not set
test ! -z "$DEV_NAME" || DEV_NAME=$(ip a \
| grep -e "^[^ ]" -e inet\ "$(echo $HOST_IP | sed 's/\./\\./g')" \
| egrep -B 1 "^ +inet" \
| head -n 1 \
| awk '{print $2}' \
| awk -F @ '{print $1}' \
| awk -F : '{print $1}')
if [ -z "$DEV_NAME" ]
then
echo "Failed to find interface name for $HOST_IP"
exit 1
fi
# get the CIDR number
test ! -z "$CIDR" || CIDR=$(ip a \
| grep inet\ "$(echo $HOST_IP | sed 's/\./\\./g')" \
| awk -F / '{print $2}' \
| awk '{print $1}')
if [ -z "$CIDR" ]
then
echo "Failed to CIDR for $HOST_IP"
exit 1
fi
# create interface up and down scripts
cat <<EOF > /usr/local/sbin/ucarp-up.sh
#!/bin/bash
/usr/sbin/ip addr add \${2}/$CIDR dev \${1}
EOF
chmod +x /usr/local/sbin/ucarp-up.sh
cat <<EOF > /usr/local/sbin/ucarp-down.sh
#!/bin/bash
/usr/sbin/ip addr delete \${2}/$CIDR dev \${1}
EOF
chmod +x /usr/local/sbin/ucarp-down.sh
# Install service
cat <<EOF > /etc/systemd/system/ucarp-$VHID.service
[Unit]
Description=ucarp-$VHID
[Service]
ExecStart=ucarp --interface=$DEV_NAME --srcip=$HOST_IP --vhid=$VHID --pass="${PASSWORD}" --addr=$VIP --upscript=/usr/local/sbin/ucarp-up.sh --downscript=/usr/local/sbin/ucarp-down.sh --shutdown
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
systemctl enable ucarp-$VHID
systemctl start ucarp-$VHID
@nickadam
Copy link
Author

Pass this script the host IP and VIP and it will create scripts for ucarp to configure the appropriate interface. The script creates a service called ucarp-20 (or whatever VHID) you pass as the third argument. You could also pass your own CARP shared password as the 4th argument.

./install-ucarp-vip.sh 10.10.10.10 10.10.10.12

systemctl status ucarp-20
● ucarp-20.service - ucarp-20
     Loaded: loaded (/etc/systemd/system/ucarp-20.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2022-11-13 18:58:45 UTC; 29s ago
   Main PID: 3338 (ucarp)
      Tasks: 1 (limit: 38432)
     Memory: 416.0K
        CPU: 20ms
     CGroup: /system.slice/ucarp-20.service
             └─3338 ucarp --interface=eth0 --srcip=10.10.10.10 --vhid=20 --pass=ucarp --addr=10.10.10.12 --upscript=/usr/loca>

Nov 13 18:58:45 testucarp2 ucarp[3338]: [INFO] Local advertised ethernet address is [00:16:3e:4d:a0:01]
Nov 13 18:58:45 testucarp2 ucarp[3338]: [WARNING] Switching to state: BACKUP
Nov 13 18:58:45 testucarp2 ucarp[3338]: [WARNING] Switching to state: BACKUP
Nov 13 18:58:45 testucarp2 ucarp[3338]: [WARNING] Spawning [/usr/local/sbin/ucarp-down.sh eth0 10.10.10.12]
Nov 13 18:58:45 testucarp2 ucarp[3338]: [WARNING] Spawning [/usr/local/sbin/ucarp-down.sh eth0 10.10.10.12]
Nov 13 18:58:45 testucarp2 ucarp[3367]: RTNETLINK answers: Cannot assign requested address
Nov 13 18:59:11 testucarp2 ucarp[3338]: [WARNING] Switching to state: MASTER
Nov 13 18:59:11 testucarp2 ucarp[3338]: [WARNING] Switching to state: MASTER
Nov 13 18:59:11 testucarp2 ucarp[3338]: [WARNING] Spawning [/usr/local/sbin/ucarp-up.sh eth0 10.10.10.12]
Nov 13 18:59:11 testucarp2 ucarp[3338]: [WARNING] Spawning [/usr/local/sbin/ucarp-up.sh eth0 10.10.10.12]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment