DevOps/NGINX

NGINX MSA 디지털 트레이닝 - 7강 : NGINX Kick Starter

갈색왜성 2022. 5. 6. 01:17
반응형

강의 동영상 : https://www.youtube.com/watch?v=sAXVraylurw
원본 동영상 : https://www.nginx.com/c/nginx-kick-start/, https://www.youtube.com/watch?v=rKXYxOVm0YE

Kick Starter 강의는 이전 1~6강 강의와 중복되는 내용이 많아서 해당 부분은 Link로 대체하고 나머지 부분만 정의했다.

1. 주요 특징 및 Context Logic

참조 : NGINX MSA 디지털 트레이닝 - 1강 : Context Logic

추가 내용 - No Downtime

  1. Master Process와 Configuration을 읽고 Worker들을 Update하는 역할을 하며 Worker Process들은 들어오는 Request를 처리한다.
  2. Configuration이 변경되고 Master Process는 이 변경된 Configuration을 다시 Reload한다.
  3. Master Process는 이미 들어온 Request들을 처리하는 Worker Process 들이 요청이 정상적으로 처리될 수 있도록 한다.
  4. 새로운 Request들을 받았을 때 Master Process는 새로운 Configuration에 맞게 Worker Process들을 구성한다.

2. Web Server 설정

1. 기본 설정

server {
        listen 0.0.0.0:80;
        server_name "";
        root  /usr/share/nginx/html;
        index  index.html;
}
  • root : Incoming request에 대해 대응되는 Contents를 제공하는 Folder 위치.
  • index : Incoming request 중 root에 대응되는 기본 index file을 정의하는 지시문.

2. Server Selection

  • 다음과 같이 두 개 이상의 server directive가 정의되어 있을 때 아래의 순서에 의해 하나의 server 를 선택
    1. server 설정에서 listen directive로 정의된 address가 더 정확하게 mapping 되는 server group 하나를 선택
    2. 한 group에는 ip만 정의되어 있고, 다른 한 group에는 port만 정의되어 있을 경우에 두 조건을 다 만족하는 incoming request에 대해서는 ip address가 mapping되는 서버가 더 높은 priority를 가짐.
    3. 같은 값을 가진 listen directive 가 두 개 이상 다른 Server 그룹에서 정의되어 있다면, incoming request의 'Host' 값과 server_name 값이 일치하는 server가 더 높은 priority를 가짐. server_name으로 하나의 Server를 선택할 때는 다음의 순서에 따라 결정됨.
      1. exact string match : 정확히 Matching 되는 server_name이 있을 경우
      2. matches with leading wild card : server_name이 '*'로 시작되고, 그 외 부분이 Matching되는 server_name이 있을 경우
      3. matches with a trailing wild card : server_name이 '*'로 마무리되고, 그 외 부분이 Matching되는 server_name이 있을 경우
      4. the first regex match : 제일 처음 Regualr Expression으로 Matching 되는 server_name 인 경우
    4. Matching 되는 server가 없을 경우 default_server directive를 통해 선언된 Server를 Default Server로 선택한다. (아래 참조)
       server {
            listen  192.168.1.1;
            server_name  www.example.*;
       }
       server {
            listen 192.168.1.1;
            server_name  *.example.net;
       }
       server {
            listen 192.168.1.1;
            server_name  ~^(host1|host2).*\.example\.com$;
       }
       server {
            listen 192.168.1.1  default_server;
            error_page  404  /40x.html;
       }

3. Location Block Types

  • 위의 규칙에 맞춰 server를 선택한 후에는, incoming request의 URI에 따라 서버에 있는 특정 Path를 선택함. 이 때 'location' directive를 사용해서 Request URI와 서버내 실제 Path를 Mapping 해주며, Prefix와 Regex의 방법이 있다.

  • Prefix Location ; Incoming Request의 URI중 시작 부분이 맞는 경우를 정의하며, 여러 Location Block에서 정의된 URI 값과, 실제 Request URI Path가 만족하는 경우 가장 긴 URI 값이 Matching되는 Location Block을 선택한다.

    server {
          listen  192.168.1.1;
          location  /app1 {...}
          location  /parts {...}
          location  /shop {...}
    }

  • Regex Location : Incoming Request의 URI가 Regular Expression(Pearl Regular Expression과 호환되는 규칙으로 작성)에 만족하는 지 확인. '~'으로 시작해서 regex location임을 알린다. 실제 Request URI Path가 여러 Regular Expression 규칙을 만족하는 경우에는 제일 먼저 규직을 만족한 Location Block을 선택한다. 규칙을 만족시키는 지 확인할 떄에는 아래 옵션에 따라 확인한다.

  • Note : Prefix Location Block과 Regex Location Block을 같이 사용하는 경우 Prefix Location을 다 정의한 후에 Regex Location을 정의하는 것을 권장하고 있다.

  • Example

    • Incoming Request : http://www.example.com/app1/index.php

    • Case 1 : 아래와 같이 설정된 상태에서 위와 같은 Request가 들어왔을 경우, 3개의 location block은 모두 만족하고, 1번째 보다는 3번째 location block이 더 긴 길이를 가지는 Prefix이기 때문에 3번째가 일단 선택되고, 그 후에 Regex Location block을 검사하려 하지만 3번째 location block에서 "^~"가 붙어 있기 때문에 더 이상 Regex Location block은 확인하지 않고 바로 3번째 location block 이 선택되게 된다.

      server {
              listen 80  default_server;
              root  /home/ubuntu/web_server_test;
      ...
              location / {
                      # the 1st location block
              }
              location ~* \.(php|html)$ {
                      # the 2nd location block
              }
              location ^~ /app1 {
                      # the 3rd location block
              } 
      }

    • Case 2 : 아래와 같이 설정된 상태에서 위와 같은 Request가 들어왔을 경우, 3개의 location block은 모두 만족하고, 1번째 보다는 3번째 location block이 더 긴 길이를 가지는 Prefix이기 때문에 3번째가 일단 선택된 후에 Regex Location block으로 정의된 두번째 Block을 검사하게 되는데, 2번째 Location Block에서 정의한 Regular Expression이 Request URL을 만족시키기 때문에 아래에서는 2번째 Location block이 선택되게 된다.

      server {
              listen 80  default_server;
              root  /home/ubuntu/web_server_test;
      ...
              location / {
                       # the 1st location block
              }
              location ~* \.(php|html)$ {
                      # the 2nd location block
              }
              location /app1 {
                      # the 3rd location block
              } 
      }

3. Reverse Proxy

참조 : NGINX MSA 디지털 트레이닝 - 2강 : Reverse Proxy

4. Load Balancer

참조 : NGINX MSA 디지털 트레이닝 - 3강 : Load Balancing

5. Caching

  • 기본 Process Flow

    1. Client Request
    2. MD5 Hash값을 생성해서 해당하는 값과 Mapping되는 Cache 값을 확인
    3. Cache 값이 없으면 Backend로 Proxy 해서 Request에 해당하는 값을 가져옴.
    4. 응답을 받은 후 Hash 값은 Memory에 저장하고, 응답을 File System에 저장
    5. 또 다시 같은 Request를 받았을 때 NGINX는 Memory에 있는 Cache에 같은 값이 있는 지 확인한후, 같은 값이 있을 경우 File System에 응답이 Caching되어 있다는 것으로 간주해서 File에서 값을 가져와 전달한다.
  • 주요 Directives

    • proxy_cache_path : cache 위치, directory level, cache 정보의 생명 기간, Memory zone의 정의와 크기, 파일 사용량 정의

          proxy_cahce_path [levels=levels] 
                           key_zone=name:size 
                           [inactive=time] 
                           [maxsize=size] 
                           [loader_files=number] 
                           [loader_sleep=time] 
                           [loader_threshold=time]
      • levels : File 저장 공간이 분산되게 하기 위해 Directory Depth를 정의하고 사용하는 글자수를 정의.
      • key_zone : cache identification and size
      • inactive : cache에서 삭제되기 위한 비활성화 기간 한도.
      • max_size : cache manager에 의해 관리되는 최대 cache size
      • Ex) proxy_cache_path /data/nginx/cache levels=1:2 key_zone=images:20m;
        • Cache File Name : /data/nginx/cache/c/29/b7f54b2df7773722d382f4809d60529**c**
    • proxy_cache : 사용할 cache를 지명.

      proxy_cache zonename | off;
      • Ex) proxy_cache mycache;
    • proxy_cache_key : Hash 값을 만들 때 사용하는 값.

      proxy_cache_key string;
      • Ex) proxy_cache_key $schema$host$request_uri
        • Client Request에서 사용된 schema, host name, request uri 값을 사용해 MD5 Hash 값을 만들고 Cache Key 로 사용.
    • proxy_cache_valid : Backend로부터의 응답에 따른 Cache 값이 valid한 기간 명시

      proxy_cache_valid   HTTP_STATUS_CODE   time;
      • Ex) proxy_cache_valid 200 5m
        • 응답 코드 200에 대해서 5분동안 캐싱한 값이 유효하며, 5분이 넘어가면 Backend로부터 새롭게 값을 가져온다.
    • Example

      proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=upstream_cache:20m inactive=5m max_size=2G;
      server {
          ...
          proxy_cache_key $scheme$host$request_uri;
          proxy_cache upstream_cache;
          proxy_cache_valid 5m;
          location / {
              proxy_pass [http://](http://localhost:8000)upstream-server.com;
          }
      }
  • Tip

    • Header를 통해 Cache를 사용하는 지 여부 확인하는 방법
    • Step 1 : NGINX 설정 파일에서 Cache 사용 여부에 대한 Response Header 추가
      # nginx.conf 파일 중 cache 사용 block에 추가
      ...
      add_header X-Proxy-Cache $upstream_cache_status;  # upstream_cache_status는 cache를 사용하는 지 여부를 가지는 변수

    • Step 2 : 실제 Response Header에 대한 Response 분석
      # Cache를 사용하지 않을 때의 응답 Header
      X-Proxy-Cache : MISS
      ...
      # Cache를 사용할 때의 응답 Header
      X-Proxy-Cache : HIT

6. NGINX Plus API and Dashboard

  • NGINX Plus에서는 설정을 통해 상태 확인용 API를 제공

    • Demo용 Swagger Document : [Link]
  • Swagger Document에 명시된 API를 지원하기 위한 설정

    • api Directive

      • 특정 location애 대해 api directive를 정의해야함.
      • Read/Write 를 모두 지원하려면 'write=on' directive를 추가해야함.
      • 기본적으로 외부에서의 Request는 모두 Deny 되기 때문에 allow directive를 이용해 ACL을 관리해야함
      • Example
        server {
            listen 8080;
            location /api {
                    api  write=on
                    allow  192.168.0.0/16
                    deny all;
            }
        }
    • zone Directive

      • nginx의 Worker Process들이 실시간 상태정보를 공유할 Shared Memory를 정의
      • Upstream Block 내에서 zone을 설정하면 해당 Block에 포함된 Server들의 정보들이 공유됨.
      • Example
        upstream myServers {
            zone backend  64k;
            server backend1 weight=1;
            server backend2 weight=3;
        }
    • Dashboard 설정

      • Dashboard.html path를 설정하면 Dashboard UI를 확인할 수 있음.
      • Example
        server {
            listen 8080;
            location /api {
                    api;
             }
            location /dashboard.html {
                    root  /usr/share/nginx/html;
            }
        }