Recent disruptions to two undersea internet cables in the Baltic Sea have yet again...
2.13.1 Initial failover configuration
Prerequisites #
- One IRP node is configured and fully functional. We will refer to this node as $IRPMASTER.
- Second IRP node is installed with the same version of IRP as on $IRPMASTER. We will refer to this node as $IRPSLAVE.
- IRP services, MySQL and HTTP daemons are stopped on $IRPSLAVE node.
- Network operator can SSH to both $IRPMASTER and $IRPSLAVE and subsequent commands are assumed to be run from a $IRPMASTER console.
Configure communication channel from $IRPMASTER to $IRPSLAVE #
root@IRPMASTER ~ # ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -C "failover@noction"
root@IRPMASTER ~ # cat ~/.ssh/id_rsa.pub | while read key; do ssh $IRPSLAVE "echo $key >> ~/.ssh/authorized_keys"; done
root@IRPMASTER ~ # ssh $IRPSLAVE
Install certificate and keys for MySQL Multi-Master replication between $IRPMASTER and $IRPSLAVE #
# cd && rm -rvf irp-certs && mkdir -p irp-certs && cd irp-certs # openssl genrsa 2048 > $(hostname -s)-ca-key.pem # openssl req -new -x509 -nodes -days 3600 -subj "/C=US/ST=CA/L=Palo Alto/O=Noction/OU=Intelligent Routing Platform/CN=$(/bin/hostname) CA/emailAddress=support@noction.com" -key $(hostname -s)-ca-key.pem -out $(hostname -s)-ca-cert.pem # openssl req -newkey rsa:2048 -days 3600 -subj "/C=US/ST=CA/L=Palo Alto/O=Noction/OU=Intelligent Routing Platform/CN=$(/bin/hostname) server/emailAddress=support@noction.com" -nodes -keyout $(hostname -s)-server-key.pem -out $(hostname -s)-server-req.pem # openssl rsa -in $(hostname -s)-server-key.pem -out $(hostname -s)-server-key.pem # openssl x509 -req -in $(hostname -s)-server-req.pem -days 3600 -CA $(hostname -s)-ca-cert.pem -CAkey $(hostname -s)-ca-key.pem -set_serial 01 -out $(hostname -s)-server-cert.pem # openssl req -newkey rsa:2048 -days 3600 -subj "/C=US/ST=CA/L=Palo Alto/O=Noction/OU=Intelligent Routing Platform/CN=$(/bin/hostname) client/emailAddress=support@noction.com" -nodes -keyout $(hostname -s)-client-key.pem -out $(hostname -s)-client-req.pem # openssl rsa -in $(hostname -s)-client-key.pem -out $(hostname -s)-client-key.pem # openssl x509 -req -in $(hostname -s)-client-req.pem -days 3600 -CA $(hostname -s)-ca-cert.pem -CAkey $(hostname -s)-ca-key.pem -set_serial 01 -out $(hostname -s)-client-cert.pem
Verify certificates. Commands must be run on both $IRPMASTER and $IRPSLAVE nodes:
# openssl verify -CAfile $(hostname -s)-ca-cert.pem $(hostname -s)-server-cert.pem $(hostname -s)-client-cert.pem server-cert.pem: OK client-cert.pem: OK
Install certificates in designated directories. Commands must be run on both $IRPMASTER and $IRPSLAVE nodes:Cross copy client key and certificates:
# mkdir -p /etc/pki/tls/certs/mysql/server/ /etc/pki/tls/certs/mysql/client/ /etc/pki/tls/private/mysql/server/ /etc/pki/tls/private/mysql/client/ # cp $(hostname -s)-ca-cert.pem $(hostname -s)-server-cert.pem /etc/pki/tls/certs/mysql/server/ # cp $(hostname -s)-ca-key.pem $(hostname -s)-server-key.pem /etc/pki/tls/private/mysql/server/ # cp $(hostname -s)-client-cert.pem /etc/pki/tls/certs/mysql/client/ # cp $(hostname -s)-client-key.pem /etc/pki/tls/private/mysql/client/ # cd && rm -rvf irp-certs
root@IRPMASTER ~# scp "/etc/pki/tls/certs/mysql/server/$IRPMASTER-ca-cert.pem" "$IRPSLAVE:/etc/pki/tls/certs/mysql/client/" root@IRPMASTER ~# scp "/etc/pki/tls/certs/mysql/client/$IRPMASTER-client-cert.pem" "$IRPSLAVE:/etc/pki/tls/certs/mysql/client/" root@IRPMASTER ~# scp "/etc/pki/tls/private/mysql/client/$IRPMASTER-client-key.pem" "$IRPSLAVE:/etc/pki/tls/private/mysql/client/" root@IRPMASTER ~# scp "$IRPSLAVE:/etc/pki/tls/certs/mysql/server/$IRPSLAVE-ca-cert.pem" "/etc/pki/tls/certs/mysql/client/" root@IRPMASTER ~# scp "$IRPSLAVE:/etc/pki/tls/certs/mysql/client/$IRPSLAVE-client-cert.pem" "/etc/pki/tls/certs/mysql/client/" root@IRPMASTER ~# scp "$IRPSLAVE:/etc/pki/tls/private/mysql/client/$IRPSLAVE-client-key.pem" "/etc/pki/tls/private/mysql/client/"
# chown -R mysql:mysql /etc/pki/tls/certs/mysql/ /etc/pki/tls/private/mysql/ # chmod 0600 /etc/pki/tls/private/mysql/server/* /etc/pki/tls/private/mysql/client/*
Configure MySQL replication on $IRPSLAVE #
IRP includes a template config file /usr/share/doc/irp/irp.my_repl_slave.cnf.template. The template designates $IRPSLAVE as second server of the Multi-Master replication and includes references to $(hostname -s) that need to be replaced with the actual hostname of $IRPSLAVE before installing. Apply the changes and review the configuration file. Alternatively a command like in the below example can be used to create $IRPSLAVE config file from template. Ensure using actual short host name instead of the provided variable:
# Ubuntu
root@IRPSLAVE ~# sed 's|$(hostname -s)|$IRPSLAVE|' < /usr/share/doc/irp/irp.my_repl_slave.cnf.template > /etc/mysql/conf.d/irp.my_repl_slave.cnf
# RedHat
root@IRPSLAVE ~# sed 's|$(hostname -s)|$IRPSLAVE|' < /usr/share/doc/irp/irp.my_repl_slave.cnf.template > /etc/my.cnf.d/irp.my_repl_slave.cnf
The config file created above must be included into $IRPSLAVE node’s MySQL config my.cnf. It is recommended to store these files inside OS-specific directories for MariaDB configuration files (Ubuntu: /etc/mysql/conf.d, RedHat: /etc/my.cnf.d/, otherwise it should be included via !include /path/to/file from main MariaDB config.
root@IRPSLAVE ~# systemctl start mariadb root@IRPSLAVE ~# tail -f /var/log/mysqld.log root@IRPSLAVE ~# mysql irp -e "show master status \G" root@IRPSLAVE ~# systemctl stop mariadb
Configure MySQL replication on $IRPMASTER #
Alternatively a command like the example below can be used to create $IRPMASTER config file from template. Ensure using actual short host name instead of the provided variable:
#Ubuntu root@IRPMASTER ~# sed 's|$(hostname -s)|$IRPMASTER|' < /usr/share/doc/irp/irp.my_repl_master.cnf.template > /etc/mysql/conf.d/irp.my_repl_master.cnf #Redhat root@IRPMASTER ~# sed ’s|$(hostname -s)|$IRPMASTER|’ < /usr/share/doc/irp/irp.my_repl_master.cnf.template > /etc/my.cnf.d/irp.my_repl_master.cnf
Again, the config file created above must be included into $IRPMASTER node’s MySQL config my.cnf. It is recommended to store these files inside OS-specific directories for MariaDB configuration files (Ubuntu: /etc/mysql/conf.d, RedHat: /etc/my.cnf.d/, otherwise it should be included via !include /path/to/file from main MariaDB config.
root@IRPMASTER ~# systemctl restart mariadb root@IRPMASTER ~# tail -f /var/log/mysqld.log root@IRPMASTER ~# mysql irp -e "show master status \G"
Create replication grants on $IRPMASTER #
mysql> CREATE USER 'irprepl'@'<mysql_slave1_ip_address>' IDENTIFIED BY '<replication_user_password>'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'irprepl'@'<mysql_masterslave1_ip_address>' REQUIRE CIPHER 'DHE-RSA-AES256-SHA'; mysql> CREATE USER 'irprepl'@'<mysql_master2_ip_address>' IDENTIFIED BY '<replication_user_password>'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'irprepl'@'<mysql_slave2_ip_address>' REQUIRE CIPHER 'DHE-RSA-AES256-SHA';
Copy IRP database configuration and database to $IRPSLAVE #
Copy root’s .my.cnf config file if exists:
root@IRPMASTER ~# scp /root/.my.cnf $IRPSLAVE:/root/
Copy config files:
root@IRPMASTER ~# scp /etc/noction/db.global.conf $IRPSLAVE:/etc/noction/ root@IRPMASTER ~# scp /etc/noction/clickhouse/users.xml $IRPSLAVE:/etc/noction/clickhouse/
root@IRPMASTER ~# rsync -av --progress --delete --delete-after --exclude="master.info" --exclude="relay-log.info" --exclude="*-bin.*" --exclude="*-relay.*" /var/lib/mysql/ $IRPSLAVE:/var/lib/mysql/
root@IRPMASTER ~# systemctl stop mariadb clickhouse-server # RedHat Enterprise Linux root@IRPMASTER ~# systemctl stop mysql clickhouse-server # Ubuntu root@IRPMASTER ~# systemctl start irp-stop-nobgpd.target systemctl start irp-shutdown-except-bgpd.target systemctl start irp-shutdown.target root@IRPMASTER ~# cd /var/lib/mysql && rm -vf ./master.info ./relay-log.info ./*-bin.* ./*-relay.* root@IRPMASTER ~# rsync -av --progress --delete --delete-after /var/lib/mysql/ $IRPSLAVE:/var/lib/mysql/
Start replication (Slaves) on both $IRPMASTER and $IRPSLAVE #
$IRPMASTER-mysql> CHANGE MASTER TO MASTER_HOST='$IRPSLAVE-ip-address', MASTER_USER='irprepl', MASTER_PASSWORD='$IRPSLAVE-password>', MASTER_PORT=3306, MASTER_LOG_FILE= '$IRPSLAVE--bin.000001', MASTER_LOG_POS= <$IRPSLAVE-bin-log-position>, MASTER_CONNECT_RETRY=10, MASTER_SSL=1, MASTER_SSL_CAPATH='/etc/pki/tls/certs/mysql/client/', MASTER_SSL_CA='/etc/pki/tls/certs/mysql/client/$IRPSLAVE-ca-cert.pem', MASTER_SSL_CERT='/etc/pki/tls/certs/mysql/client/$IRPSLAVE-client-cert.pem', MASTER_SSL_KEY='/etc/pki/tls/private/mysql/client/$IRPSLAVE-client-key.pem', MASTER_SSL_CIPHER='DHE-RSA-AES256-SHA';
You must manually check what values to assign to
mysql> START SLAVE \G mysql> show slave status \G
$IRPSLAVE-mysql> CHANGE MASTER TO MASTER_HOST='$IRPMASTER-ip-address', MASTER_USER='irprepl', MASTER_PASSWORD='$IRPMASTER-password>', MASTER_PORT=3306, MASTER_LOG_FILE= '$IRPMASTER-bin.000001', MASTER_LOG_POS= <$IRPMASTER-bin-log-position>, MASTER_CONNECT_RETRY=10, MASTER_SSL=1, MASTER_SSL_CAPATH='/etc/pki/tls/certs/mysql/client/', MASTER_SSL_CA='/etc/pki/tls/certs/mysql/client/$IRPMASTER-ca-cert.pem', MASTER_SSL_CERT='/etc/pki/tls/certs/mysql/client/$IRPMASTER-client-cert.pem', MASTER_SSL_KEY='/etc/pki/tls/private/mysql/client/$IRPMASTER-client-key.pem', MASTER_SSL_CIPHER='DHE-RSA-AES256-SHA';
You must manually check what values to assign to
mysql> START SLAVE \G mysql> show slave status \G
# systemctl start irp.target
Configure Failover using Wizard on $IRPMASTER #
Run failover wizard: #
Configure IRP failover: #
Apply configuration changes to edge routers: #
Enable failover: #
Synchronize RRD statistics to $IRPSLAVE #
root@IRPMASTER ~ # rsync -av /var/spool/irp/ $IRPSLAVE:/var/spool/irp