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=:80Pastikan 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/helloLalu 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/helloAgar 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 situsList service
docker stack services situsID 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:latestScale 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 dc1Export 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_IDBuat 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: trueSelanjutnya 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 siteList service
docker service lsID 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/tcpScale up service site
docker service scale site_site=5