Nginx - Pihole cluster load balancing

Trong bài viết này mình sẽ cùng bạn dựng DNS server với pihole và dùng nginx để làm load balancing.

Tổng quát luồng xử lý như sau:

# DNS
DNS request :53 --> nginx :53 --> pihole_1 :531
                              --> pihole_2 :532

# HTTP
Admin user :8080 --> nginx :8080 --> pihole_1 :8081
                                 --> pihole_2 :8082

Môi trường

Server đã cài đặt sẵn các ứng dụng và dịch vụ như sau:

Cài đặt Pihole Cluster

Tạo file docker-compose.yml nội dung như bên dưới, cluster gồm 2 docker, share chung data, thư mục mount tạo tự động ở cùng cấp với file docker-compose.yml

version: "3"

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
  pihole1:
    container_name: pihole1
    image: pihole/pihole:latest
    ports:
      - "531:53/tcp"
      - "531:53/udp"
      - "671:67/udp"
      - "8081:80/tcp"
    environment:
      TZ: 'Asia/Ho_Chi_Minh'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # Volumes store your data between container upgrades
    volumes:
      - './etc-pihole/:/etc/pihole/'
      - './etc-dnsmasq.d/:/etc/dnsmasq.d/'
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped
  pihole2:
    container_name: pihole2
    image: pihole/pihole:latest
    ports:
      - "532:53/tcp"
      - "532:53/udp"
      - "672:67/udp"
      - "8082:80/tcp"
    environment:
      TZ: 'Asia/Ho_Chi_Minh'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # Volumes store your data between container upgrades
    volumes:
      - './etc-pihole/:/etc/pihole/'
      - './etc-dnsmasq.d/:/etc/dnsmasq.d/'
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Lưu file.

Tạo container: docker-conpose up -d

Kiểm tra các container với docker ps hoặc docker stats ta có như minh họa sau:

Cấu hình Nginx

nginx làm reverse proxy cho DNS request TCP/UDP port 53

Cầu hình này yêu cầu cần nằm ngang cấp với thẻ http của nginx, edit file /etc/nginx/nginx.conf thêm vào nội dung:

stream {
  upstream dns_servers {
    server 127.0.0.1:531 fail_timeout=5s;
    server 127.0.0.1:532 fail_timeout=5s;
  }

  server {
    listen 53 udp;
    listen 53; #tcp
    proxy_pass dns_servers;
    error_log /var/log/nginx/dns.log info;
    proxy_responses 1;
    proxy_timeout 1s;
  }
}

nginx làm load-balancer cho pihole web UI

Tạo 1 file pihole_cluster_ui.conf trong /etc/nginx/sites-available, nội dung:

upstream pihole_ui {
  server 127.0.0.1:8081;
  server 127.0.0.1:8082;
}

server {
  listen 8080;
  location / {
    proxy_pass http://pihole_ui;
    proxy_set_header Host $host;
  }
}

Enable file cấu hình trên:

cd /etc/nginx/sites-enabled/
# tạo symbolic link
ln -s ../etc/nginx/sites-available/pihole_cluster_ui.conf pihole_cluster_ui.conf

Kiểm tra cấu hình với: nginx -t (hoặc nginx -T)

Ngoài ra, cổng 53 trên Ubuntu thường đã được sử dụng, tham khảo hướng dẫn sau để giải phóng cổng này, tóm tắt:

Đến đây, các thay đổi trên chưa được nginx sử dụng, áp dụng cấu hình mới với lệnh: service nginx reload

Sử dụng

Lưu ý

Với cấu hình hiện tại, khi bạn xem truy cập trong trang Pihole Web Admin, sẽ thấy server không nhận được IP chính xác của client đang request, thay vậy, sẽ là IP của Nginx server (hoặc docker gateway), nếu cần cho pihole nhận biết chính xác IP của client, xem thêm tài liệu sau: IP Transparency and Direct Server Return with NGINX and NGINX Plus as Transparent Proxy

Tags:
#nginx #docker #pihole #load-balancing #load-balancer #cluster