Kestrel 웹 서버를 NGINX 및 NGINX Plus로 구현
Microsoft 웹 사이트와 GitHub 저장소에서 Kestrel 에 대한 문서에 설명된대로, 일반적으로 Kestrel을 IIS나 NGINX와 같은 프로덕션 웹 서버 뒤에서 실행합니다. 이 자습서에서는 Kestrel을 NGINX와 NGINX Plus 뒤에 구현하는 방법에 대해 설명하겠습니다.
해당 포스트에서는 다음과 같은 방법을 배웁니다.
- .NET Core, NGINX 및 NGINX Plus 설치
- 매우 간단한 웹 애플리케이션 Build
- 웹 서버로 Kestrel 시작
- NGINX를 Frontend로 설치 및 구성
- 고급 NGINX Plus 기능 활성화
설치 및 구성이 완료되면,
- .NET Core 및 Kestrel
- 동적 애플리케이션 코드 실행
- Local IP 주소에서 HTTP 요청 수신 및 응답
- Reverse Proxy로 작동하는 NGINX 또는 NGINX Plus
- IPv6 및 IPv4를 통한 HTTP/2 트래픽 허용
- .NET 애플리케이션을 위한 SSL 오프로드 제공
- 정적 파일 서비스 제공
- Access log 제공
- Caching 추가
- NGINX Plus
- Live Acitivity Monitoring (실시간 활동 모니터링) 및 Metrics 제공
- Active Health Checks를 통해 애플리케이션 작동 상태 확인
.NET Core 애플리케이션의 배포 아키텍처는 Node.js나 Go 애플리케이션의 배포 아키텍처와 유사합니다.
NGINX는 .NET 애플리케이션에 대해 트래픽 관리 기능을 제공하여 애플리케이션의 생산 배포와 확장성을 간소화 합니다.
동일한, 또는 다른 기기에서 여러 .NET 애플리케이션을 실행할 수 있으며, NGINX 또는 NGINX Plus는 이들 사이에서 로드 밸런싱과 지능적 트래픽 라우팅을 수행합니다.
목차
1. .NET Core, NGINX 및 NGINX Plus 설치
2. “Hello World” 앱 실행
3. Kestrel HTTP 서버 실행
3-1. Kestrel 종속성 추가
3-2. 코드 작성
3-3. .NET Core 서버 실행
3-4. HTTP 연결 테스트
4. .NET 애플리케이션을 NGINX 또는 NGINX Plus를 사용하여 Reverse Proxy 구성
4-1. SSL 인증서 설치
4-2. Reverse Proxy 구성
4-3. .NET Core 앱에 대한 연결 테스트
5. NGINX Plus Live Activity Monitoring 및 Active Health Checks 구성
5-1. Live Activity Monitoring
5-2. Active Health Checks
6. 결론
1. .NET Core, NGINX 및 NGINX Plus 설치
Microsoft 웹 사이트의 지침에 따라 .NET Core를 설치합니다. 이 예에서는 Ubuntu 16.04를 사용하고 있습니다.
$ sudo apt-get install apt-transport-https
$ sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
$ sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
$ sudo apt-get update
$ sudo apt-get install dotnet-dev-1.0.0-preview2-003131
그 다음 NGINX를 설치합니다.
$ sudo apt-get install nginx
Live Activity Monitoring, Active Health Checks 또는 둘 다를 원하는 경우 NGINX Plus를 설치할 수 있습니다.
자세한건 NGINX Plus Documentation을 참조하십시오.
2. “Hello World” 앱 실행
선택한 상위 디렉토리에 “Hello World” 앱을 설치하고 초기화합니다.
$ cd parent-dir-for-apps
$ mkdir app
$ cd app
$ dotnet restore
앱이 작동하는지 확인하려면 dotnetrun
명령을 실행합니다.
3. Kestrel HTTP 서버 실행
3-1. Kestrel 종속성 추가
./project.json 파일을 편집하여 Kestrel을 프로젝트에 대한 종속성으로 추가합니다.
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
},
"imports": "dnxcore50"
}
}
}
3-2. 코드 작성
간단한 앱의 대한 이 코드를 Program.cs 라는 새 파일에 복사합니다. localhost의 5000 포트에서 Kestrel을 실행하여 현재의 날짜와 시간을 반환합니다.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.Configure(app =>
{
app.Run(async (context) => await context.Response.WriteAsync("Current date: " + DateTime.Now + "n"));
})
.Build();
host.Run();
}
}
}
3-3. .NET Core 서버 실행
dotnet run
명령어를 실행하여 .NET Core 서버를 실행합니다.
$ dotnet run
Project app (.NETCoreApp,Version=v1.0) will be compiled because inputs were modified
Compiling app for .NETCoreApp,Version=v1.0
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:01.9047678
Hello World!
Hosting environment: Production
Content root path: /app/bin/Debug/netcoreapp1.0
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
3-4. HTTP 연결 테스트
curl 명령어를 실행하여 HTTP 연결을 테스트합니다.
$ curl -v localhost:5000
* Rebuilt URL to: localhost:5000/
* Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 14 Feb 2017 19:50:59 GMT
< Transfer-Encoding: chunked
< Server: Kestrel
<
Current date: 02/14/17 12:50:59 PM
* Connection #0 to host localhost left intact
현재 .NET Core는 Linux에서 실행되고, HTTP 서버로 Kestrel을 사용하여 동적 데이터를 제공하고 있습니다.
4. .NET 애플리케이션을 NGINX 또는 NGINX Plus를 사용하여 Reverse Proxy 구성
.NET 애플리케이션의 Reverse Proxy로 NGINX 또는 NGINX Plus를 사용하면 SSL/TLS, HTTP/2 지원 등 다양한 기능을 통해 .NET Core 애플리케이션과 함께 빠른 애플리케이션 전달을 위한 보안 구성을 쉽게 설정할 수 있습니다.
아래 지침은 NGINX 및 NGINX Plus가 이미 시스템에 설치되어 있는 것으로 가정합니다.
그렇지 않은 경우 1. .NET Core, NGINX 및 NGINX Plus 설치 를 참조하십시오.
4-1. SSL 인증서 설치
SSL 인증서를 설치하세요. 다음과 같은 여러 가지 방법이 있습니다.
- 알려진 인증 기관 (CA)에서 구매
- 회사 IT 그룹이나 CA에서 생성
- 기존의 IIS 서버에서 내보내기
- Let’s Encrypt와 같은 무료 CA 사용
- 직접 자체 서명된 인증서 생성
빠르게 SSL을 적용한 샘플 .NET Core 앱을 설정하기 위해, 다음 openssl
명령을 사용하여 자체 서명된 인증서와 관련 키를 생성합니다.
인증서와 키는 NGINX의 표준 위치는 /etc/nginx에 설치되지만 다른 위치를 선택할 수도 있습니다.
$ openssl req -x509 -subj /CN=localhost -days 365 -set_serial 2 -newkey rsa:4096 -keyout /etc/nginx/cert.key -nodes -out /etc/nginx/cert.pem
Generating a 4096 bit RSA private key
.........++
............................++
writing new private key to '/etc/nginx/cert.key'
-----
4-2. Reverse Proxy 구성
HTTP 가상 서버에 대한 기본 NGINX 및 NGINX Plus 구성 파일에서 Reverse Proxy를 구성합니다.
NGINX 및 NGINX Plus의 주 구성 파일은 /etc/nginx/nginx.conf입니다.
그러나 여러 NGINX 배포판 (NGINX Plus도 포함)은 주 파일에 실제 구성을 많이 넣지 않고, /etc/nginx의 하위 디렉토리에 작은 기능별 파일을 생성하는 관행을 따릅니다.
- nginx.org 에서 제공하는 NGINX 오픈소스 빌드 및 NGINX Plus의 경우 디렉토리는 /etc/nginx/conf.d 이고 HTTP 가상 서버의 기본 파일은 default.conf 입니다.
- Ubuntu와 함께 배포되는 NGINX 오픈소스 빌드의 경우 디렉터리는 /etc/nginx/sites-enabled 이고 HTTP 가상 서버의 기본 파일은 default 입니다.
이러한 디렉토리의 기능별 파일 내용은 include 지시문을 사용하여 주 (nginx.conf) 파일에 읽혀집니다.
예를 들면 다음과 같습니다.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
시스템에서 HTTP 가상 서버의 기본 구성 파일이 어떤 것인지 확실하지 않은 경우, /etc/nginx/nginx.conf에서 관련 있는 include 지시문을 찾으세요.
NGINX 또는 NGINX Plus를 리버스 프록시로 구성하려면, HTTP 가상 서버의 기본 구성 파일에 다음 세 가지 구성 블록을 추가하세요.
- 첫 번째 server 블록은 포트 80에서의 HTTP 요청을 받아 HTTPS 요청을 위한 가상 서버로 리다이렉션합니다.
- 두 번째 server 블록은 포트 443에서의 HTTPS 요청을 받아 하나 이상의 upstream(백엔드) 서버 그룹인
dotnet
으로 프록시합니다. (4-1에서 /etc/nginx 이외의 디렉토리에 자체 서명된 SSL 인증서를 설치한 경우,ssl_certificate
및ssl_certificate_key
지시문에 올바른 경로를 대체하세요.) - upsteam 블록은
dotnet
백엔드 서버 그룹을 정의합니다.
Kestrel HTTP 서버 실행에서는 Kestrel을 localhost:5000
에서 구성했으므로 해당 포트에서 IPv4 및 IPv6 트래픽을 수신합니다 (Kestrel을 하나의 프로토콜만으로 구성하는 것은 불안정성과 잠재적인 502
오류를 일으킬 수 있습니다.) 마찬가지로, NGINX 및 NGINX Plus는 localhost
를 IPv4와 IPv6 주소로 해석합니다(127.0.0.1 및 ::1). 간편함을 위해 여기서는 업스트림 서버를 localhost
가 아닌 127.0.0.1로 식별하여 IPv4 트래픽만 수신하도록 했습니다. IPv6를 포함한 더 고급 구성에 익숙하다면 localhost
를 사용할 수 있습니다.
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
ssl_certificate /etc/nginx/cert.pem;
ssl_certificate_key /etc/nginx/cert.key;
location / {
proxy_pass http://dotnet;
proxy_set_header Host $host;
}
}
upstream dotnet {
zone dotnet 64k;
server 127.0.0.1:5000;
}
4-3. .NET Core 앱에 대한 연결 테스트
다음 curl
명령을 실행하여 HTTPS를 통해 .NET Core 앱과의 연결성을 테스트합니다.
(대신 Linux 서버에서 브라우저를 통해 방문할 수도 있습니다.)
$ curl -kv https://localhost
* Rebuilt URL to: https://localhost/
* Trying ::1...
* Connected to localhost (::1) port 443 (#0)
...[SKIPPED]...
< HTTP/1.1 200 OK
< Server: nginx/1.10.0 (Ubuntu)
< Date: Tue, 14 Feb 2017 20:22:07 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
<
Current date: 02/14/17 1:22:07 PM
502 Bad Gateway
오류가 나타나면 NGINX 또는 NGINX Plus가 .NET 애플리케이션에 연결할 수 없음을 의미합니다.
애플리케이션이 실행 중이고 포트 5000에서 응답을 제공하는지 확인하세요.
nghttp2
패키지를 설치한 경우 다음 nghttp
명령을 실행하여 HTTP/2를 통한 연결성을 테스트할 수도 있습니다. 아래 예시의 시작 부분에서 주황색으로 강조된 줄을 찾아보세요. 출력은 다소 길 수 있습니다.
$ nghttp -v https://localhost
[ 0.000] Connected
The negotiated protocol: h2
[ 0.009] send SETTINGS frame
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.009] send PRIORITY frame
(dep_stream_id=0, weight=201, exclusive=0)
5. NGINX Plus Live Activity Monitoring 및 Active Health Checks 구성
이 시점에서 .NET Core와 함께 NGINX 또는 NGINX Plus의 기본 구성을 완료했습니다. NGINX 또는 NGINX Plus는 .NET Core 애플리케이션에 대해 HTTP 처리, 수동 상태 확인, SSL/TLS를 통한 보안 및 HTTP/2 연결 기능을 제공합니다.
NGINX Plus를 설치한 경우 Live Activity Monitoring과 Active Health Checks이라는 두 가지 추가 기능을 구성할 수 있습니다.
5-1. Live Acitivity Monitoring
다음 server 블록을 HTTP 가상 서버의 기본 NGINX 구성 파일에 추가하세요. 통계 및 메트릭에 대한 액세스를 제한하는 것을 강력히 권장합니다. 여기서는 localhost 및 로컬 네트워크의 사용자에게만 액세스를 허용합니다.
실시간 활동 모니터링에 대한 자세한 정보는 NGINX STORE의 “Live Activity 모니터링” 포스트를 참조하십시오.
server {
listen 8080;
allow 127.0.0.1; # Allow localhost to access the statistics
allow 10.3.3.0/24; # Allow local network to access the statistics
deny all; # Prevent access from anywhere else
root /usr/share/nginx/html;
location / {
return 302 /dashboard.html;
}
location /api {
api write=on;
}
location = /dashboard.html {
root /usr/share/nginx/html;
}
# Redirect requests made to the old dashboard
location = /status.html {
return 301 /dashboard.html;
}
}
5-2. Active Health Checks
Active Health Checks는 NGINX Plus가 정상적으로 작동하는 애플리케이션에만 트래픽을 전송하도록 보장합니다.
NGINX Plus가 주시적으로 애플리케이션에 보내는 HTTP 요청 및 애플리케이션이 정상으로 간주되기 위해 반환해야 하는 응답 유형을 정의합니다.
앱의 응답은 다음 조건을 충족해야 합니다.
- 응답 코드가 200 OK여야 합니다.
- 앱 서버가 Kestrel이며 다른 소프트웨어가 아니어야 합니다.
- 응답의 본문에 “Current date”라는 단어가 포함되어야 합니다.
- 앱은 1초의 타임아웃 기간 내에 응답해야 합니다.
HTTP 가상 서버의 기본 구성 파일에 다음 location 블록을 메인 server 블록(4-2에서 정의한 HTTPS 트래픽을 위한 두 번째 블록)에 추가하세요.
location @healthcheck {
proxy_pass http://dotnet;
proxy_set_header Host localhost;
health_check match=currentdate;
proxy_connect_timeout 1s;
proxy_read_timeout 1s;
}
또한 server 및 upstream 블록과 동일한 수준의 계층에 다음 match 블록을 추가하세요.
match currentdate {
status 200;
header Server = Kestrel;
body ~ "Current date";
}
백엔드 애플리케이션이 정상인지 확인하려면 내장된 Live Activity Monitoring 대시보드의 Upstreams 탭에서 확인할 수 있습니다 (브라우저를 사용하여 http://nginx-plus-server-address:8080/로 접속하세요).

NGINX 구성 옵션에 대한 자세한 내용은 Microsoft 설명서를 참조하십시오.
6. 결론
ASP.NET으로 개발한 애플리케이션을 Production 환경에 배포할 때, NGINX 및 NGINX Plus는 Reverse Proxy로 필요한 트래픽 관리 기능을 제공합니다. NGINX와 NGINX Plus는 보안, 확장성, 인증, 트래픽 제한 및 HTTP 요청을 .NET Core 앱으로 지능적으로 라우팅하는 기능을 제공합니다.
NGINX Plus를 직접 사용해 보려면 무료 30일 체험판을 시작하거나 사용 사례에 대해 문의하십시오.
댓글을 달려면 로그인해야 합니다.