Project 3: Application Redundancy - squatchulator/Tech-Journal GitHub Wiki
https://www.linuxbabe.com/mariadb/galera-cluster-ubuntu
- On u1 u2 and u3, change he network adapters to LAN and boot. Create a new named user, elevate it to sudo group, rename server, delete old user on all 3.
- Edit the netplan configuration located in
/etc/netplan/00-installer-config.yaml
. The addresses for this box will be .201, .202, and .203 respectively.
network:
ethernets:
ens160:
dhcp4: false
addresses: [10.0.5.201(2,3)/24]
gateway4: 10.0.5.1
nameservers:
addresses: [10.0.5.1]
version: 2
- Enter the following to import the MariaDB repo key:
sudo apt-get -y install apt-transport-https curl
sudo mkdir -p /etc/apt/keyrings
sudo curl -o /etc/apt/keyrings/mariadb-keyring.pgp 'https://mariadb.org/mariadb_release_signing_key.pgp'
- Create a new file called
/etc/apt/sources.list.d/mariadb.sources
and add the following:
# MariaDB 11.3 repository list - created 2024-02-20 15:14 UTC
# https://mariadb.org/download/
X-Repolib-Name: MariaDB
Types: deb
# deb.mariadb.org is a dynamic mirror if your preferred mirror goes offline. See https://mariadb.org/mirrorbits/ for details.
# URIs: https://deb.mariadb.org/11.3/ubuntu
URIs: https://ftp.osuosl.org/pub/mariadb/repo/11.3/ubuntu
Suites: jammy
Components: main main/debug
Signed-By: /etc/apt/keyrings/mariadb-keyring.pgp
- Then, run an
apt-get update
and installmariadb-server
. This should also install galera4 which is what we will need for database redundancy. Run asystemctl enable mariadb
as well to enable on boot. - Edit the file
/etc/mysql/mariadb.conf.d/60-galera.cnf
and add the following:
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "MariaDB Galera Cluster"
wsrep_cluster_address = "gcomm://10.0.5.201,10.0.5.202,10.0.5.203"
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_force_primary_key = 1
innodb_doublewrite = 1
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 4
innodb_flush_log_at_trx_commit = 0
wsrep_node_name = <hostname of this node>
wsrep_node_address = "<this node's IP>"
# By default, MariaDB error logs are sent to journald, which can be hard to digest sometimes.
# The following line will save error messages to a plain file.
log_error = /var/log/mysql/error.log
- To let firewall traffic locally through, run
sudo ufw allow in from <ip>
3 times on each server, once for each IP in the cluster. Runsudo ufw enable
right after. Run the following on all 3 boxes:
cd /etc/apparmor.d/disable/
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld
sudo systemctl restart apparmor
- Now to start the cluster, we first need to shut off mariadb with systemctl or the following commands will not work. Run this on the primary node (first one, u1):
sudo systemctl stop mariadb
sudo galera_new_cluster
mysql -u root -p
show status like 'wsrep_cluster_size';
- This should show you that our node is successfully added. To add the other nodes, restart mariadb on the unadded ones and they should just pop up.
- To secure your cluster, go to u1 and run
sudo mariadb-secure-installation
and configure a root password. You should now be able to log in to mariadb using the same password on all 3 hosts!
- First thing to do on our web01 and web02 boxes is to tell SELinux to allow DB connections to our web server. This can be done with
sudo setsebool -P httpd_can_network_connect_db on
- Now we need to install PHP and MySQL.
sudo yum -y install php php-mysql
sudo systemctl restart httpd
- Head over to /var/www/html and create a new php file called
info.php
. Put the following in it:
<?php
phpinfo();
?>
- After saving and closing the file, navigate to
http://<server IP>/info.php
to check that it worked. - We have to create the MariaDB backend. Make sure that your clustering is working properly. Log into MariaDB on one of your databse servers with
mysql -u root -p
and runCREATE DATABASE <new_database>;
. This will make a new database that our frontend will use. - Run
USE <new_database>;
to select the one we just made, and then enter something similar to the following:
CREATE TABLE cats
(
id INT unsigned NOT NULL AUTO_INCREMENT, # Unique ID for the record
name VARCHAR(150) NOT NULL, # Name of the cat
owner VARCHAR(150) NOT NULL, # Owner of the cat
birth DATE NOT NULL, # Birthday of the cat
PRIMARY KEY (id) # Make the id the primary key
);
- When done, you can check that the table was made correctly with
SHOW TABLES;
andDESCRIBE <new_database>;
. If you want to insert additional information into the table, use something like the following:
INSERT INTO cats ( name, owner, birth) VALUES
( 'Siggy', 'Harold', '2018-01-05' ),
( 'Freya', 'Gutenberg', '2017-11-10' ),
( 'Patches', 'Charlie', '2015-05-15' );
-
You can select specific fields from a table using the SELECT statement. For example, running
SELECT * FROM cats;
will display all records on the "cats" table. This can be extended further by including the WHERE clause, which can look something likeSELECT name FROM cats WHERE owner = 'Charlie';
- this allows you to pretty thoroughly narrow down your database navigation. -
To integrate our MySQL servers with PHP, we need to create a new user in our databases. Replace the user password and change localhost to the IP of the Apache servers. Then to grant all perms to this new user, run
GRANT ALL PRIVILEGES ON <new_database>.* TO 'user'@'localhost' IDENTIFIED BY 'password';
-
Now from your web server, try to remotely log into the MySQL database as your new user with the command
mysql -u <new_user> -p -h <db_server_ip>
. -
Now to create the webpages. Go onto /var/www/html of your webserver and create three new files: birthday.html, add_cat.php, and birthday.php.
-
birthday.php:
<?php
$username = "miles";
$password = "password";
$database = "pets";
$name = $_POST['name'];
$mysqli=new mysqli('10.0.6.10', $username, $password, $database);
$query = "SELECT * from cats where name='".$name."'";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
$hostnameQuery = "SELECT @@hostname";
$hostnameResult = $mysqli->query($hostnameQuery);
$hostnameRow = $hostnameResult->fetch_assoc();
$hosttname = $hostnameRow['@@hostname'];
if ($result->num_rows > 0) {
while ($row=$result->fetch_assoc()) {
echo "Database server currently in use: " . $hostname . "</br>";
echo $row['name']."'s birthday is ".$row['birth']."</br>";
}
}
else {
echo 'NO RESULTS';'
}
?>
- add_cat.php:
<?php
$username = "miles";
$password = "password";
$database = "pets";
$newName = $_POST['new_name'];
$newOwner= $_POST['new_owner'];
$newBirth= $_POST['new_birth'];
$mysqli = new mysqli('localhost', $username, $password, $database);
$query = "INSERT INTO cats (name, owner, birth) VALUES ('$newName', '$newOwner', '$newBirth')";
$mysqli->query($query) or die($mysqli->error.__LINE__);
$mysqli->close();
header("Location: birthday.html");
exit();
?>
- birthday.html:
<html>
<body>
<form action="birthday.php" method="post">
Currently running web interface on: (web server name here) </br>
Look up your cat's birthday! </br>
Cats Name: <input type="text" name="name"></br>
<input type="Submit">
</form>
<form action="add_cat.php" method="post">
Add a new cat:</br>
Cat's Name: <input type="text" name="new_name"></br>
Owner's Name: <input type="text" name="owner_name"></br>
Cat's Birthday (YYYY-MM-DD): <input type="text" name="birthday"></br>
<input type="Submit" value="Add Cat">
</form>
</body>
</html>
- On both ha1 and ha2, edit the
/etc/haproxy/haproxy.cfg
file and add the following block below your haproxy configuration for the web servers:
frontend db
bind *:3306
mode tcp
default_backend dbpool
backend dbpool
balance roundrobin
mode tcp
server u1 10.0.5.201:3306 check
server u2 10.0.5.202:3306 check
server u3 10.0.5.203:3306 check
- Now restart haproxy on both servers with systemctl (NOTE: I also had to disable the firewall on the DB servers.)
- Install mariadb-client on xUbuntu-lan and make sure that the new account you made can access your new database
- Then go into xubuntu-wan, and edit the
/etc/hosts
file. Below the localhost section, add a new entry for your WAN IP and the hostnameweb-cluster.miles.local
.