NGINX Unit API 제어

NGINX Unit은 JSON 기반의 구성 파일과 RESTful API를 활용하여 서버의 설정과 애플리케이션을 관리하는 시스템입니다. 이 문서에서는 NGINX Unit의 API를 사용하여 서버와 애플리케이션을 제어하는 방법을 소개합니다. NGINX Unit의 API는 네 가지 주요 옵션을 통해 접근할 수 있으며, 이를 통해 SSL/TLS 인증서 관리, 일반적인 설정, 애플리케이션 제어 및 상태 조회 등을 수행할 수 있습니다.

목차

1. NGINX Unit API 제어
2. OpenAPI specification
3. Quick start
 3-1. API 조작
 3-2. Examples

1. NGINX Unit API 제어

NGINX Unit은 JSON 기반으로 구성을 진행하게 되고 RESTful API를 통해 Unit에 요청을 보내 구성을 진행할 수 있습니다. NGINX Unit은 4가지 옵션으로 구성할 수 있습니다.

ObjectDescription
/certificatesSSL/TLS 인증서를 관리합니다.
/config일반 NGINX Unit을 구성하는데 사용됩니다.
/control애플리케이션을 컨트롤하는데 사용됩니다.
/statusNGINX Unit에 인스턴스 및 전체 측정 항목을 보여줍니다.

API는 설치 방법에 따라 유형과 주소가 달라지는 소켓을 통해 노출됩니다. 컴파일 시간 설정은 NGINX Unit 시작 시 재정의 될 수 있습니다. 보안을 위해 명시하지 않는 한 예제에서는 Unix 도메인 소켓을 사용합니다. 예제에서는 curl를 통해 요청을 보냅니다. URI 앞에 http://localhost가 붙습니다.(호스트 이름은 유닛 자체와 관련이 없음) 모든 HTTP 도구를 사용하여 구성할 수 있습니다. Visual Studio Code 사용자는 확장을 사용하여 Visual Studio Code 안에서 구성할 수 있습니다.

사용된 구성 파일이 없습니다.

NGINX Unit은 API를 통해 구성됩니다. 이는 의도적인 디자인 선택입니다. 다음과 같은 문제를 방지하기 위해 만들어졌습니다.

  • 감지되지 않은 구성 오류 : 구성 파일이 잘못된 상태로 저장될 수 있습니다. 잘못된 상태로 저장될 경우 NGINX Unit를 재시작 하거나 시작할 때까지 문제를 확인할 수 없을 것입니다. API를 통한 구성은 이를 방지하고 즉각으로 구성 변경 사항을 검증합니다.
  • 광범위, 제한적인 구성 파일 권한 : 구성 파일에 액세스할 수 없는 경우 불러올 수 없습니다. 파일 권한이 너무 광범위 할 경우 민감한 데이터가 유출될 수 있습니다. API를 통한 구성은 관리 가능한 단일 진입점이 있습니다.
  • 예측할 수 없는 동작 : 구성 파일 계층 구조에서 추적을 잃거나 무언가를 잘못 구성하기 쉽습니다. API를 통한 구성은 전체 구성이 단일해지고 체-계적이며 탐색가능한 엔티티가 됩니다.
단위 상태 복제

유닛은 완전한 동적이지만, 때로는 기존 구성을 복사하고 싶을 때도 있습니다.
단위 상태 디렉토리 상호 교환 가능 유닛 버전이 동일하게 유지되는 한 따라서 바로가기를 사용하여 단위 인스턴스를 복제할 수 있습니다. Docker Container에서도 작동합니다.

VM에서 참조 단위 인스턴스가 실행되는 상태가 어디에 저장되는지 확인해보세요.

$ unitd -h

      --state DIRECTORY    set state directory name
                           default: "/path/to/reference/unit/state"

시작 시 상태 위치가 재정의되지 않았는지 다시 확인하세요.

$ ps ax | grep unitd
      ...
      unit: main v1.33.0 [unitd --state /runtime/path/to/reference/unit/state ... ]

두 번째 컴퓨터에서 이 명령을 반복하세요. 대상 인스턴스가 상태를 저장하는 위치를 확인합니다.

두 단위 인스턴스를 모두 중지합니다.

# systemctl stop unit
  • 메모 : 중지 및 시작 명령은 다를 수 있습니다. 장치가 다음에서 설치된 경우 비공식 저장소 또는 다음에서 빌드 할 수 있습니다.

참조 상태 디렉터리를 대상 상태 디렉터리에 복사합니다. 임의의 수단으로; 하위 디렉터리와 숨겨진 파일을 포함해야 합니다. 마지막으로 두 단위 인스턴스를 모두 다시 시작합니다.

# systemctl restart unit

유닛 인스턴스를 수동으로 실행하는 경우, –state를 사용하여 상태 디렉터리를 설정을 시작할 수 있습니다.

다시 시작한 후, 대상 인스턴스가 구성을 선택합니다. 상태 디렉터리에 복사했습니다.

2. OpenAPI specification

좀 더 공식적인 접근 방식을 위해 장치의 제어 API에, 다운로드 OpenAPI specification 또는 Docker Container를 사용해 보세요. 이미지를 빌드 후 컨테이너를 실행합니다.

$ docker build --tag=unit-openapi -f unit-openapi.Dockerfile .

$ docker run -d -p 8765:8765 -p 8080:8080 unit-openapi

http://localhost:8765 를 브라우저에서 오픈합니다.

기존에 사용하던 NGINX Unit에 이미지를 사용하려면 해당 페이지에 인스턴스 제어 소켓(현재는 IP 소켓만 지원합니다.)의 주소와 포트를 입력합니다.

3. Quick start

예시를 위해 정적 파일을 보여줄 수 있도록 Unit을 구성합니다. (/www/data/index.html)

<!DOCTYPE html>
<html>
   <head>
      <title>Welcome to NGINX Unit!</title>
      <style>
         body {
         width: 35em;
         margin: 0 auto;
         font-family: Tahoma, Verdana, Arial, sans-serif;
         }
      </style>
   </head>
   <body>
      <h1>Welcome to NGINX Unit!</h1>
      <p>If you see this page, the NGINX Unit web server is successfully
         installed and working.  Further configuration is required.
      </p>
      <p>For online documentation and support, please refer to
         <a href="https://unit.nginx.org/">unit.nginx.org</a>.<br/>
      </p>
      <p><em>Thank you for using NGINX Unit.</em></p>
   </body>
</html>

NGINX Unit은 들어오는 요청을 파일을 제공하는 공유 작업으로 라우팅하는 포트를 통해 요청을 처리해야 합니다.

{
    "listeners": {
        "127.0.0.1:8080": {
            "pass": "routes"
        }
    },

    "routes": [
        {
            "action": {
                "share": "/www/data$uri"
            }
        }
    ]
}

장치를 구성하려면 NGINX Unit 제어 소켓을 통해 JSON을 /config 엔드포인트에 PUT Method로 요청합니다. curl에서 JSON 전체를 넣는 것은 번거로울 수 있습니다. snippet.json으로 저장하고 업로드할 수 있습니다..

$ curl -X PUT --data-binary @snippet.json --unix-socket  \
      /path/to/control.unit.sock http://localhost/config

      {
          "success": "Reconfiguration done."
      }

NGINX Unit이 정적 파일을 보여주는지 listener에 지정된 포트로 요청하여 확인합니다.

$ curl -i 127.0.0.1:8080

      HTTP/1.1 200 OK
      Content-Type: text/html
      Server: Unit/1.28.0

      <!DOCTYPE html>
      <html>
         <head>
            <title>Welcome to NGINX Unit!</title>
            ...

3-1. API 조작

Nginx Unit의 제어 API를 사용하려면, HTTP를 통해 제어 소켓에 쿼리를 보내야 합니다. API 요청의 URI 경로 세그먼트는 JSON 객체 멤버의 이름이나 JSON 배열 요소의 인덱스를 지정해야 합니다.

  • NGINX Unit을 수동으로 자주 구성하는 겨어우 다음과 같은 JSON 도구가 매우 유욯합니다.(jq, jo)

API는 다음과 같은 HTTP 메서드를 지원합니다.

MethodAction
GET요청 URL에서 현재 구성을 확인합니다. JSON으로 반환됩니다.
POST요청 URL에서 현재 구성을 업데이트합니다. JSON 값 기준으로 업데이트됩니다.
PUT요청 URI에 있는 엔터티를 대체합니다.
DELETE요청 URI에서 현재 구성을 삭제합니다.

구성 변경 전 NGINX Unit 전체 구성에서 발생하는 차이정을 확인 후 없다면 업데이트되지 않습니다.
NGINX Unit을 재구성 할 수 없습니다.

NGINX Unit은 가능한 자연스럽게 실제 재구성 단계를 수행합니다. 실행 중인 작업은 자연스럽게 만료되고, 연결은 적절히 종료되며, 프로세스는 원활하게 종료됩니다.

올바른 JSON을 제공하는 경우 다양한 URI를 사용하여 모든 유형의 업데이트를 수행할 수 있습니다.

$ curl -X PUT -d '{ "pass": "applications/blogs" }' --unix-socket \
       /path/to/control.unit.sock http://localhost/config/listeners/127.0.0.1:8300

$ curl -X PUT -d '"applications/blogs"' --unix-socket /path/to/control.unit.sock \
       http://localhost/config/listeners/127.0.0.1:8300/pass

첫 번째 명령은 8300에 대한 포트의 전체 리스너를 대체하며, 구성했을 수 있는 다른 옵션들을 모두 제거합니다. 반면, 두 번째 명령은 pass 값만 대체하고 다른 옵션은 그대로 유지합니다.

3-2. Examples


오타를 줄이고 작업 효율성을 높이기 위해, 명령어에 JSON 페이로드를 직접 삽입하는 대신, 구성 스니펫을 저장하여 검토 및 재사용하는 것이 좋습니다. 예를 들어, 애플리케이션 객체를 wiki.json으로 저장하세요.

{
    "type": "python",
    "module": "wsgi",
    "user": "www-wiki",
    "group": "www-wiki",
    "path": "/www/wiki/"
}

이를 사용하여 wiki-prod라는 애플리케이션을 설정합니다.

curl -X PUT --data-binary @wiki.json \
       --unix-socket /path/to/control.unit.sock http://localhost/config/applications/wiki-prod

동일한 앱의 배포 버전이 아닌 개발 버전을 설정하려면 이름만 변경하여 요청합니다.

curl -X PUT --data-binary @wiki.json \
       --unix-socket /path/to/control.unit.sock http://localhost/config/applications/wiki-dev

wiki-dev 앱을 다른 소스 코드 디렉터리로 전환합니다.

curl -X PUT -d '"/www/wiki-dev/"' \
       --unix-socket /path/to/control.unit.sock http://localhost/config/applications/wiki-dev/path

다음으로 프로덕션 앱의 프로세스 수를 늘립니다.

curl -X PUT -d '5' \
       --unix-socket /path/to/control.unit.sock http://localhost/config/applications/wiki-prod/processes

wiki-prod 앱 에서의 모든 호스트 IP에서 요청을 수락하려면 다음을 수행하세요.

curl -X PUT -d '{ "pass": "applications/wiki-prod" }' \
       --unix-socket /path/to/control.unit.sock 'http://localhost/config/listeners/*:8400'

wiki-dev 에 접속하기 위해 앱을 Listener에 연결합니다.

curl -X PUT -d '"applications/wiki-dev"' --unix-socket /path/to/control.unit.sock \
       'http://localhost/config/listeners/*:8400/pass'

앱의 개발 버전에 URI 기반 경로를 추가합니다.

$ cat << EOF > config.json

    [
        {
            "match": {
                "uri": "/dev/*"
            },

            "action": {
                "pass": "applications/wiki-dev"
            }
        }
    ]
EOF

$ curl -X PUT --data-binary @config.json --unix-socket \
       /path/to/control.unit.sock http://localhost/config/routes

$ curl -X PUT -d '"routes"' --unix-socket \
       /path/to/control.unit.sock 'http://localhost/config/listeners/*:8400/pass'

다음으로, wiki-dev 의 URI를 변경합니다.

curl -X PUT -d '"/development/*"' --unix-socket /path/to/control.unit.sock \
       http://localhost/config/routes/0/match/uri

prod 앱에 경로를 추가합니다. POST는 항상 끝에 추가됩니다.

curl -X POST -d '{"match": {"uri": "/production/*"}, \
       "action": {"pass": "applications/wiki-prod"}}'  \
       --unix-socket /path/to/control.unit.sock        \
       http://localhost/config/routes/

전체 구성을 얻기위해선 아래와 같은 URI로 요청을 해야합니다.

$ curl --unix-socket /path/to/control.unit.sock http://localhost/config/

    {
        "listeners": {
            "*:8400": {
                "pass": "routes"
            }
        },

        "applications": {
            "wiki-dev": {
                "type": "python",
                "module": "wsgi",
                "user": "www-wiki",
                "group": "www-wiki",
                "path": "/www/wiki-dev/"
            },

            "wiki-prod": {
                "type": "python",
                "processes": 5,
                "module": "wsgi",
                "user": "www-wiki",
                "group": "www-wiki",
                "path": "/www/wiki/"
            }
        },

        "routes": [
            {
                "match": {
                    "uri": "/development/*"
                },

                "action": {
                    "pass": "applications/wiki-dev"
                }
            },
            {
                "action": {
                    "pass": "applications/wiki-prod"
                }
            }
        ]
    }

wiki-dev 의 애플리케이션 객체를 얻으려면 다음와 같은 요청을 해야합니다.

$ curl --unix-socket /path/to/control.unit.sock \
       http://localhost/config/applications/wiki-dev

    {
        "type": "python",
        "module": "wsgi",
        "user": "www-wiki",
        "group": "www-wiki",
        "path": "/www/wiki-dev/"
    }

이러한 요청을 JSON으로 저장하여 사용할 수 있습니다.

curl --unix-socket /path/to/control.unit.sock \
       http://localhost/config/ > config.json

*:8400에서 리스널를 삭제하려면 다음과 같은 요청을 해야합니다.

curl -X DELETE --unix-socket /path/to/control.unit.sock \
       'http://localhost/config/listeners/*:8400'

다른 객체가 의존하는 객체는 삭제할 수 없다는 점을 유의해야합니다.
ex) 리스너가 다른 roiutes에 참조할 때 다음과 같은 응답을 받게 됩니다.

curl -X DELETE --unix-socket /path/to/control.unit.sock \
        http://localhost/config/routes

     {
         "error": "Invalid configuration.",
         "detail": "Request \"pass\" points to invalid location \"routes\"."
     }

NGINX Unit에 관련된 더 많은 정보를 알고싶으시다면 NGINXSTORE NGINX Unit 카테고리에서 확인할 수 있습니다.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required