1. Home
  2. Docs
  3. Self-hosted Server
  4. Docker: Open-Source Conta...
  5. Docker Swarm: High Availability Docker Cluster

Docker Swarm: High Availability Docker Cluster

Docker Swarm adalah solusi clustering untuk Docker. Yang bisa membuat kita menjalankan Docker Container dalam mode HA (High Availability) dan mudah untuk skaling up/down pada beberapa server.

Alasan Menggunakan Docker Swarm

  • Docker Swarm solusi clustering native untuk docker.
  • Docker Swarm lebih mudah di setup/setting daripada Kubernetes.
  • Docker Swarm jauh lebih hemat biaya untuk membuat Docker Container Cluster dibandingkan dengan Kubernetes.

Contoh Skenario

Dalam dokumentasi ini saya akan mencontohkan bagaimana setup High Availability Docker Swarm dengan skenario :

Docker Swarm: High Availability Docker Cluster + GlusterFS + Keepalived
  • Manager NODE, Karena untuk implementasi High Availability harus mempunyai minimal 3 manager-node jadi saya menyiapkan 3 pcs server fisik. Spesifikasi masing-masing server 4 CPU RAM 2GB.
  • Load Balancer menggunakan Keepalived.
  • Distributed Network Storage menggunakan GlusterFS.

Setup Docker Swarm Cluster

Install Docker, Docker Compose dan Git di setiap node sebelum inisialisasi docker swarm.

Inisialisasi Swarm Mode

Kemudian inisialisasi docker swarm di server node-master-1, login ssh dan jalankan perintah :

adam@master-1:~# sudo docker swarm init --advertise-addr 192.168.99.101

Dalam contoh di dokumentasi ini, sesuaikan --advertise-addr dengan IP kita. Saya menggunakan IP 192.168.99.101 di node-master-1. Output yang muncul akan seperti ini :

Swarm initialized: current node (myjwx5z3m7kcrplih1yw0e2sy) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-2gwqttpup0hllec6p6xkun8nmht4xu18g09vsxyjhlyqc9sgjw-729yfmz5rfg02eiw0537m49c1 192.168.99.101:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Setelah kita inisialisasi swarm mode, ada 2 perintah untuk menambahkan node manager atau node worker.

Join Manager

Karena kita hanya menggunakan 3 node sebagai master semua jadi jalankan kembali perintah berikut untuk mendapatkan join-token sebagai manager yang akan kita jalankan di node-master-2 dan node-master-3.

adam@master-1:~# sudo docker swarm join-token manager

Setelah muncul perintah join-token untuk manager, jalankan perintah di node-master-2 dan node-master-3 :

$ sudo docker swarm join --token SWMTKN-1-2gwqttpup0hllec6p6xkun8nmht4xu18g09vsxyjhlyqc9sgjw-eba5cbn1o4zv449w441bndfv0 192.168.99.101:2377

Join Worker

Untuk mendapatkan join-token jika kita mempunyai node Worker, jalankan perintah seperti :

adam@master-1:~# sudo docker swarm join-token worker

Kemudian jalankan perintah join-token yang muncul di server node worker kita.

Cek Daftar Member Node

Setelah kita menambahkan node-node, kita bisa cek member node swarm dengan menjalankan perintah pada salah satu node manager :

adam@master-1:~# sudo docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
yowshmeyvxwhu8kf979kn3gh6 *   master-1   Ready     Active         Leader           25.0.2
rzn3rmbdkw1d6y9wmfm367u40     master-2   Ready     Active         Reachable        25.0.2
uolr8v5k5uipuqj81rmjdb8br     master-3   Ready     Active         Reachable        25.0.2

Sampai sini kita sudah selesai setup docker swarm cluster setelah inisialilasi semua manager node.

Keepalived

Karena kita menerapkan High Availability Docker Swarm, dengan Keepalived kita bisa memungkinkan hanya menggunakan satu Virtual IP untuk mengakses semua services atau aplikasi dalam docker swarm, tanpa harus menargetkan ke IP masing-masing node. Keepalived dapat self-healing jika salah satu node mati, jadi IP selalu online untuk di akses oleh user.

Dalam contoh skenario ini, kita akan membuat 1 Virtual IP. IP Ini akan terarahkan ke salah satu node dan jika salah satu node mati, IP akan renegotiate routing otomatis ke node lain nya.

Contoh Layout:

  • master-1 192.168.99.101
  • master-2 192.168.99.102
  • master-3 192.168.99.103
  • Ingress (Virtual IP) – 192.168.99.100

Jadi user hanya mengakses 1 IP yaitu 192.168.99.100 untuk akses service atau aplikasi dalam container docker swarm kita.

Install

Jalankan perintah dibawah di semua node untuk menginstall Keepalived

$ sudo apt-get -y install keepalived

Setelah Keepalived terinstall di masing-masing node kita harus edit konfigurasi pada file /etc/keepalived/keepalived.conf pada masing-masing node.

Edit Konfigurasi

Pada masing-masing node mempunyai konfigurasi berbeda untuk dapat provosioning.

node-master-1

adam@master-1:~# sudo nano /etc/keepalived/keepalived.conf

Kemudian isi dengan :

global_defs {
  router_id DOCKER_INGRESS
}

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass passwordkita
  }
  virtual_ipaddress {
  192.168.99.100
  }
}

Aktifkan service Keepalived pada node :

adam@master-1:~# systemctl start keepalived
adam@master-1:~# systemctl enable keepalived

node-master-2

adam@master-2:~# sudo nano /etc/keepalived/keepalived.conf

Isi file konfigurasi :

global_defs {
  router_id DOCKER_INGRESS
}

vrrp_instance VI_1 {
  state BACKUP
  interface eth0
  virtual_router_id 51
  priority 90
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass passwordkita
  }
  virtual_ipaddress {
    192.168.99.100
  }
}

Aktifkan service Keepalived pada node :

adam@master-2:~# systemctl start keepalived
adam@master-2:~# systemctl enable keepalived

node-master-3

adam@master-3:~# sudo nano /etc/keepalived/keepalived.conf

Isi file konfigurasi :

global_defs {
  router_id DOCKER_INGRESS
}

vrrp_instance VI_1 {
  state BACKUP
  interface eth0
  virtual_router_id 51
  priority 80
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass passwordkita
  }
  virtual_ipaddress {
    192.168.99.100
  }
}

Aktifkan service Keepalived pada node :

adam@master-3:~# systemctl start keepalived
adam@master-3:~# systemctl enable keepalived

Setelah konfigurasi keepalived di masing-masing node, kita bisa cek Virtual IP yang sudah kita tambahkan dengan menjalankan perintah di node-master-1 :

adam@master-1:~# ip a show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether fe:c3:8b:c2:b3:5a brd ff:ff:ff:ff:ff:ff
    inet 192.168.99.101/24 brd 192.168.99.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.99.100/32 scope global eth0
       valid_lft forever preferred_lft forever

Jika keepalived berhasil negotiate virtual ip di noce kita, kita bisa lihat terdapat IP 192.168.99.100 di interface eth0. Kita bisa coba ping IP tersebut di luar jaringan cluster kita.

GlusterFS

Karena kita mengimplementasikan High Availability Docker Swarm, jadi kita membutuhkan distributed file system yang bisa kita gunakan untuk menyimpan dan akses file di semua node. Menjaga high availability / data redundancy dengan konsep replikasi data otomatis dan mendistribusikan data di beberapa node berbeda. Pada contoh skenario ini saya menggunakan GlusterFS.

Di setiap node saya mempunyai Harddisk/SSD dengan kapasitas yang sama di khususkan untuk digunakan oleh Storage GlusterFS, dan saya menggunakan mode replikasi untuk replikasi data di semua node untuk kebutuhan Persistent Storage yang digunakan oleh container-container yang terdapat di docker swarm untuk menghindari single-point failure untuk penyimpanan data container.

Hostname

Saya menggunakan hostname agar Node/Peer GlusterFS dapat berkomunikasi, jadi saya edit /etc/hosts di semua node :

$ sudo nano /etc/hosts
192.168.99.101 master-1
192.168.99.102 master-2
192.168.99.103 master-3

Tinggal sesuaikan IP & hostname node swarm kita.

Install

Install GlusterFS di semua node dengan perintah :

$ sudo apt-get -y install glusterfs-server
$ sudo systemctl start glusterd
$ sudo systemctl enable glusterd

Persiapan Storage Volume

Di semua node kita buat Bricks untuk digunakan nantinya untuk membuat GlusterFS Volume. Bricks digunakan untuk menyimpan data asli di setiap server dan dianggap storage fisik dari GlusterFS volume.

Bricks

Di semua node yang terdapat harddisk, jalankan perintah berikut :

adam@master-1:~# fdisk -l

Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
.
.
.
Disk /dev/sda: 465.76 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Samsung SSD 870
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Jika kita lihat saya mempunyai Samsung SSD dengan kapasitas 500GB, jadi kita gunakan /dev/sda sebagai bricks di node-master-1.

# Format disk kita
adam@master-1:~# mkfs.xfs -f /dev/sda

# Buat lokasi folder untuk mounting ssd
adam@master-1:~# mkdir -p /mnt/ssd

# Tambahkan baris perintah ke /etc/fstab agar mount otomatis ssd saat booting
adam@master-1:~# echo "/dev/sda /mnt/ssd xfs defaults 0 0" | tee -a /etc/fstab

# Buat lokasi folder u/ dijadikan brick
adam@master-1:~# mkdir -p /mnt/ssd/glusterfs

# Mount
adam@master-1:~# mount -a

# Cek
adam@master-1:~# df -h /mnt/ssd/glusterfs

Lakukan hal yang sama di node-master-2 & node-master-3

Join Cluster

Join node-master-2 & node-master-3 ke cluster GlusterFS

adam@master-1:~# sudo gluster peer probe master-2
peer probe: success
adam@master-1:~# sudo gluster peer probe master-3
peer probe: success

# Check
adam@master-1:~# sudo gluster pool list
UUID                                    Hostname        State
2554d571-31ec-48f7-b049-f019efed7a14    master-2        Connected 
821bbeba-e992-4d68-82c3-a8736e661b2b    master-3        Connected 
bf7d20c5-7787-48f5-86ab-2c6abb394cc0    localhost       Connected

Kita bisa lihat semua node sudah join ke dalam glusterfs cluster.

Volume

Di GlusterFS, logical volume dibuat dari satu atau beberapa bricks (resource storage fisik). GlusterFS Volume adalah Storage Pool yang bisa di akses di beberapa node dalam cluster untuk menyimpan data. Di contoh skenario ini saya akan me replika 3 bricks semua node dengan mode Replicated dengan nama volume gfs0.

adam@master-1:~# sudo gluster volume create gfs0 replica 3 transport tcp master-1:/mnt/ssd/glusterfs master-2:/mnt/ssd/glusterfs master-3:/mnt/ssd/glusterfs

Cek volume yang kita buat dengan perintah :

adam@master-1:~# sudo gluster volume info gfs0
Volume Name: gfs0
Type: Replicate
Volume ID: e457ca40-026c-4ac0-8c50-14bdab3cadc3
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: master-1:/mnt/ssd/glusterfs
Brick2: master-2:/mnt/ssd/glusterfs
Brick3: master-3:/mnt/ssd/glusterfs
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

Start volume dengan perintah :

adam@master-1:~# sudo gluster volume start gfs0

Sekarang kita sudah mempunyai GlusterFS Volume, kita tinggal mount di semua node dalam cluster dengan jalankan perintah :

$ mkdir -p /mnt/docker
$ echo "localhost:/gfs0 /mnt/docker glusterfs defaults,_netdev 0 0" | sudo tee -a /etc/fstab
$ mount -a

Folder /mnt/docker adalah folder mounting volume glusterfs kita, dan sekarang kita sudah mempunyai persistent storage untuk docker container dengan kemampuan high availability dan redudancy.

Portainer

Tahap terakhir ya kita mulai deploy aplikasi di container docker swarm kita. Di sini saya coba mulai dengan deploy docker stack Portainer dalam cluster docker swarm, ya tentu saya kita gunakan nantinya untuk manage clustering kita.

Deploy

Buat docker-compose YAML.

$ nano portainer-agent-stack.yml

Dengan docker stack untuk deploy Portainer WebUI di salah satu manager node dan Portainer Agent di semua node

version: '3.2'

services:
  agent:
    image: portainer/agent:alpine
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer-ce:alpine
    command: -H tcp://portainer_agent:9001 --tlsskipverify
    ports:
      - "9443:9443"
      - "9000:9000"
      - "8000:8000"
    volumes:
      - /mnt/docker/portainer/data:/data
    networks:
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]

networks:
  agent_network:
    driver: overlay
    attachable: true

Jalankan perintah berikut untuk mulai deploy portainer :

$ sudo docker stack deploy -c portainer-agent-stack.yml portainer

Melihat container yang baru dibuat :

$ sudo docker stack ps portainer

Melihat log proses deploy

$ sudo docker service logs portainer_portainer
$ sudo docker service logs portainer_agent

Kalau dibandingkan dengan membangun clustering menggunakan kubernetes, docker swarm jauh lebih sederhana dan hemat resource.

Official Dokumentasi :
Docker Swarm : https://docs.docker.com/engine/swarm/
GlusterFS : https://docs.gluster.org/en/latest/
Keepalived : https://www.keepalived.org/manpage.html
Portainer : https://docs.portainer.io/start/install/server/swarm

Tags , , , ,

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *