Docker Swarm cluster

Docker swarm adalah container orchestration dan clustering tool untuk mengatur Docker hosts, yang merupakan bagian dari Docker engine. Yang merupakan original clustering yang dibuat dan disediakan oleh Docker sehingga menjamin High Availability dan High Performance aplikasi yang jalan.

Kali ini kita akan mencoba docker swarm dengan topologi seperti berikut

Docker1 (192.168.192.45) sebagai manager kemudian docker2 (192.168.192.47) dan docker3 (192.168.192.46) sebagai workernya. Semua server menggunakan OS Ubuntu 18.04.

Konfigurasi hosts di semua node docker

Edit file /etc/hosts disemua server, dan tambahkan syntax berikut

192.168.192.45 docker1
192.168.192.47 docker2
192.168.192.46 docker3

Coba ping dari node docker1 ke docker2 atau docker3, lakukan sebaliknya juga

[email protected]:~$ ping docker2
PING docker2 (192.168.192.47) 56(84) bytes of data.
64 bytes from docker2 (192.168.192.47): icmp_seq=1 ttl=64 time=0.308 ms
64 bytes from docker2 (192.168.192.47): icmp_seq=2 ttl=64 time=0.318 ms
64 bytes from docker2 (192.168.192.47): icmp_seq=3 ttl=64 time=0.350 ms
^C
--- docker2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2031ms
rtt min/avg/max/mdev = 0.308/0.325/0.350/0.023 ms
[email protected]:~$ ping docker3
PING docker3 (192.168.192.46) 56(84) bytes of data.
64 bytes from docker3 (192.168.192.46): icmp_seq=1 ttl=64 time=0.521 ms
64 bytes from docker3 (192.168.192.46): icmp_seq=2 ttl=64 time=0.555 ms
64 bytes from docker3 (192.168.192.46): icmp_seq=3 ttl=64 time=0.574 ms
^C
--- docker3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2052ms
rtt min/avg/max/mdev = 0.521/0.550/0.574/0.021 ms

Install dan menjalankan Docker Service di semua node docker

Update dan upgrade apt

# apt update && apt upgrade -y

Install paket untuk meng”allow” apt dapat digunakan melalui https

# apt-get install apt-transport-https ca-certificates curl software-properties-common -y

Tambahkan Docker GPG key dan set repositorinya

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Install Docker CE versi terbaru

# apt-get install docker-ce

Enable docker service agar dapat jalan otomatis setiap server booting/direstart, kemudian start docker service

# systemctl enable docker
# systemctl start docker

Agar docker bisa dijalan pada user biasa (bukan root), gunakan command

# usermod -aG docker <username>

Pada lab kali ini saya menggunakan user ubuntu

# usermod -aG docker ubuntu

Sekarang kita coba menjalankan docker hello-world menggunakan user biasa

[email protected]:/home/ubuntu# su - ubuntu
[email protected]:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
The Docker client contacted the Docker daemon.
The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/

Konfigurasi Docker1 Node untuk Inisialisasi Swarm Cluster

Sekarang kita akan membuat swram cluster untuk ketiga node. Untuk membuatnya, memerlukan inialisasi pada dockermanager node (pada lab ini docker1 sebagai manager) kemudian dockerworker (docker2 dan docker3) untuk join cluster.

docker swarm init –advertise-addr <manager node IP address>

[email protected]:~$ docker swarm init --advertise-addr 192.168.192.45
Swarm initialized: current node (ifoxr4e0uvx75wjoa5x38ebn5) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0oxl56zp3d6uafxq21tk6pyblh4a1d2l7v6nfod0cl1f6d6wa6-40ptwffkqc8ynp07urtgkdl35 192.168.192.45:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
[email protected]:~$

Pada hasil diatas, join token sudah digenerate oleh dockermanager, ini nanti digunakan untuk join dockerworkers

Konfigurasi Docker2 dan Docker3 Node untuk join Swarm Cluster

Dari hasil join token diatas, ketikkan command diatas tadi ke docker2 dan docker3

[email protected]:~$ docker swarm join --token SWMTKN-1-0oxl56zp3d6uafxq21tk6pyblh4a1d2l7v6nfod0cl1f6d6wa6-40ptwffkqc8ynp07urtgkdl35 192.168.192.45:2377
This node joined a swarm as a worker.
[email protected]:~$ docker swarm join --token SWMTKN-1-0oxl56zp3d6uafxq21tk6pyblh4a1d2l7v6nfod0cl1f6d6wa6-40ptwffkqc8ynp07urtgkdl35 192.168.192.45:2377
This node joined a swarm as a worker.

Verifikasi Swarm Cluster

Untuk melihat status node menggunakan command berikut di dockermanager

[email protected]:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ifoxr4e0uvx75wjoa5x38ebn5 * docker-1 Ready Active Leader 18.09.3
2ar0x7l132sxmvdpxyijd7r4p docker-2 Ready Active 18.09.3
moxtattg9gmsigwhgxk2rzh9s docker-3 Ready Active 18.09.3

Apabila kehilangan join token, bisa menggunakan command

docker swarm join-token manager -q

docker swarm join-token worker -q

Cluster WEB menggunakan Nginx

Hi…

Kali ini kita akan mecoba membuat cluster web sederhana menggunakan nginx sebagai loadbalancing nya, dan juga sync nya agar server web pertama dan web kedua sama isinya. Topologinya kurang lebih seperti berikut

Dalam lab ini membutuhkan 3 buah server (menggunakan Centos 7), yaitu 1 server sebagai gateway (yg diakses oleh user) dan 2 buah server untuk backend web server.

Detail IP nya sebagai berikut : 192.168.192.34 sebagai gateway server, 192.168.192.37 sebagai web1, dan 192.168.192.38 sebagai web2.

Untuk mempermudah, tambahkan di /etc/hosts pada semua server

vi /etc/hosts


192.168.192.34 gateway
192.168.192.37 web1
192.168.192.38 web2

Seperti biasa, update dan install epel-release pada semua server Centos

yum update -y
yum install epel-release -y

Setelah itu, install nginx disemua server, kemudian enable dan start service nginx

yum install nginx -y
systemctl enable nginx
systemctl start nginx

Edit index.html masing2 server, untuk pengecekan apakah service nginx sudah bekerja dengan baik.

vi /usr/share/nginx/html/index.html

Pada lab ini, index.html saya tambahkan nama masing2 server, sehingga menjadi seperti berikut tampilan webnya

gateway
web1
web2

Sekarang edit nginx.conf pada gateway server, ubah dan tambahkan konfigurasi sehingga menjadi seperti berikut :

[[email protected] centos]# vi /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;
}

http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

upstream 192.168.192.34 {
least_conn;
server 192.168.192.37:80;
server 192.168.192.38:80;
}

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 192.168.192.34;
#root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
proxy_pass http://192.168.192.34;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
index index.html index.htm;
}


error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }

}

Kemudian restart service nginx

systemctl restart nginx

Sekarang coba di web browser, akan mengarah ke web1 dan web2, setiap di refresh akan ganti-gantian

Sampai disini kita sudah bisa membuat loadbalancing di cluster. Dan untuk membuat sama isi dari web1 dan web2, menggunakan metode rsync untuk sinkronisasinya dan crontab untuk menjadwalkan waktu sikronisasinya.

Di lab kali ini, master data web akan saya letakkan di gateway, dimana doc root dari web tidak akan diakses oleh user web langsung.

Untuk mempermudah rsync, pastikan gateway server bisa akses web1 dan web2 tanpa menggunakan password. Untuk amannya, kita akan menggunakan ssh key. Jadi generate dulu ssh key di gateway server, menggunakan perintah :

ssh-keygen -t rsa

Sehingga akan digenerate public key (id_rsa.pub) dan private ke (id_rsa). Lokasi filenya ada di ~/.ssh/

Copykan isi id_rsa.pub ke authorized_keys pada web1 dan web2. Setelah itu restart service ssh pada semua service untuk memastikan service ssh berjalan dengan baik.

Sekarang apakah sudah bisa ssh akses web1 dan web2 dari gateway.

ssh [email protected]
ssh [email protected]

Sekarang coba rsync dari gateway ke web1 dan web2

[[email protected] centos]# rsync -avzhe ssh /usr/share/nginx/html/ [email protected]:/usr/share/nginx/html/
sending incremental file list
./
index.html
sent 499 bytes received 74 bytes 1.15K bytes/sec
total size is 14.25K speedup is 24.87
[[email protected] centos]# rsync -avzhe ssh /usr/share/nginx/html/ [email protected]:/usr/share/nginx/html/
sending incremental file list
./
index.html
sent 499 bytes received 74 bytes 1.15K bytes/sec
total size is 14.25K speedup is 24.87

Tampilan web apabila di refresh berulang kali, akan selalu sama

Sekarang buat crontab untuk rsync otomatis sesuai yg kita set. Di lab ini saya buat tiap 5 menit akan sinkronisasi, tentunya tergantung besaran data juga ya.

[[email protected] centos]# crontab -e
*/5 * * * * rsync -avzhe ssh /usr/share/nginx/html/ [email protected]:/usr/share/nginx/html/
*/5 * * * * rsync -avzhe ssh /usr/share/nginx/html/ [email protected]:/usr/share/nginx/html/

Untuk memastikan crontab jalan, isi web saya ubah. Tampilannya menjadi berikut

Selamat mencoba….