Create percona xtradb cluster using rkt containers on multiple hosts over flannel overlay network
Since the new technologies are using containers I have decided to give rkt a try to see what it can do. Rkt is developed by CoreOs and was announced in 2014. It got alot of attention in February 2016 when it was released version 1.0. Rkt can run docker images therefore there is no more need for docker to run the already built images.
It's enough about rkt since there are quite a lot of informations out there which does not need to be repeated. To cover the setup we are using 3 deployed virtual machines with public IP's running Debian jessie. We are running an etcd v3.2.0 cluster on the hosts running rkt. To make it simple we do not use ssl/tls certificates to encrypt the internode traffic. To run the containers in background we are running it using systemd.
Let's see how it is done.
First we are creating an etcd cluster id by simple browing http://54.215.153.3/new:
#curl http://54.215.153.3/new
https://discovery.etcd.io/<etcd cluster discovery id>
Once we have the cluster discovery id we can start running the rkt container using the following command:
#systemd-run --slice=machine \
--unit=etcd3 \
rkt run \
--net=host \
--dns=8.8.8.8 \
--hostname=$(hostname) \
--set-env=ETCD_INITIAL_ADVERTISE_PEER_URLS=http://$(hostname -I | awk '{print $1}'):2380 \
--set-env=ETCD_DISCOVERY=http://54.215.153.3/<etcd cluster discovery id> \
--set-env=ETCD_LISTEN_PEER_URLS=http://$(hostname -I | awk '{print $1}'):2380 \
--set-env=ETCD_LISTEN_CLIENT_URLS=http://$(hostname -I | awk '{print $1}'):2379,http://$(hostname -I | awk '{print $1}'):4001,http://127.0.0.1:2379,http://127.0.0.1:4001 \
--set-env=ETCD_ADVERTISE_CLIENT_URLS=http://$(hostname -I | awk '{print $1}'):2379 \
--set-env=ETCD_NAME=$(hostname)-etcd-cluster \
--set-env=ETCD_DATA_DIR=$(hostname) \
coreos.com/etcd:v3.2.0 \
-- --log-output=stderr --- \
--debug=true
some of the more important options are:
--net = setting the networking type, In this case we are using the host networking therfore the etcd will be binding on the hosts IP addresses.
--dns = we are telling to the rkt what dns servers to be used.
--hostname = we are setting the hostname of the container
--debug = enabling or disabling debugging of the rkt
coreos.com/etcd:v3.2.0 is the image name which is to be used for the rkt container.
After starting the container on all the 3 nodes we can check the containers by running:
#rkt list
UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS
bda8c7d7 etcd coreos.com/etcd:v3.2.0 running 1 hour ago 1 hour ago
Now that we have the etcd cluster running it's time to configure the flanneld.
For this we need to install go version 1.5 or higher.
We have downloaded go versio 1.8. using the following link.
#cd /usr/src
#wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
#tar -xzvf go1.8.3.linux-amd64.tar.gz
#export GOPATH=/usr/src/go
#export GOROOT=/usr/src/go
#export PATH=$PATH:$GOROOT
Now it's time to download the flannel. This installer is a little bit weird cause it will need to be installed in under $GOPATH and with a specific folder path.
#apt-get update
#apt-get -y install build-essential linux-libc-dev git
#mkdir -p src/github.com/coreos
#git clone https://github.com/coreos/flannel.git
#cd flannel
#CGO_ENABLED=1 make dist/flanneld
#cp dist/flanneld /sbin/flanneld
Now that we have flanneld installed it's type to configure it. Flannel does not have a configuration file it's configuration it's registered into etcd. That is the reason why we have created the etcd cluster first.
First we need to create the flannel network config for rkt into /etc/rkt/net.d
:
#cat /etc/rkt/net.d/10-test.conf
{
"name": "test",
"type": "flannel"
}
Now we can register the flannel overlay network configuration using the following command:
#rkt enter --app=etcd bda8c7d7 etcdctl set /xtradb/network/config '
{
"Network": "10.0.0.0/8",
"SubnetLen": 20,
"SubnetMin": "10.10.0.0",
"SubnetMax": "10.99.0.0",
"Backend": {
"Type": "vxlan",
"VNI": 100,
"Port": 8472 }
}'
{"Network": "10.0.0.0/8", "SubnetLen": 20, "SubnetMin": "10.10.0.0", "SubnetMax": "10.99.0.0", "Backend": { "Type": "vxlan", "VNI": 100, "Port": 8472 } }
Now we can start running flanneld on each host. As for rkt we will be running flanneld using systemd:
#systemd-run \
--unit=flannel \
--slice=machine \
/sbin/flanneld \
-public-ip="$(hostname -I | awk '{print $1}')" \
-etcd-prefix \
/xtradb/network \
-etcd-endpoints=http://<host1_IP>:2379,http://<host2_IP>:2379,http://<host3_IP>:2379 \
-iface=eth0 \
--ip-masq=true \
-v=1
If we are watching the journalctl then we will see the following output:
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.748117 516 main.go:331] Using interface with name eth0 and address <host1_IP>
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.749289 516 main.go:344] Using <host1_IP> as external address
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.750008 516 main.go:148] Created subnet manager: &{registry:0xc4202dec90}
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.750588 516 main.go:151] Installing signal handlers
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.780903 516 main.go:248] Found network config - Backend type: vxlan
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.821736 516 local_manager.go:181] Picking subnet in range 10.10.0.0 ... 10.99.0.0
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.842398 516 local_manager.go:167] Allocated lease (10.12.16.0/20) to current node (<host1_IP>)
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.857298 516 ipmasq.go:47] Adding iptables rule: -s 10.0.0.0/8 -d 10.0.0.0/8 -j RETURN
Jun 17 17:22:41 test1 kernel: ip_tables: (C) 2000-2006 Netfilter Core Team
Jun 17 17:22:41 test1 kernel: nf_conntrack version 0.5.0 (8002 buckets, 32008 max)
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.920789 516 ipmasq.go:47] Adding iptables rule: -s 10.0.0.0/8 ! -d 224.0.0.0/4 -j MASQUERADE
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.931444 516 ipmasq.go:47] Adding iptables rule: ! -s 10.0.0.0/8 -d 10.0.0.0/8 -j MASQUERADE
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.937259 516 main.go:197] Wrote subnet file to /run/flannel/subnet.env
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.938328 516 main.go:202] Finished starting backend.
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.940547 516 vxlan_network.go:56] Watching for L3 misses
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.941405 516 vxlan_network.go:64] Watching for new subnet leases
Jun 17 17:22:41 test1 flanneld[516]: I0617 17:22:41.946535 516 main.go:285] Waiting for 22h59m59.876144802s to renew lease
Jun 17 17:22:51 test1 flanneld[516]: I0617 17:22:51.471353 516 vxlan_network.go:157] Handling initial subnet events
Jun 17 17:22:59 test1 flanneld[516]: I0617 17:22:59.391501 516 vxlan_network.go:116] Subnet added: 10.13.16.0/20
Now we have both etcd and flannel running and it's time to start the xtradb cluster nodes which will be registering to the etcd to create the cluster on different hosts. To create the nodes run the following command on each node. It is recommended to wait for the first node to start up before you start the next nodes.
#systemd-run \
--slice=machine \
--unit=xtradb \
rkt run \
--hostname=$(hostname)-container \
--set-env=MYSQL_ROOT_PASSWORD=somepass \
--set-env=DISCOVERY_SERVICE=$(hostname -I | awk '{print $1}'):2379 \
--set-env=CLUSTER_NAME=somecluster \
--set-env=XTRBACKUP_PASSWORD=xtr4b4ckup \
--net=default,test \
--port=3306-tcp:13601 \
--insecure-options=image \
docker://quay.io/zozo6015/percona-xtradb:latest \
--name=xtradb \
--debug=true
I am using a slightly modified docker percona xtradb image since the script inside which ensures if the cluster nodes are registered into etcd were not working properly so I had to fix the script for my usage. But the official image should be working as well out of the box.
Once all the 3 nodes are started properly you can check the mysql cluster status using the following commands:
#rkt list
UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS
bda8c7d7 etcd coreos.com/etcd:v3.2.0 running 1 hour ago 1 hour ago
dd10431a xtradb quay.io/zozo6015/percona-xtradb:latest running 1 hour ago 1 hour ago test:ip4=10.12.16.2, default:ip4=172.16.28.2
#rkt enter dd10431a mysql -u root -psomepass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1238
Server version: 5.7.18-15-57-log Percona XtraDB Cluster (GPL), Release rel15, Revision 7693d6e, WSREP version 29.20, wsrep_29.20
Copyright (c) 2009-2017 Percona LLC and/or its affiliates
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show status like 'wsrep_%';
....
| wsrep_incoming_addresses | 10.15.160.2:3306,10.12.16.2:3306,10.13.16.2:3306 |
| wsrep_cluster_size | 3 |
....
+----------------------------------+--------------------------------------------------+
67 rows in set (0.00 sec)
mysql>
As results this is a very simple way of creating a percona xtradb cluster using rkt. Of course we could use some mounted folders from the host to ensure that we don't loose any files in case the xtradb cluster goes down and the container needs to be redeployed but that is not covered into this tutorial since it's coverage inside the rkt documentation is good enough.