기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
배포 매니페스트를 사용하여 여러 애플리케이션 및 ASP.NET Core 애플리케이션 실행
배포 매니페스트를 사용하여 Elastic Beanstalk에 애플리케이션을 배포하는 방법을 알릴 수 있습니다. 이 방법을 사용하면 MSDeploy를 사용하여 웹 사이트의 루트 경로에서 실행되는 단일 ASP.NET 애플리케이션의 소스 번들을 생성할 필요가 없습니다. 대신 매니페스트 파일을 사용하여 서로 다른 경로에서 여러 애플리케이션을 실행할 수 있습니다. 또는 ASP.NET Core를 사용하여 앱을 배포하고 실행하도록 Elastic Beanstalk에 지시할 수도 있습니다. 또한 배포 매니페스트를 사용하여 애플리케이션을 실행할 애플리케이션 풀을 구성할 수도 있습니다.
배포 매니페스트는 Elastic Beanstalk에 .NET Core 애플리케이션에 대한 지원을 추가합니다. 배포 매니페스트를 사용하지 않고 .NET Framework 애플리케이션을 배포할 수 있습니다. 하지만 .NET Core 애플리케이션을 Elastic Beanstalk에서 실행하려면 배포 매니페스트가 필요합니다. 배포 매니페스트를 사용할 때는 각 애플리케이션의 사이트 아카이브를 만든 후 배포 매니페스트가 들어 있는 두 번째 ZIP 아카이브에 그 사이트 아카이브를 번들링합니다.
배포 매니페스트는 여러 경로에서 여러 애플리케이션을 실행하는 기능도 추가합니다. 배포 매니페스트는 배포 대상 배열을 정의하는데, 각 배포 대상에는 사이트 아카이브 및 IIS가 이를 실행해야 하는 경로가 들어 있습니다. 예를 들어 /api 경로에서 웹 API를 실행하여 비동기 요청을 처리하고, API를 사용하는 루트 경로에서 웹 앱을 실행할 수 있습니다.
배포 매니페스트를 사용하여 사용자 지정 바인딩 및 물리적 경로로 IIS 웹 사이트를 구성할 수 있습니다. 이를 통해 애플리케이션을 배포하기 전에 특정 포트 또는 호스트 이름에서 수신 대기하는 웹 사이트를 설정할 수 있습니다.
배포 매니페스트를 사용하여 IIS 또는 Kestrel의 애플리케이션 풀을 사용하여 여러 애플리케이션을 실행할 수도 있습니다. 애플리케이션을 주기적으로 다시 시작하거나, 32비트 애플리케이션을 실행하거나, .NET Framework 실행 시간의 특정 버전을 사용하도록 애플리케이션 풀을 구성할 수 있습니다.
완전한 사용자 지정을 하려면 Windows PowerShell에 자체 배포 스크립트를 작성하고 Elastic Beanstalk에 애플리케이션을 설치, 제거 및 다시 시작하기 위해 실행할 스크립트를 알리면 됩니다.
배포 매니페스트와 관련 기능에는 Windows Server 플랫폼 버전 1.2.0 이상이 필요합니다.
사용 가능한 모든 구성 옵션, 속성, IIS 재설정 건너뛰기와 같은 고급 기능에 대한 자세한 내용은 배포 매니페스트 스키마 참조를 참조하세요.
Sections
.NET Core 앱
배포 매니페스트를 사용하여 Elastic Beanstalk 에서 .NET Core 애플리케이션을 실행할 수 있습니다. .NET Core는 .NET의 교차 플랫폼 버전으로, 명령 줄 도구(dotnet)와 함께 제공됩니다. 이 도구를 사용하여 애플리케이션을 생성하고 로컬로 실행하고 게시하도록 준비할 수 있습니다.
Elastic Beanstalk에서 .NET Core 애플리케이션을 실행하려면 dotnet publish를 실행하고 포함된 모든 디렉터리를 제외한 출력을 ZIP 아카이브로 패키징하면 됩니다. 배포 대상 유형이 aspNetCoreWeb인 배포 매니페스트를 사용하여 사이트 아카이브를 소스 번들에 배치합니다.
다음 배포 매니페스트는 루트 경로에서 dotnet-core-app.zip이라는 사이트 아카이브의 .NET Core 애플리케이션을 실행합니다.
예 aws-windows-deployment-manifest.json - .NET Core
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "my-dotnet-core-app",
"parameters": {
"archive": "dotnet-core-app.zip",
"iisPath": "/"
}
}
]
}
}매니페스트와 사이트 아카이브를 ZIP 아카이브로 번들링하여 소스 번들을 만듭니다.
예 dotnet-core-bundle.zip
.
|-- aws-windows-deployment-manifest.json
`-- dotnet-core-app.zip
사이트 아카이브에는 컴파일된 애플리케이션 코드, 종속 항목, web.config 파일이 들어 있습니다.
예 dotnet-core-app.zip
.
|-- Microsoft.AspNetCore.Hosting.Abstractions.dll
|-- Microsoft.AspNetCore.Hosting.Server.Abstractions.dll
|-- Microsoft.AspNetCore.Hosting.dll
|-- Microsoft.AspNetCore.Http.Abstractions.dll
|-- Microsoft.AspNetCore.Http.Extensions.dll
|-- Microsoft.AspNetCore.Http.Features.dll
|-- Microsoft.AspNetCore.Http.dll
|-- Microsoft.AspNetCore.HttpOverrides.dll
|-- Microsoft.AspNetCore.Server.IISIntegration.dll
|-- Microsoft.AspNetCore.Server.Kestrel.dll
|-- Microsoft.AspNetCore.WebUtilities.dll
|-- Microsoft.Extensions.Configuration.Abstractions.dll
|-- Microsoft.Extensions.Configuration.EnvironmentVariables.dll
|-- Microsoft.Extensions.Configuration.dll
|-- Microsoft.Extensions.DependencyInjection.Abstractions.dll
|-- Microsoft.Extensions.DependencyInjection.dll
|-- Microsoft.Extensions.FileProviders.Abstractions.dll
|-- Microsoft.Extensions.FileProviders.Physical.dll
|-- Microsoft.Extensions.FileSystemGlobbing.dll
|-- Microsoft.Extensions.Logging.Abstractions.dll
|-- Microsoft.Extensions.Logging.dll
|-- Microsoft.Extensions.ObjectPool.dll
|-- Microsoft.Extensions.Options.dll
|-- Microsoft.Extensions.PlatformAbstractions.dll
|-- Microsoft.Extensions.Primitives.dll
|-- Microsoft.Net.Http.Headers.dll
|-- System.Diagnostics.Contracts.dll
|-- System.Net.WebSockets.dll
|-- System.Text.Encodings.Web.dll
|-- dotnet-core-app.deps.json
|-- dotnet-core-app.dll
|-- dotnet-core-app.pdb
|-- dotnet-core-app.runtimeconfig.json
`-- web.config여러 애플리케이션 실행
여러 배포 대상을 정의하여 배포 매니페스트로 여러 애플리케이션을 실행할 수 있습니다.
다음 배포 매니페스트는 .NET Core 애플리케이션 두 개를 구성합니다. WebApiSampleApp 애플리케이션은 단순한 웹 API를 구현하며, /api 경로에서 비동기 요청을 수행합니다. DotNetSampleApp 애플리케이션은 루트 경로에서 요청을 수행하는 웹 애플리케이션입니다.
예 aws-windows-deployment-manifest.json - 여러 앱
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "WebAPISample",
"parameters": {
"appBundle": "WebApiSampleApp.zip",
"iisPath": "/api"
}
},
{
"name": "DotNetSample",
"parameters": {
"appBundle": "DotNetSampleApp.zip",
"iisPath": "/"
}
}
]
}
}다음을 통해 여러 애플리케이션으로 구성된 샘플 애플리케이션을 사용할 수 있습니다.
-
배포 가능한 소스 번들 - dotnet-multiapp-sample-bundle-v2.zip
IIS 웹 사이트 구성
배포 매니페스트를 사용하여 사용자 지정 바인딩 및 실제 경로로 IIS 웹 사이트를 구성할 수 있습니다. 이는 특정 포트에서 수신 대기하거나, 사용자 지정 호스트 이름을 사용하거나, 특정 디렉터리의 콘텐츠를 제공하는 웹 사이트를 설정해야 할 때 유용합니다.
다음 배포 매니페스트는 특정 포트 번호와 사용자 지정 실제 경로를 사용하여 HTTP에서 수신 대기하는 사용자 지정 IIS 웹 사이트를 구성합니다.
예 aws-windows-deployment-manifest.json - IIS 웹 사이트 구성
{
"manifestVersion": 1,
"iisConfig": {
"websites": [
{
"name": "MyCustomSite",
"physicalPath": "C:\inetpub\wwwroot\mysite",
"bindings": [
{
"protocol": "http",
"port": 8080,
"hostName": "mysite.local"
}
]
}
]
},
"deployments": {
"aspNetCoreWeb": [
{
"name": "my-dotnet-core-app",
"parameters": {
"appBundle": "dotnet-core-app.zip",
"iisWebSite": "MyCustomSite",
"iisPath": "/"
}
}
]
}
}이 예시는 다음과 같이 설정되어 있습니다.
-
"MyCustomSite"라는 웹 사이트가 사용자 지정 물리적 경로로 생성됩니다.
-
웹 사이트는 특정 호스트 이름으로 포트 8080에 HTTP 바인딩을 갖습니다.
-
ASP.NET Core 애플리케이션은
iisWebSite파라미터를 사용하여 이 사용자 지정 웹 사이트에 배포됩니다.
Application Request Routing(ARR) 사용
Application Request Routing(ARR) 및 URL Rewrite 모듈은 Elastic Beanstalk Windows AMI에 사전 설치되어 사용할 수 있습니다. 이러한 모듈을 사용하면 ebextensions 또는 애플리케이션 구성을 사용하는 IIS 구성을 통해 고급 라우팅 시나리오 및 URL 조작이 가능합니다.
다음 예제는 사용자 지정 포트로 웹 사이트를 구성하는 간단한 배포 매니페스트와 기본 ARR 라우팅을 설정하는 ebextensions 구성을 결합한 것을 보여줍니다.
예 aws-windows-deployment-manifest.json - 간단한 ARR 설정
{
"manifestVersion": 1,
"iisConfig": {
"websites": [
{
"name": "ARRSite",
"physicalPath": "C:\\inetpub\\wwwroot\\arrsite",
"bindings": [
{
"protocol": "http",
"port": 8080,
"hostName": "localhost"
}
]
}
]
},
"deployments": {
"aspNetCoreWeb": [
{
"name": "BackendApp",
"parameters": {
"appBundle": "backend-app.zip",
"iisWebSite": "ARRSite",
"iisPath": "/backend"
}
}
]
}
}ARR 구성은 ebextensions를 통해 수행됩니다. 다음 구성은 기본 ARR 라우팅 규칙을 설정합니다.
예.ebextensions/arr-config.config - 기본 ARR 구성
files:
"C:\\temp\\configure-arr.ps1":
content: |
# Enable ARR proxy at server level
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/proxy' -Name 'enabled' -Value 'True'
# Clear any existing global rules to avoid conflicts
Clear-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/rewrite/globalRules'
# Add global rule to route all requests to backend
Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
-Filter 'system.webServer/rewrite/globalRules' `
-Name '.' `
-Value @{
name = 'Route_to_Backend'
stopProcessing = 'True'
match = @{ url = '^(?!backend/)(.*)' }
action = @{
type = 'Rewrite'
url = 'http://localhost:8080/backend/{R:1}'
}
}
container_commands:
01_configure_arr:
command: powershell -ExecutionPolicy Bypass -File "C:\\temp\\configure-arr.ps1"
waitAfterCompletion: 0이 구성은 포트 8080에 웹 사이트를 생성하고 모든 수신 요청을 해당 사이트에서 실행되는 백엔드 애플리케이션으로 라우팅하도록 ARR을 설정합니다.
애플리케이션 풀 구성
Windows 환경에서 여러 애플리케이션을 지원할 수 있습니다. 다음 두 가지 방법을 사용할 수 있습니다.
-
Kestrel 웹 서버를 통해 프로세스 외 호스팅 모델을 사용할 수 있습니다. 이 모델을 사용하기 위해 여러 애플리케이션이 하나의 애플리케이션 풀에서 실행되도록 구성할 수 있습니다.
-
진행 중인 호스팅 모델을 사용할 수 있습니다. 이 모델에서는 여러 애플리케이션 풀을 사용하여 각 풀에 하나의 애플리케이션만 있는 여러 애플리케이션을 실행합니다. IIS 서버를 사용하고 있고 여러 애플리케이션을 실행해야 하는 경우 이 방법을 사용해야 합니다.
하나의 애플리케이션 풀에서 여러 애플리케이션을 실행하도록 Kestrel을 구성하려면 hostingModel="OutofProcess" 파일에 web.config를 추가합니다. 다음 예제를 살펴보세요.
예 web.config - Kestrel의 프로세스 외 호스팅 모델
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add
name="aspNetCore"
path="*" verb="*"
modules="AspNetCoreModuleV2"
resourceType="Unspecified" />
</handlers>
<aspNetCore
processPath="dotnet"
arguments=".\CoreWebApp-5-0.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="OutofProcess" />
</system.webServer>
</location>
</configuration>예 aws-windows-deployment-manifest.json - 여러 애플리케이션
{
"manifestVersion": 1,
"deployments": {"msDeploy": [
{"name": "Web-app1",
"parameters": {"archive": "site1.zip",
"iisPath": "/"
}
},
{"name": "Web-app2",
"parameters": {"archive": "site2.zip",
"iisPath": "/app2"
}
}
]
}
}IIS는 프로세스 내 호스팅 모델을 사용하므로 하나의 애플리케이션 풀에서 여러 애플리케이션을 지원하지 않습니다. 따라서 각 애플리케이션을 하나의 애플리케이션 풀에 할당하여 여러 애플리케이션을 구성해야 합니다. 즉, 하나의 애플리케이션 풀에 하나의 애플리케이션만 할당합니다.
aws-windows-deployment-manifest.json 파일에서 여러 애플리케이션 풀을 사용하도록 IIS를 구성할 수 있습니다. 다음 예제 파일을 참조하여 다음과 같이 업데이트합니다.
-
iisConfig라는 하위 섹션이 포함된appPools섹션을 추가합니다. -
appPools블록에서 애플리케이션 풀을 나열합니다. -
deployments섹션에서 각 애플리케이션에 대한parameters섹션을 정의합니다. -
parameters섹션은 각 애플리케이션에 대해 아카이브, 실행 경로 및 실행할appPool을 지정합니다.
다음 배포 매니페스트는 10분마다 애플리케이션을 다시 시작하는 2개의 애플리케이션 풀을 구성합니다. 또한 지정된 경로에서 실행되는 .NET Framework 웹 애플리케이션에 애플리케이션을 연결합니다.
예 aws-windows-deployment-manifest.json - 애플리케이션 풀당 하나의 애플리케이션
{
"manifestVersion": 1,
"iisConfig": {"appPools": [
{"name": "MyFirstPool",
"recycling": {"regularTimeInterval": 10}
},
{"name": "MySecondPool",
"recycling": {"regularTimeInterval": 10}
}
]
},
"deployments": {"msDeploy": [
{"name": "Web-app1",
"parameters": {
"archive": "site1.zip",
"iisPath": "/",
"appPool": "MyFirstPool"
}
},
{"name": "Web-app2",
"parameters": {
"archive": "site2.zip",
"iisPath": "/app2",
"appPool": "MySecondPool"
}
}
]
}
}사용자 지정 배포 정의
더욱 세부적인 제어를 위해 사용자 지정 배포를 정의하여 애플리케이션 배포를 완전히 사용자 지정할 수 있습니다. 사용자 지정 배포를 사용하면 Elastic Beanstalk는 사용자가 제공하는 PowerShell 스크립트만 실행하며 사용자를 대신하여 IIS 관리를 수행하지 않습니다. 이는 msDeploy Elastic Beanstalk가 설치 전에 IIS를 자동으로 중지하고, 나중에 시작하고, 필요한 경우 다시 시작하는 및 aspNetCoreWeb 배포와 다릅니다. 사용자 지정 배포의 경우 스크립트는 애플리케이션 콘텐츠를 배치하고, 환경(예: IIS)을 구성하고, 애플리케이션을 다시 시작합니다.
중요
로드 밸런싱된 웹 서버 환경에서 Elastic Beanstalk는 포트 80에서 환경의 상태 확인 경로(/기본값)를 요청하여 인스턴스 상태를 확인합니다. 해당 경로를 제공해야 합니다. 그렇지 않으면 모든 배포 스크립트가 성공하더라도 환경이 비정상이 됩니다. 이는 오류 없이 완료되지만 환경을 빨간색 상태로 유지하는 사용자 지정 배포의 일반적인 원인입니다. 독립 실행형 사용자 지정 배포의 경우 기본 웹 사이트의 루트에서 애플리케이션을 제공합니다. 다른 배포가 이미 상태 확인 경로를 제공하는 경우 하위 경로 아래에 사용자 지정 애플리케이션을 배치하는 것이 유효합니다. 예를 들어 다중 애플리케이션 매니페스트에 있습니다. 환경 상태에 대한 자세한 내용은 환경 모니터링을 참조하세요.
사용자 지정 배포는 최대 3개의 스크립트를 정의합니다. 다음 표에서는 각 스크립트, Elastic Beanstalk가 스크립트를 실행하는 시기, 스크립트가 수행해야 하는 작업을 설명합니다.
| Script | Elastic Beanstalk가 실행할 때 | 책임 |
|---|---|---|
uninstall |
각 새 애플리케이션 버전이 설치되기 전에, 즉 각 애플리케이션 배포 전에. | 서비스를 중지하거나 이전 버전의 파일을 제거합니다. |
install |
각 애플리케이션 배포 중. | 파일을 배포하고, IIS 또는 서비스를 구성하고, 상태 확인 경로에서 애플리케이션을 제공합니다. |
restart |
모든 애플리케이션 배포 후 및 모든 구성 변경 후. 를 skipIISReset로 설정하면 trueElastic Beanstalk는 애플리케이션 배포 시이 스크립트를 건너뛰지만 구성 변경 시 계속 실행합니다. 앱 서버 재시작을 선택하면 플랫폼 수준이 수행iisreset되고 사용자 지정 재시작 스크립트가 호출되지 않습니다. |
새 버전이 활성화되도록 IIS(iisreset) 또는 서비스를 다시 시작합니다. |
이러한 스크립트는 예를 들어 초기 환경 생성 및 Auto Scaling이 인스턴스를 추가하는 경우(스케일 아웃)와 같이 Elastic Beanstalk가 새로 시작된 인스턴스에 애플리케이션을 배포할 때마다 실행됩니다. 각 새 인스턴스는 부트스트랩할 때 애플리케이션을 설치하기 때문입니다.
다음 배포 매니페스트는 Elastic Beanstalk에 32비트 모드에서 PowerShell 스크립트를 실행하도록 지시합니다. 스크립트(install.ps1), install 스크립트restart(restart.ps1) 및 uninstall 스크립트()를 지정합니다uninstall.ps1. 제거할 것이 없는 경우 첫 번째 배포가 실패하지 true 않도록 스크립트는 uninstall를 ignoreErrors로 설정합니다.
예 aws-windows-deployment-manifest.json - 사용자 지정 배포
{
"manifestVersion": 1,
"deployments": {
"custom": [
{
"name": "Custom site",
"architecture": 32,
"scripts": {
"install": {
"file": "install.ps1"
},
"restart": {
"file": "restart.ps1"
},
"uninstall": {
"file": "uninstall.ps1",
"ignoreErrors": true
}
}
}
]
}
}매니페스트와 스크립트를 사용하여 소스 번들에 애플리케이션을 실행하는 데 필요한 모든 결과물을 포함시킵니다. Elastic Beanstalk는 사용자 지정 배포를 위해 이러한 아티팩트를 추출하지 않으므로 스크립트가 아티팩트를 추출해야 합니다. 다음 예제에서는 애플리케이션 콘텐츠가 로 패키징됩니다MyApp.zip.
예 Custom-site-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- install.ps1
|-- restart.ps1
|-- uninstall.ps1
`-- MyApp.zip
다음 스크립트는 IIS 호스팅 애플리케이션에 대한 완전한 health-check-correct 사용자 지정 배포를 보여줍니다. install.ps1 스크립트는 애플리케이션 콘텐츠를 추출하고 기본 웹 사이트의 물리적 경로를 가리키므로 상태 확인이 표시되는 루트 경로(/)에서 애플리케이션이 제공됩니다.
예 install.ps1
$ErrorActionPreference = "Stop"
$appPath = "C:\inetpub\MyApp"
if (Test-Path $appPath) { Remove-Item $appPath -Recurse -Force }
# Elastic Beanstalk doesn't extract your bundle for custom deployments, so extract it yourself.
# MyApp.zip ships in the bundle, alongside this script. Resolve it relative to the script's
# own location so the path is reliable regardless of the current working directory.
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
$bundleZip = Join-Path $scriptDir "MyApp.zip"
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
[IO.Compression.ZipFile]::ExtractToDirectory($bundleZip, $appPath)
# Serve from the Default Web Site root ("/"), where the health check looks.
Import-Module WebAdministration
Set-ItemProperty "IIS:\Sites\Default Web Site" -Name physicalPath -Value $appPath
iisreset.exe /restart
if ($LASTEXITCODE -ne 0) { exit 1 }예 restart.ps1
$ErrorActionPreference = "Stop"
iisreset.exe /restart
if ($LASTEXITCODE -ne 0) { exit 1 }예 uninstall.ps1
# Stop IIS first. While the site is live, w3wp holds locks on files under the app directory,
# which would make the following removal fail.
iisreset.exe /stop | Out-Null
Remove-Item "C:\inetpub\MyApp" -Recurse -Force -ErrorAction SilentlyContinue사용자 지정 배포 스크립트를 작성할 때는 다음 사항에 유의하세요.
-
상태 확인 경로를 제공합니다. 애플리케이션에서 기본 웹 사이트의 물리적 경로를 가리키거나 상태 확인이 성공하도록 상태 확인 경로에 배포합니다.
-
기본 문서를 포함합니다. 사이트 루트에 기본 문서가 없는 경우는 HTTP 403을
GET /반환하고 상태 확인이 실패합니다.<defaultDocument>요소를 설정하는web.config파일을 발송하거나Default.htm또는와 같은 IIS 기본 문서 이름과 일치하도록 랜딩 페이지의 이름을 지정합니다index.htm. -
IIS를 직접 다시 시작합니다. Elastic Beanstalk는 사용자 지정 배포에 대한 IIS 관리를 수행하지 않으므로 변경 사항이 적용
iisreset되도록 스크립트를 실행해야 합니다. -
스크립트를 기준으로 번들 파일을 찾습니다. Elastic Beanstalk는 스크립트와 번들 아티팩트를 동일한 디렉터리로 함께 추출합니다. 현재 작업 중인 특정 디렉터리를 수임하는 대신
$PSScriptRoot(실행 중인 스크립트가 포함된 폴더)에 대해 번들링된 파일을 해결합니다. -
실패는 배포에 실패합니다. 외부 명령
$LASTEXITCODE후$ErrorActionPreference = "Stop"를 설정하고 확인합니다. 그렇지 않으면 손상된 스크립트가 성공적으로 종료될 수 있으며, Elastic Beanstalk는 애플리케이션이 올바르게 실행되지 않더라도 배포를 성공으로 처리합니다.
예: 자체 호스팅 Windows 서비스
사용자 지정 배포를 사용하면 IIS 호스팅 사이트 대신 Windows 서비스를 실행할 수 있습니다. Elastic Beanstalk Windows 플랫폼은 작업자 환경 계층을 지원하지 않습니다. 로드 밸런싱된 환경에서 로드 밸런서는 포트 80의 상태 확인 경로를 확인하므로, 환경을 정상으로 유지하려면 Windows 서비스가 해당 요청에 응답해야 합니다. 다음 예제는 포트 80 자체에서 수신 대기하는 자체 호스팅 서비스이므로 동반 IIS 사이트가 필요하지 않습니다.
참고
Windows 플랫폼에는 작업자 계층이 없으므로 백그라운드 전용 서비스는 로드 밸런싱된 환경에서 상태 확인에 응답해야 합니다. 서비스가 상태 확인 경로(예: )에도 응답하도록 하거나 서비스를 제공하는 사이트와 함께 백그라운드 작업을 실행합니다.
매니페스트는 서비스를 빌드하는 데 사용되는 64비트 C# 컴파일러와 일치하는 64비트 모드에서 스크립트를 실행합니다.
예 aws-windows-deployment-manifest.json - Windows 서비스
{
"manifestVersion": 1,
"deployments": {
"custom": [
{
"name": "EbCustomService",
"architecture": 64,
"scripts": {
"install": {
"file": "serviceInstall.ps1"
},
"restart": {
"file": "serviceRestart.ps1"
},
"uninstall": {
"file": "serviceUninstall.ps1",
"ignoreErrors": true
}
}
}
]
}
}번들은 매니페스트, 3개의 스크립트, 서비스 소스 코드 및 version.txt 파일(예:와 같은 버전 문자열)을 제공합니다v1. 설치 스크립트는 인스턴스에서 서비스를 컴파일하므로 번들에 빌드 도구 체인이 필요하지 않습니다.
예 Custom-service-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- EbCustomService.cs
|-- serviceInstall.ps1
|-- serviceRestart.ps1
|-- serviceUninstall.ps1
`-- version.txt스크립트는 IIS에서 포트 80을 해제하고, 인박스 C# serviceInstall.ps1 컴파일러(csc.exe)를 사용하여 번들 소스에서 서비스를 컴파일하고, 이를 LocalSystem 서비스로 등록하고, 시작합니다. 로 실행LocalSystem하면 URL ACL 예약 http://+:80/ 없이 서비스가 바인딩되어 예제가 최소화됩니다. 프로덕션 환경에서는와 같은 최소 권한 계정을 선호NetworkService하고를 사용하여 명시적으로 바인딩을 부여합니다netsh http add urlacl.
예 serviceInstall.ps1
# INSTALL: compile and register a self-hosted HTTP service that owns port 80.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
$appPath = "C:\CustomService"
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
# Free port 80 from IIS and keep it from reclaiming the port on reboot.
Stop-Service W3SVC -Force -ErrorAction SilentlyContinue
Set-Service W3SVC -StartupType Manual -ErrorAction SilentlyContinue
# Fresh application directory.
if (Test-Path $appPath) { Remove-Item $appPath -Recurse -Force }
New-Item -ItemType Directory -Path $appPath | Out-Null
# Compile the service with the in-box .NET Framework compiler (no build tooling needed).
$csc = Join-Path $env:WINDIR "Microsoft.NET\Framework64\v4.0.30319\csc.exe"
$src = Join-Path $scriptDir "EbCustomService.cs"
$exe = Join-Path $appPath "EbCustomService.exe"
& $csc /nologo /target:exe /out:"$exe" /reference:System.ServiceProcess.dll "$src"
if ($LASTEXITCODE -ne 0) { exit 1 }
# Write the content served at "/". A real service would serve its own responses;
# here the install script writes a simple marker so the health check passes.
$version = (Get-Content (Join-Path $scriptDir "version.txt") -Raw).Trim()
Set-Content -Path (Join-Path $appPath "marker.txt") `
-Value "Custom service deployment $version succeeded" -NoNewline
# Register as a LocalSystem service so it can bind http://+:80/ without a URL ACL.
if (Get-Service $svcName -ErrorAction SilentlyContinue) {
Stop-Service $svcName -Force -ErrorAction SilentlyContinue
sc.exe delete $svcName | Out-Null
# sc.exe delete is async; poll until gone so New-Service below doesn't hit
# "service marked for deletion".
$deadline = (Get-Date).AddSeconds(30)
while ((Get-Service $svcName -ErrorAction SilentlyContinue) -and (Get-Date) -lt $deadline) {
Start-Sleep -Milliseconds 500
}
}
New-Service -Name $svcName -BinaryPathName "`"$exe`"" `
-DisplayName "EB Custom Service" -StartupType Automatic | Out-Null
Start-Service $svcNameserviceRestart.ps1 스크립트는 새 버전이 활성화되도록 서비스를 다시 시작합니다.
예 serviceRestart.ps1
# RESTART: restart the service so the new version becomes live.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
Restart-Service $svcName -ForceserviceUninstall.ps1 스크립트는 서비스를 중지 및 삭제하고 이전 버전의 파일을 제거합니다. 첫 번째 배포에는 제거할 이전 버전이 없으므로 매니페스트는이 스크립트에 ignoreErrors true 대해 로 설정됩니다.
예 serviceUninstall.ps1
# UNINSTALL: stop and remove the previous version before the new install.
# The manifest sets ignoreErrors:true because the first deploy has nothing to remove.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
$appPath = "C:\CustomService"
if (Get-Service $svcName -ErrorAction SilentlyContinue) {
Stop-Service $svcName -Force -ErrorAction SilentlyContinue
sc.exe delete $svcName | Out-Null
# sc.exe delete is async; poll until the service is really gone so the next
# deploy's New-Service doesn't hit "service marked for deletion".
$deadline = (Get-Date).AddSeconds(30)
while ((Get-Service $svcName -ErrorAction SilentlyContinue) -and (Get-Date) -lt $deadline) {
Start-Sleep -Milliseconds 500
}
}
if (Test-Path $appPath) {
Remove-Item $appPath -Recurse -Force -ErrorAction SilentlyContinue
}서비스 자체는 HttpListener에서를 호스팅http://+:80/하고에 대한 텍스트 응답을 반환하는 작은 C# 프로그램으로GET /, 로드 밸런서 상태 확인을 충족합니다.
예 EbCustomService.cs
// Minimal self-hosted HTTP Windows service. Hosts an HttpListener on http://+:80/
// and answers the load balancer's GET "/" health check with the content that the
// install script wrote to marker.txt.
using System;
using System.IO;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading;
namespace EbCustomService
{
public class MarkerService : ServiceBase
{
private const string Root = @"C:\CustomService";
private HttpListener _listener;
private Thread _worker;
private volatile bool _running;
public MarkerService()
{
this.ServiceName = "EbCustomService";
}
protected override void OnStart(string[] args)
{
_running = true;
_listener = new HttpListener();
_listener.Prefixes.Add("http://+:80/");
_listener.Start();
_worker = new Thread(Loop) { IsBackground = true };
_worker.Start();
}
protected override void OnStop()
{
_running = false;
try { if (_listener != null) _listener.Stop(); } catch { }
}
private void Loop()
{
while (_running)
{
HttpListenerContext ctx;
try { ctx = _listener.GetContext(); }
catch { break; }
try
{
byte[] buf = Encoding.UTF8.GetBytes(ReadFile(Path.Combine(Root, "marker.txt")));
ctx.Response.StatusCode = 200;
ctx.Response.ContentType = "text/plain";
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
ctx.Response.OutputStream.Close();
}
catch { }
}
}
private static string ReadFile(string p)
{
try { return File.Exists(p) ? File.ReadAllText(p) : ""; }
catch { return ""; }
}
public static void Main()
{
ServiceBase.Run(new MarkerService());
}
}
}참고
이 예제에서에서 제공되는 응답/은 애플리케이션의 실제 콘텐츠를 나타내는 작은 텍스트 마커(marker.txt)입니다. 프로덕션 서비스는 대신 자체 응답을 제공합니다. 이러한 스크립트의 다른 모든 것은 작동하는 Windows 서비스 사용자 지정 배포에 필요한 최소 항목입니다.