DB 모니터링 솔루션 도입을 준비중이다.
솔루션의 구성을 대략 설명하자면 이렇다.
1) DB 메트릭을 받아서 관리하는 '수집 서버'
2) DB서버에 설치되어서 수집 서버에게 메트릭을 전달하는 '에이전트'
여기서 문제는 DB서버와 수집서버간의 직접 통신을 보안상 제한하고 있다는 것이다.
그래서 이 두 서버 사이에 proxy 서버를 놓고 통신을 중개하고자 한다.
이 솔루션은 tcp 프로토콜로 통신한다고 하며, 크게 리소스를 요구하지도 않을 것 같기에 가벼운 nginx를 선택했다.
stable, legacy, mainline 3가지 종류가 존재
Nginx에는 stream 모듈과 http 모듈이 존재한다.
stream 모듈
http 모듈
TCP proxy 서버를 구성하려면 stream 모듈을 사용하면 된다.
다만, 기본 레포지토리(yum, apt)에서 패키지로 설치하면 stream 모듈이 제공되지 않는다.
필요하다면 소스 코드를 직접 컴파일해서 설치해야 하며, 컴파일 할 때 --with-stream
옵션을 추가해야 한다.
참조 공식문서에 설명이 잘 되어있고, 구성이 아주 간단하다.
컴파일 설치
# nginx 1.24 stable version
[admin@test-b-srv ~]$ wget https://nginx.org/download/nginx-1.24.0.tar.gz
--2023-06-26 11:15:27-- https://nginx.org/download/nginx-1.24.0.tar.gz
Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5704::6, ...
Connecting to nginx.org (nginx.org)|3.125.197.172|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1112471 (1.1M) [application/octet-stream]
Saving to: ‘nginx-1.24.0.tar.gz’
100%[==================================================================================================>] 1,112,471 824KB/s in 1.3s
2023-06-26 11:15:30 (824 KB/s) - ‘nginx-1.24.0.tar.gz’ saved [1112471/1112471]
[admin@test-b-srv ~]$ tar -zxvf nginx-1.24.0.tar.gz
nginx-1.24.0/
nginx-1.24.0/auto/
...
[admin@test-b-srv nginx-1.24.0]$ ./configure --with-stream
checking for OS
+ Linux 3.10.0-1160.83.1.el7.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found
checking for gcc builtin atomic operations ... found
...
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
[admin@test-b-srv nginx-1.24.0]$ sudo make install
make -f objs/Makefile install
make[1]: Entering directory `/home/admin/nginx-1.24.0'
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I o bjs \
-o objs/src/core/nginx.o \
src/core/nginx.c
...
make[1]: Leaving directory '/home/admin/nginx-1.24.0'
# nginx.service 파일 생성
# 경로 꼭 확인할 것
# vi /etc/systemd/system/nginx.service
---
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# 등록
[root@test-b-srv system]# systemctl daemon-reload
# 부팅시 자동 실행 설정
[root@test-b-srv system]# systemctl enable --now nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /etc/systemd/system/nginx.service.
# 상태 확인
[root@test-b-srv system]# systemctl status nginx
● nginx.service - nginx
Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2023-06-26 11:26:57 KST; 4s ago
Process: 65069 ExecStart=/usr/local/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 65070 (nginx)
Tasks: 2
Memory: 676.0K
CGroup: /system.slice/nginx.service
├─65070 nginx: master process /usr/local/nginx/sbin/nginx
└─65071 nginx: worker process
Jun 26 11:26:57 test-b-srv systemd[1]: Starting nginx...
Jun 26 11:26:57 test-b-srv systemd[1]: Started nginx.
telnet으로 타겟 tcp 포트가 열렸는지 확인
python2 -m SimpleHTTPServer 6001
# nginx 설치
# nginx.conf 수정
events {
}
stream {
# target
upstream test-a {
server 211.xx.xx.aa:6001;
}
# tcp
server {
listen 6002;
proxy_pass test-a;
proxy_connect_timeout 1s;
}
}
# b서버의 tcp포트 오픈 체크
[root@test-c-srv ~]# telnet 211.xx.xx.bb 6002
Trying 211.xx.xx.bb...
Connected to 211.xx.xx.bb.
Escape character is '^]'.
netcat : TCP 또는 UDP를 통해 데이터를 주고 받을 수 있는 유틸리티
참조
실제 데이터를 주고 받을 수 있는지 테스트
proxy - b서버 211.xx.xx.bb
양방향 테스트를 위해 2개의 upstream 생성 (a → b → c, c→ b → a)
nginx.conf
#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 {
}
stream {
# ----- c->b->a -----
# target
upstream test-a {
server 211.xx.xx.aa:6001;
}
# tcp
server {
listen 6001;
proxy_pass test-a;
proxy_connect_timeout 1s;
}
# ------ a->b->c ------
# target
upstream test-c {
server 211.xx.xx.cc:6003;
}
# tcp
server {
listen 6003;
proxy_pass test-c;
proxy_connect_timeout 1s;
}
}
server - a서버 211.xx.xx.aa
6001번 포트를 열어놓는다
[root@test-a-srv ~]# nc -l 6001
client에서 데이터를 전송하면 아래처럼 실시간으로 확인할 수 있다.
[root@test-a-srv ~]# nc -l 6001
hi, I'm c
[root@test-c-srv ~]# cat test.txt
hi, I'm c
프록시 서버로 전달 [root@test-c-srv ~]# cat test.txt | nc 211.xx.xx.bb 6002
stream 모듈을 포함하지 않은 nginx로 tcp proxy 서버를 구축하려는 경우 발생하는 에러
[root@test-b-srv nginx]# systemctl restart nginx.service
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
[root@test-b-srv nginx]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2023-06-26 11:03:29 KST; 8s ago
Process: 60128 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE)
Process: 60126 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 15642 (code=exited, status=0/SUCCESS)
Jun 26 11:03:29 test-b-srv systemd[1]: Starting The nginx HTTP and reverse proxy server...
Jun 26 11:03:29 test-b-srv nginx[60128]: nginx: [emerg] unknown directive "stream" in /etc/nginx/nginx.conf:16
Jun 26 11:03:29 test-b-srv nginx[60128]: nginx: configuration file /etc/nginx/nginx.conf test failed
Jun 26 11:03:29 test-b-srv systemd[1]: nginx.service: control process exited, code=exited status=1
Jun 26 11:03:29 test-b-srv systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
Jun 26 11:03:29 test-b-srv systemd[1]: Unit nginx.service entered failed state.
Jun 26 11:03:29 test-b-srv systemd[1]: nginx.service failed.
nginx: [emerg] unknown directive "stream" : stream을 찾을 수 없다고 나온다. 소스코드 컴파일로 설치하자