Load balancing adalah proses mendistribusikan lalu lintas di beberapa server untuk ketersediaan tinggi (HA) dan skalabilitas elastis.
Jika sebelumnya sudah membahas tentang load balancer dengan apache, pada panduan kali ini akan membahas load balance beberapa instance dengan traefik pada lingkungan docker.
Docker CLI #
Jalankan container traefik
docker run -dit --name traefik \
-p 80:80 -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
traefik --api.insecure=true --providers.docker=true --providers.docker.exposedbydefault=false --entrypoints.web.address=:80
Pastikan akses ke dashboard traefik http://IP:8080 bisa diakses
Selanjutnya jalankan container nginx dan beri nama web1
docker run -dit --name web1 \
-l web1 \
--label 'traefik.enable=true' \
--label 'traefik.http.routers.web1.rule=Host(`example.io`)' \
--label 'traefik.http.services.web1.loadbalancer.server.port=80' \
--label 'traefik.http.routers.web1.entrypoints=web' \
nginxdemos/hello
Lalu jalankan container nginx dan beri nama web2
docker run -dit --name web2 \
-l web2 \
--label 'traefik.enable=true' \
--label 'traefik.http.routers.web2.rule=Host(`example.io`)' \
--label 'traefik.http.services.web1.loadbalancer.server.port=80' \
--label 'traefik.http.routers.web2.entrypoints=web' \
nginxdemos/hello
Agar trafik yang masuk dapat dibagi pada kedua container, setting label traefik.http.services.web1.loadbalancer.server.port=80
pada container web2
dan untuk container
yang akan dibuat selanjutnya dapat disamakan labelnya agar masuk ke http service web1
Terakhir akses http://example.io di browser dan aktifkan Auto Refresh untuk melihat perbedaannya. Atau dapat Anda test dengan bantuan tool wrk
lalu monitor dengan
docker stats
.
Jika label traefik.http.services.<service>.loadbalancer.server.port
pada setiap container diberi nama yang berbeda maka trafik yang masuk hanya akan diarahkan ke tujuan 1 container saja
dan tidak dibagi.
Lalu jika container tersebut mati maka traefik akan otomatis memindahkannya ke tujuan container yang memiliki label traefik.http.routers.<service>.rule
dengan Host
yang sama.
Docker Compose #
Ada 2 metode untuk penggunaan load balance yaitu dengan single node
dan swarm cluster
Single node #
version: "3.3"
services:
traefik:
image: "traefik"
command:
# - "--log.level=DEBUG"
- --api.insecure=true
- --providers.docker=true
# - "--providers.docker.defaultrule=Host(`{{ normalize .Name }}.example.io`)"
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --accesslog=true
- --accesslog.bufferingsize=100
- --accesslog.filepath=/var/log/traefik/traefik-access.log
# keep headers and user agents in logs
- --accesslog.fields.defaultmode=keep
- --accesslog.fields.names.ClientUsername=drop
- --accesslog.fields.headers.defaultmode=keep
- --accesslog.fields.headers.names.User-Agent=keep
- --accesslog.fields.headers.names.Authorization=drop
- --accesslog.fields.headers.names.Content-Type=keep
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/var/log/traefik:/var/log/traefik"
site:
image: "nginxdemos/hello"
labels:
- "traefik.enable=true"
- "traefik.http.routers.site.rule=Host(`example.com`)"
- "traefik.http.services.site.loadbalancer.server.port=80"
- "traefik.http.routers.site.entrypoints=web"
# Setting resource jika diperlukan
deploy:
resources:
limits:
cpus: "0.50"
memory: "512M"
reservations:
cpus: "0.25"
memory: "128M"
# Ini untuk scale up atau down.
web:
image: "nginxdemos/hello"
labels:
- "traefik.enable=true"
- "traefik.http.routers.scale.rule=Host(`example.com`)"
# Samakan dengan label pada service site.
- "traefik.http.services.site.loadbalancer.server.port=80"
- "traefik.http.routers.scale.entrypoints=web"
# Setting resource jika diperlukan
deploy:
resources:
limits:
cpus: "0.50"
memory: "512M"
reservations:
cpus: "0.25"
memory: "128M"
Lalu deploy
docker stack deploy -c docker-compose.yml situs
List service
docker stack services situs
ID NAME MODE REPLICAS IMAGE PORTS
fcxfxrkhaet1 traefik_site replicated 1/1 nginxdemos/hello:latest
ocy2ktvmxf10 traefik_traefik replicated 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp
vlpcggoyax73 traefik_web replicated 1/1 nginxdemos/hello:latest
Scale up atau replicate service
docker service scale traefik_web=<jumlah container>
Test load balance melalui http://example.com lalu aktifkan Auto Refresh atau test dengan bantuan tool seperti wrk
Swarm cluster #
Buat network overlay
docker network create --driver=overlay --attachable dc1
Export Node Id untuk memastikan trafik melalui node yang sama {% raw %}
export NODE_ID=$(docker info -f '{{.Swarm.NodeID}}')
{% endraw %}
Lalu tambahkan label pada node tersebut.
docker node update --label-add traefik-public.traefik-public-certificates=true $NODE_ID
Buat file traefik.yml
lalu edit
version: '3.9'
services:
traefik:
image: traefik
ports:
- 80:80
- 8080:8080
deploy:
mode: global
placement:
constraints:
# Tambahkan aturan berikut agar traefik hanya dibuat pada node yang dilabel atau bisa juga berdasarkan role manager
- node.labels.traefik-public.traefik-public-certificates == true
# - node.role == manager
labels:
- traefik.enable=true
- traefik.docker.network=dc1
- traefik.constraint-label=dc1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/log/traefik:/var/log/traefik
command:
- --log
- --api.insecure=true
- --providers.docker
- --providers.docker.network=dc1
- --providers.docker.constraints=Label(`traefik.constraint-label`, `dc1`)
- --providers.docker.exposedbydefault=false
- --providers.docker.swarmmode
- --entrypoints.http.address=:80
- --accesslog.bufferingsize=100
- --accesslog.filepath=/var/log/traefik/traefik-access.log
# keep headers and user agents in logs
- --accesslog.fields.defaultmode=keep
- --accesslog.fields.names.ClientUsername=drop
- --accesslog.fields.headers.defaultmode=keep
- --accesslog.fields.headers.names.User-Agent=keep
- --accesslog.fields.headers.names.Authorization=drop
- --accesslog.fields.headers.names.Content-Type=keep
networks:
- dc1
networks:
dc1:
external: true
Selanjutnya buat file site.yml
untuk websitenya.
version: "3.9"
networks:
dc1:
external: true
services:
site:
image: nginxdemos/hello
networks:
- dc1
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.site.rule=Host(`example.com`)"
- "traefik.http.routers.site.entrypoints=http"
- "traefik.docker.network=dc1"
- "traefik.constraint-label=dc1"
- "traefik.http.services.site.loadbalancer.server.port=80"
resources:
limits:
cpus: "0.50"
memory: "512M"
reservations:
cpus: "0.25"
memory: "128M"
Pastikan label ditambahkan dibawah konfig deploy agar label dapat terbaca saat mode swarm diaktifkan. {: .prompt-tip }
Deploy traefik dan website
docker stack deploy -c traefik.yml traefik
docker stack deploy -c site.yml site
List service
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
51iplyhnz93h site_site replicated 1/1 nginxdemos/hello:latest
m3t29drd6piy traefik_traefik global 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp
Scale up service site
docker service scale site_site=5