DevOps/NGINX

NGINX MSA 디지털 트레이닝 - 8강 : Basics and Best Practices

갈색왜성 2022. 5. 22. 01:26
반응형

강의 동영상 : https://www.youtube.com/watch?v=rQa2HrXXTJA
원본 동영상 : https://www.youtube.com/watch?v=pkHQCPXaimU

8강은 7강과 거의 동일한 내용을 설명하고 있다. 대부분의 내용이 7강 : NGINX Kick Starter 과 중복되어 있지만, 예시 위주로 다시한 번 정리했다.


Simple Virtual Server

server {
        listen    80 default_server;
        server_name  [www.example.com](http://www.example.com);

        return    200;
}

  • server : virtual server context를 정의하는 Block
  • listen : 수신할 IP, Port Number를 정의. IP을 명시하지 않을 경우는 System이 가진 모든 IP에 Binding한다.
  • server_name : Virtual Server가 수신하는 hostname
  • return : request에 대한 response 정의

Basic Web Server Configuration

server {
        listen    80 default_server;
        server_name [www.example.com](http://www.example.com);

        location  /i/  {
                root    /usr/share/nginx/html;
                # alias /usr/share/nginx/html;
                index    index.html index.htm;
        }
}

  • root : NGINX가 설치된 서버의 파일시스템에서 파일이 저장된 위치를 지정.
  • alias : root directive와 비슷하지만 location에 정의된 URL을 사용하지 않고 alias로 지정된 그 Path만을 사용.
  • index : 기본적으로 사용할 index file을 지정
  • 실제 사용할 때의 예.

Basic Load Balancing Configuration

upstream my_upstream {
        server    server1.example.com;
        server    server2.example.com;
        least_time;
}
server {
        location / {
                proxy_set_header    Host    $host;
                proxy_pass    [http://my\_upstream](http://my_upstream);
        }
}

  • upstream : Load Balancer에 포함될 모든 Backend Pool을 정의하는 Directive.
  • Load Balancing Algorithm
    • default. : 별다른 설정이 없을 경우에는 Round Robin 방식으로 사용
    • least_conn : Active Connection이 적은 서버로 Request가 전달됨
    • least_time : NGINX Plus에서만 가능하며, least_conn + 응답 속도를 기준으로 Request가 전달됨
  • proxy_pass : 들어오는 Request를 다른 곳으로 전달. 위에서는 Load Balancing을 위해 정의한 Backend Pool로 이동.
  • Remark
    • NGINX는 기본적으로 Host 값을 proxy server의 값으로 치환하기 떄문에, proxy_set_header directive를 통해 원래의 Client Host Header로 변경해야 한다.
    • $host ; NGINX 가 수신한 Client Host 값을 가진 변수이다.

Basic Reverse Proxy Configuration

server {
        location ~ ^(.+\.php)(.*)$ {
                fastcgi_split_path_info ^(.+\.php)(.*)$;

                # fastcgi_pass 127.0.0.1:9000;
                fastcgi_pass    unix:/var/run/php7.0-fpm.sock;

                fastcgi_index    index.php
                include    fastcgi_params;
        }
}

  • Remark : Apache HTTPD의 경우 static content와 하나의 Dynamic Content를 직접 제공하는데 비해, NGINX는 Dynamic Contents는 Application Server를 통해 제공
  • fastcgi_pass : proxy_pass와 유사. IP+Port로 Network Layer에서 Routing 하거나 Unix Socket을 사용하는 방식으로 Routing 할 수 있다.

Caching Configuration

proxy_cache_path /path/to/cache. levels=1:2 
                                keys_zone=my_cache:10m max_size=10g
                                inactive=60m use_temp_path=off;

server {
       location / {
               proxy_cache my_cache;
               proxy_set_header Host $host;
               proxy_pass http://my_upstream;
       }
}

  • proxy_cache_path : cache를 위한 모든 parameter를 설정. 제일 먼저 Cache Data가 저장할 Path를 지정
    • levels : file path의 depth를 몇 단계로 할지와 cache key를 몇 글자 사용할 지를 지정
    • key_zone : cache key를 저장할 Memory Size. 1MB인 경우 약 8000개의 Cache Key 저장
    • max_size : 최대 Cache 크기
    • inactive : Cache내 저장된 객체가 Access되지 않은 채로 최대한 머무를 수 있는 시간.
    • use_temp_path : Caching시 임시 파일을 저장할 공간 사용여부. 사용할 경우 저장할 Path를 지정해야 한다.
  • proxy_cache : 여러개의 cache context중 하나를 지정

Basic SSL Configuration

server {
        listen       80 default_server;
        server_name  [www.example.com](http://www.example.com);
        return 301 [https://$server\_name$request\_uri](https://$server_name$request_uri);
}
server {
        listen  443 ssl default_server;
        server_name    [www.example.com](http://www.example.com);
        ssl_certificate        cert,crt;
        ssl_certificate_key    cert.key;

        location / {
                root     /usr/share/nginx/html;
                index    index.html  index.htm;
        }
}


Basic HTTP/2 Configuration

server {
        listen 443 ssl http2 default_server;
        server_name   [www.example.com](http://www.example.com);

        ssl_certificate          cert.crt;
        ssl_certificate_key      cert.key;
}

  • HTTP/2 지원을 위해서 listen directive에 http2 directive만 추가하면 가능
    • HTTP/2는 SSL 위에서만 동작하기 때문에 ssl directive도 명시해야함
  • HTTP/2는 Client Side에만 적용, Server Side는 HTTP 1이나 1.1이다.
  • Remark : HTTP/2는 OpenSSL 1.0.2 이상에서 동작. 즉 Ubntu 16.04 나 RedHat 7.4 이후 버젼에서 적용 가능

Multiplexing Multiple Sites on One IP

server {
        listen 80 default_server; 
        server_name www.example.com; 
        # ... 
}
server {
        listen 80; 
        server_name www.example2.com; 
        # ... 
}
server {
        listen 80; 
        server_name www.example3.com; 
        # ... 
}


Layer 7 Request Routing

server {
        # ...
        location /service1 {
                proxy_pass    [http://upstream1](http://upstream1);
        }
        location /service2 {
                proxy_pass    [http://upstream2](http://upstream2);
        }
        location /service3 {
                proxy_pass    [http://upstream3](http://upstream3);
        }
}

  • location 하나의 가상 서버가 URL에 따라 다르게 Routing 될 수 있게 설정
  • 위의 예에서는 upstream1~3의 3개의 서비스가 있고, /service1, /service2, /service/3 이라는 URL에 따라 각각 다른 서비스로 연결된다.

Advanced - nginx.conf 수정

user  nginx;
wrok_processes auto;
...
http {
        ...
        keepalive_timeout   300s;
        keepalive_requests  100000;
}

  • work_process
    • auto ; 시스템의 코어당 하나 이상의 프로세스를 생성(대부분의 경우에 권장되는 사항)
  • keepalive
    • keepalive_timeout : idle 상태의 connection을 얼마나 유지하느냐를 설정. 기본값은 75초
    • keepalive_requests : 단일 Connection에서 처리할 수 있는 최대 request양. 설정값 이상의 request를 받았을 때 Connection을 끊는다.
    • keepalive_*로 시작하는 설정값은 가상서버에서 따로 재정의 할 수 있다.

HTTP/1.1 Keepalive to upstreams

upstream my_upstream {
        server server1.example.com;
        keepalive 32;
}
server {
         location /service1 {
                proxy_set_header    Host    $host;
                proxy_http_version  1.1;
                proxy_set_header    Connection "";

                proxy_pass    http://my_upstream;
        }
}

  • keepalive : TCP connection cache를 활성화함
    • 기본적으로 NGINX는 HTTP/1.0을 사용 (Connection: Close)
  • proxy_http_version : 사용하려는 HTTP Version을 설정
  • proxy_set_header : 기본값으로 Connection: Close를 사용하기 떄문에 HTTP Header의 Connection 값을 ""으로 재설정

SSL Session Caching

server {
        listen  443    ssl default_server;
        server_name    www.example.com;

        ssl_certificate    cert.crt;
        ssl_certificate_key    cert.key;

        ssl_session_cache       shared:SSL:10m;
        ssl_session_timeout     10m;
}

  • SSL Session Cache를 사용하면 SSL/TLS 성능이 향상. Idle 상태에 있던 Client가 재접속할 때 계산비용이 많이 드는데 이런 문제를 방지할 수 있다.
  • 1MB의 Cache는 약 4,000개의 Session을 저장
  • Cache는 모든 worker들이 공유.

Advanced Caching Configuration

proxy_cache_path /path/to/cache  levels=1:2
                keys_zone=my_cache:10m max_size=10g
                inactive=60m  use_temp_path=off;

server {
        location / {
                proxy_cache    my_cache;
                proxy_cache_lock    on;
                proxy_cache_revalidate    on;
                proxy_cache_use_stale    error
                             timeout  updating 
                             http_500
                             http_502
                             http_503 
                             http_504;
                proxy_cache_background_update    on;

                proxy_set_header    Host    $host;
                proxy_pass    http://my_upstream;
        }
}

  • proxy_cache_use_steal ; Error 대신 오래된 contents를 제공
  • proxy_cache_background_update : NGINX의 cache가 background에서 update 할수 있게 설정. proxy_cache_use_steal과 함께 사용.
  • proxy_cache_lock : 한 번에 단 하나의 요청만 upstream server로 전달하게 함
  • proxy_cache_revalidate : "If-Modified-Since" 또는 If-None-Match"헤더 필드와 함께 만료 된 캐시 항목의 유효성을 다시 검사

gRPC Proxing

server {
        listen 443 ssl http2;
        ssl_certificate           server.crt;
        ssl_certificate_key       server.key;
        location / {
                grpc_pass    grpc://localhost:50051;
        }

  • gRPC를 위해서는 HTTP/2가 설정되야함. (SSL 설정은 Optional)
  • grpc_pass : grpc routing을 위해 사용하는 directive

Active Health Checks

upstrem. my_upstream {
        zone  my_upstresm 64k;
        server  server1.example.com  slow_start=30s;
}
server {
        #...
        location /health {
                internal;
                health_check   interval=5s uri=/test.php match=statusok;
                proxy_set_header    HOST  www.example.com;
                proxy_pass    http://my_upstream;
        }
match statusok {
        # used for /test.php healh check
        status 200;
        header Content-Type = text/html;
        body ~ "Server[0-9]+ is alive";
}

  • NGINX 는 기본적으로 passive health check 만 지원. Active Health check는 NGINX Plus에서만 지원
  • health_check : 백엔드 서버의 healch check를 위한 directive
    • interval : probe packet 전송 간격
    • uri : health check를 위한 target uri
    • match : health check 응답 결과 Check를 위한 match block 지정
  • match block : health check 결과 검증
    • 예에서는 status code, response header, response body를 지정하고 있으며 이 조건을 만족하지 못하는 경우 실패 처리.

Sticky Cookie Session Persistence

upstrem  my_upstream { 
        server    server1.example.com'
        server    server2.example.com;

        sticky  cookie  name expires=1h domain=.example.com  path=/;
}

  • NGINX Plus 에서만 제공
  • Client가 특정 서버와 응답을 지속할 수 있게 기능 지원. Client가 쿠키값을 사용하게 하며, 해당 쿠키값을 이용해 최초 연결된 서버로 Routing 하는 방법으로 기능 제공
  • sticky cookie : sticky cookie 기능 Enable
    • expires : cookie 유효 시간
    • domain : cookie 값이 유효한 domain 명시. 없을 경우 cookie 값에서 domain filed가 공백으로 남게됨.
    • path : cookie 값이 설정된 path. 없을 경우 cookie 에서 path field가 공백으로 남게됨.

Logging and Monitoring

NGINX Stub Status Module

server {
        location /basic_status {
                stub_status;
        }
}
$ curl  http://www.example.com/basic_status
Active connections: 1
server accepts handled requests
 7 7 7
 Reading:0 Writing:1 Waiting: 0

  • NGINX에 기본으로 내장된 기능으로 NGINX 상태 정보를 확인할 수 있다.
  • stub_status : location block으로 활성화 시키면 해당 URL로 접근시 7개의 상태정보를 확인할 수 있다.

NGINX Plus Extended Status

server {
        listen 8080;
        location /api {
                api write=on;
                ...
                # Limit access to the API
                allow 10.0.0.0/8;
                deny all;
        }
        location = /dashboard.html {
            root  /usr/share/nginx/html;
        }

  • NGINX plus에서는 약 40개 이상의 상태 정보를 제공할 수 있음
  • NGINX에서 제공하는 통계 정보를 사용하기 위해 /api location 블록을 지정하고, 'api write=on' directive를 사용해야함.
  • 통계정보는 /usr/share/nginx/html/dashboard.html로 제공됨.
  • Example : demo.nginx.com

NGINX Access Logs

  • NGINX 는 기본적으로 Logging 기능이 켜져 있음
    • 사용하지 않을 경우 "access_log off" directive를 사용하면 됨.
    • 기본적으로는 client IP, date, request, referrer, user agenct 정보가 포함됨
    • log_format : Log 형식을 지정하는 directive
    • Remark : Logging 작업은 성능 저하를 가져올 수 있기 때문에, 실제 서비스에서는 비활성화 시킬 수도 있음.