"한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다."
백엔드 개발자라면 nginx를 알고 있을 것이다. nginx는 웹 어플리케이션을 만들 때, 리버스 프록시, 로드 밸런서, API Gateway 등의 역할로 제일 앞단에 사용된다. 나는 Kubernetes 에서 어플리케이션을 사용자에게 노출할 때, ingress라는 오브젝트를 사용했는데, 이를 구현할 때 nginx를 많이 사용했었다. 큰 설정 없이 사용했지만, nginx가 제공하는 기능을 알면 도움이 될 것 같아서 이 책을 골랐다.
NGINX의 다양한 기능을 소개한다. 대부분의 경우, 문제를 제시하고 해당 문제를 해결하기 위한 NGINX 설정 파일을 보여준다.
이 책은 번역서이지만 술술 읽히는 편이다. 그러나 몇몇 부분에서 잘못 설명된 부분이 있는 것 같다. 물론, 이는 제가 잘못 이해한 것일 수도 있습니다.
1) 12장에서는 고가용성을 다루며, Keepalived와 같은 도구를 사용하여 NGINX 서버의 가용성을 높이는 방법을 다룬다. 그러나 Keepalived가 백업 서버로 하트비트를 보낸다고 적혀 있는데 이게 아니라 NGINX 서버에 하트비트를 보내야 하지 않을까?
2) 15장에서는 성능 튜닝을 다루며, proxy_buffering 을 활성화하는 이유로 업스트림 서버의 응답을 메모리에 임시 파일에 기록되지 않도록 메모리에 버퍼링한다 라고 하는데 그러나 실제 레퍼런스에서는 임시 파일이 생성된다고 한다. 이 설명이 조금 다른 것 같다.
When buffering is enabled, nginx receives a response from the proxied server as soon as possible, saving it into the buffers set by the proxy_buffer_size and proxy_buffers directives. If the whole response does not fit into memory, a part of it can be saved to a temporary file on the disk. Writing to temporary files is controlled by the proxy_max_temp_file_size and proxy_temp_file_write_size directives.
아래는 책의 내용을 요약한 것인데 만약 관심 있는 내용이 있다면 책을 참고하시는 것도 좋을 것 같습니다.
NGINX 설치하는 방법과 주요 설정 파일과 디렉토리에 대해서 다룬다. (로그 디렉토리 위치, NGINX 기본 설정 파일 등)
이 외에도 기본 HTTP 설정 파일을 소개하고, 설정을 바꿨을 때 무중단으로 reload 하는 방법에 대해서 가르켜준다.
HTTP, TCP, UDP 부하 분산을 제공하는 방법.
상태 유지가 필요한 어플리케이션에서 부하분산을 제공할 때 사용자 경험을 해치지 않는 법
부하분산 대상이 되는 업스트림 어플리케이션의 상태를 모니터링 하는 방법
부하분산 제공
상태 유지가 필요한 어플리케이션에서 부하분산을 제공할 때 사용자 경험을 해치지 않는 법
부하분산 대상이 되는 업스트림 어플리케이션의 상태를 모니터링 하는 방법
트래픽 경로 설정과 제어 방법
사용자 요청을 특정 비율로 분기하거나, 사용자 위치 정보를 활용해서 흐름을 조절하고 요청 빈도, 연결수, 대역폭 등을 제한해서 트래픽을 제어하는 방법
NGINX 를 이용한 콘텐츠 캐싱 제공 (CDN 처럼)
캐시와 관련된 여러가지 기능을 소개한다.
프로그래머빌리티 (programmability) 란 프로그래밍을 통해서 상호작용하는 능력을 말한다.
여기서는 HTTP API 를 통해서 NGINX Plus (상용 버전. 오픈 소스 버전이 아님) 와 상호 작용하고 동적 제어 하는 방법을 다룬다. (업스트림 서버를 추가하거나 제거, 키 값 저장소를 통한 블랙리스트 추가 등)
NJS 모듈을 바탕으로 사용자 요청이나 응답 처리 시 엔진엑스에서 자바스크립트 실행하기
NGINX 레벨에서 인증을 해서 업스트림 서버에는 인증을 통과한 요청만 전달하도록 할 수 있다. 여기서는 NGINX 에서 제공하는 인증을 다룬다. NGINX 오픈 소스 버전에서는 HTTP 기본 인증과 하위 요청 인증이 있고, NGINX Plus 에서는 JWT 검증이 가능하다.
NGINX 하위 요청은 목적지 서버로 보내기 전에 내부 인증 서버로 보내서 요청을 처리하도록 하는 것이다.
추가로 NGINX Plus 에서는 OpenID 커넥트 SSO 를 통한 사용자 인증이 가능하다.
NGINX 를 이용해서 어플리케이션의 보안을 제어하는 방법에 대해서 다룬다.
보안 제어 방법
IP 주소 기반 접근 제어가 있다. 접근이 되는 whitelist 를 허용하는 방식.
CORS 접근 허용
클라이언트와 NGINX, NGINX 와 업스트림 서버의 통신에서 암호화 사용.
비밀값을 사용해서 리소스 접근 보호
어플리케이션에서 비밀값을 이용해 보안 링크 생성.
특정 클라이언트에서만 적용되는 기간을 가진 제한 링크를 통해서 리소스 접근 보호
사용 기간이 만료되면 파기되는 링크 생성하기
HTTP 요청을 HTTPS 로 리다이렉션
폐쇄형 웹사이트를 위해서 모든 보안 검증을 통과해야 요청이 전송되도록
DDOS (Distributed Denial of Service) 공격 완화하기
NGINX 에서 HTTP/2 를 이용하는 방법과 서버 푸쉬 방법 그리고 gRPC 를 이용하는 방법에 대해서 다룬다.
NGINX 를 이용해서 MP4 (MPEG-4), FLV (Flash video) 파일을 스트리밍하는 방법에 대해서 다룬다.
NGINX Plus 는 HTTP 라이브 스트리밍 (HLS) 모듈을 이용해서 콘텐츠를 실시간으로 작게 나눠서 전송하는 방법, 이미 작게 쪼개진 미디어 파일을 전송하는 HTTP 동적 스트리밍 (HTTP Dynamic Streaming) 형식도 제공한다.
추가로 시청 경험을 해치지 않는 선에서 사용자가 미디어 콘텐츠를 내려받는 네트워크 대역폭을 제한할 수 있다.
NGINX 를 컨테이너 식으로 배포하는 방법과 이를 쿠버네티스와 openshift 에서 사용하는 방법
NGINX 를 API Gateway 로 사용해서 보안, 검증, 인증을 수행하고 요청을 적절한 서비스로 라우팅 하는 기능
이미 구성된 DNS 의 SRV 레코드를 활용해서 엔진엑스 플러스의 업스트림 서버를 설정하기
도커 허브에 등록된 공식 NGINX 이미지를 사용하기
여러 환경에서 동일한 컨테이너 이미지를 사용하도록 엔진엑스 설정에서 환경 변수를 사용하는 법
어플리케이션을 쿠버네티스 환경으로 배포하면서 인그레스 컨트롤러를 사용하는 법
프로메테우스로 모니터링 되는 환경에 NGINX 를 배포하고 통계를 확인하는 법
NGINX 에서 고가용성을 보장하는 방법
nginx-ha-keepalived 패키지를 이용해서 fail over 를 제공해서 고가용성을 보장하는 방법
DNS 서버에 NGINX IP 주소를 여러개 등록해서 부하를 분산하는 방법
NGINX Plus 설정 동기화하기
NGINX Plus 에서 고가용성 서버 간에 공유 메모리 영역 동기화하기
NGINX 를 사용하는 경우에 제공하는 모니터링 지표들에 대해서 알아보는 것. (사용자 요청, 업스트림 서버 풀, 캐시, 서버 상태 등)
NGINX 의 기본 모니터링 활성화하기
NGINX Plus 에서 상세 지표 수집하기
NGINX Plux 에서 API 로 지표 수집하기
유의미한 로그를 남기는 방법 (access.log 과 error.log)
중앙화된 로그 수집 시스템으로 로그를 넘기는 방법
접근 로그 남기기
오류 로그 남기기
로그를 시스로그로 전달하기
NGINX 로그와 어플리케이션 로그를 연관짓는법
NGINX 오픈 트레이싱 셋업
클라이언트와의 연결을 유지해서 성능을 높이는 법 (keepalive 이용)
업스트림 서버와의 연결을 계속해서 유지해서 성능을 높이는 법 (keepalive 이용)
업스트림 서버의 응답이 메모리에 버퍼링 되도록 하기
접근 로그를 버퍼링해서 시스템 부하가 높을 때 워커 프로세스의 작업이 지연되거나 차단당하지 않도록 하기
스파이크성 부하가 예상되거나 대량의 트래픽이 발생할 수 있는 경우에 운영체제가 더 많은 연결을 맺도록 튜닝해놓기.
커널 옵션 중 net.core.somaxconn 이 있다. 커널이 연결을 큐잉할 수 있는 최대 값임. 512 보다 더 큰 값을 설정하고 nginx 의 listen 지시자의 backlog 매개변수에도 같은 값을 설정해야한다. 주로 튜닝 시점은 커널 로그에 명시적으로 값을 설정하라고 남겨질 때 하면 된다. nginx 자체가 워낙 연결 처리가 빨라서.
시스템 성능 시 파일 디스크립터 (file descriptor) 설정을 늘려놓는 경우가 더 유용하다. 시스템 환경에서 연결이 맺어지면 이게 하나씩 생긴다. nginx 는 클라이언트와 업스트림 서버 둘을 연결하므로 두 개씩 생긴다. 대량의 연결을 처리하기 위해서 sys.fs.file.max 를 통해서 파일 디스크립터 개수를 늘려놓을 수 있다. 아니면 NGINX 가 시스템 사용자를 통해서 실행되는 경우에는 /etc/security/limits.conf 를 통해서 조정할 수 있다.
마지막으로 더 많은 연결을 처리할 수 있도록 임시 포트를 활성화해야한다. 이 최대 개수는 net.ipv4.ip_local_port_range 값을 통해서 확인할 수 있다. 최솟값이 1024 이고 최대값이 65335 이면 문제 없다. 1024 가 TCP 포트 번호가 끝나는 지점, 65535 가 임시 포트가 끝나는 지점이다.
부피가 큰 설정 파일을 모듈화해서 관리하고, 설정 파일을 모울 땐 include 를 이용하기
NGINX 가 예상치 못하게 죽었거나 동작할 때 디버깅하는 방법