0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NginxでL4LBを構築し、DNSの冗長化

Last updated at Posted at 2023-08-16

目的

Nginxをhttpロードバランサとして用いるケースはよくある。nginxはTCPやUDPでもルーティング出来る様なので、今回はそれを試す。

構成

dns冗長.png

ディレクトリ構造

  • docker-compose.yml
  • Dockerfile
  • docker-log
  • unbound.conf
  • nginx
    • Dockerfile
    • nginx.conf
    • start.sh

docker-compose.yml

unbound1, unbound2で2台のDNSを構築する。nginxl4でL4loadbalancerを構築

version: "3.9"
services:
  unbound1:
    build: .
    image: unbound-alma:1.0.0
    container_name: unbound1
    tty: true

    networks:
      vlan0:
        ipv4_address: 172.24.20.210
    volumes:
      - unbound1:/etc/unbound/log/

  unbound2:
    build: .
    image: unbound-alma:1.0.0
    container_name: unbound2
    tty: true

    networks:
      vlan0:
        ipv4_address: 172.24.20.211
    volumes:
      - unbound2:/etc/unbound/log/

  nginxl4:
    container_name: nginxl4
    restart: always
    build: ./nginx
    image: nginxl4
    tty: true
    stdin_open: true
    networks:
      vlan0:
        ipv4_address: 172.24.20.15

networks:
  vlan0:
    name: vlan0
    driver: macvlan
    driver_opts:
      parent: enp1s0
    ipam:
      config:
        - subnet: 172.24.20.0/24
          gateway: 172.24.20.254


volumes:
  unbound1:
  unbound2:

DNSの構築

以下には実際のDNSの設定を入れていく。

Dockerfile

FROM almalinux:latest
RUN yum -y update && yum -y install unbound
ADD unbound.conf /etc/unbound/
ENV TZ=Asia/Tokyo
ADD docker-log /etc/logrotate.d/

RUN mkdir -p /etc/unbound/log/
RUN chmod 777 /etc/unbound/log/ && \
chown unbound:unbound /etc/unbound/log/ && \
touch /etc/unbound/log/unbound.log && \
chmod 777 /etc/unbound/log/unbound.log && \
chown unbound:unbound /etc/unbound/log/unbound.log && \
chmod 644 /etc/logrotate.d/*

ENTRYPOINT ["/usr/sbin/unbound","-d","-c","/etc/unbound/unbound.conf"]

docker-log

ログの設定を入れる。

/etc/unbound/log/unbound.log { # 対象のログファイル
    ifempty            # ログファイルが空でもローテーションする
    dateformat .%Y%m%d # dateフォーマットを任意のものに変更する
    missingok          # ログファイルがなくてもエラーを出さない
    compress           # 圧縮する
    rotate 10          # 10世代分古いログを残す
    postrotate         # ローテート後にsyslogを再起動
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}

unbound.conf

unbound自体の設定ファイル。
ローカルドメインを一つ設定しておく。

server:
    # Send minimum amount of information to upstream servers to enhance
    # privacy. Only sends minimum required labels of the QNAME and sets
    # QTYPE to NS when possible.

    # See RFC 7816 "DNS Query Name Minimisation to Improve Privacy" for
    # details.

    # qname-minimisation: yes

    # allow local address
    access-control: 0.0.0.0/0 allow

    # listen interface
    interface: 0.0.0.0

    # hide version
    hide-version: yes
    hide-identity: yes


    logfile: "/etc/unbound/log/unbound.log"
    use-syslog: no
    log-queries: yes
    log-time-ascii: yes

    local-data: "www.tmcit.sho    IN A 172.24.20.25"
#    local-data: "fuga.example.com.    IN A 172.16.0.2"
#    local-data: "foo.example.com.     IN A 172.16.0.3"
#    local-data: "bar.example.com.     IN A 172.16.0.4"


#forward-zone:
#        name: "example.org."
#        forward-addr: 192.168.10.5

forward-zone:
        name: "."
        forward-addr: 8.8.8.8
        forward-addr: 8.8.4.4
        forward-addr: 172.24.2.51

Nginxの構築

Dockerfile

FROM almalinux:latest
ADD start.sh /
ADD nginx.conf /usr/local/nginx-1.25.1/conf/nginx.conf

RUN chmod +x /start.sh
RUN yum -y update && yum -y install wget gcc openssl-devel pcre-devel openssl-devel libxslt-devel gd-devel perl-ExtUtils-Embed epel-release nginx-mod-stream
RUN yum -y groupinstall "Development Tools"
RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
RUN yum -y install GeoIP-devel
RUN wget http://nginx.org/download/nginx-1.25.1.tar.gz
RUN tar -zxvf  nginx-1.25.1.tar.gz

RUN cd nginx-1.25.1 && ./configure --prefix=/usr/local/nginx-1.25.1 \
--user=www \
--group=www \
--pid-path=/var/run/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--lock-path=/var/run/nginx.lock \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_stub_status_module \
--without-http_rewrite_module \
--without-http_gzip_module \
--with-stream              \
--with-stream=dynamic      \
--with-stream_ssl_module   \
--with-stream_geoip_module \
--with-stream_geoip_module=dynamic

RUN cd nginx-1.25.1 && make && make install

RUN groupadd www && useradd -g www www && usermod -s /bin/false www

ENTRYPOINT ["/start.sh"]

start.sh

起動時に実行するスクリプト

start.sh
#!/bin/bash

/usr/local/nginx-1.25.1/sbin/nginx -c /usr/local/nginx-1.25.1/conf/nginx.conf
while true; do  echo test >> /dev/null; sleep 1s; done

nginx.conf

1行目で、モジュールの読み込みを行う。
streamディレクティブで、proxy先のサーバーを指定する

load_module /usr/local/nginx-1.25.1/modules/ngx_stream_module.so;

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {

}

#    include       mime.types;
#    default_type  application/octet-stream;
#
#    #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  logs/access.log  main;
#
#    sendfile        on;
#    #tcp_nopush     on;
#
#    #keepalive_timeout  0;
#    keepalive_timeout  65;
#
#    #gzip  on;

stream {
    proxy_protocol on;
    upstream dns {
        server 172.24.20.210:53;
        server 172.24.20.211:53;
    }

    server {
        listen 53 udp;
        proxy_pass dns;
    }
}

#        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

#        location / {
#            root   html;
#            index  index.html index.htm;
#        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
#        error_page   500 502 503 504  /50x.html;
#        location = /50x.html {
#            root   html;
#        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
#    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

確認

image.png

現状の課題

  • VPN越しだと解決が出来ない。同じセグメントに属している場合は問題なく解決できる

→ DNSをホストか、portsで公開

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?