티스토리 뷰
<참조> https://azuredevopslabs.com/labs/vstsextend/aspnetmodernize/
이 랩은 진행과정에서의 설명을 일부 생략된 부분 때문에 그리고 랩 수행 환경 탓인지 에러가 많이 발생하여 미뤄왔던 것이었다. 이번에 다시 2편에 걸쳐 나눠서 재시도하여 정리를 하려 한다. 먼저 1편을 정리한다. |
개요
웹 애플리케이션을 현대화하고 클라우드로 이동하기로 결정한 경우 반드시 앱을 완전히 재설계(re-architect)할 필요는 없다. 온 프레미스 아키텍처를 에뮬레이트하는 환경을 구축하고 애플리케이션을 "가져오기"는 하지만 그 이상을 달성하지는 못한다.
마이크로 서비스와 같은 고급 접근 방식을 사용하여 애플리케이션을 재구성하는 것은 비용과 시간 제약으로 인해 항상 선택 사항이 아니다. 앱을 분리하고 때로는 수년 간의 작업이 될 수 있는 내용을 다시 작성하고 사람과 비즈니스 결정을 반복하는 것은 권장되는 첫 번째 단계가 아닐 것 이다.
애플리케이션 유형에 따라 앱을 다시 설계 할 필요가 없을 수 있다. 하지만 Dockerfile을 추가하고 데이터베이스를 Azure의 SQL Database와 같은 서비스 제품으로 마이그레이션 할 때 연결 문자열 외에 다른 코드 변경이 필요하지 않을 수 있다.
이 실습에서는 Nerd Dinner 애플리케이션을 사용한다. Nerd Dinner는 전문가와 컴퓨터 사용자가 모임을 계획하는 데 도움이 되는 오픈 소스 ASP.NET MVC 프로젝트이다. 라이브 실행 사이트는 http://www.nerddinner.com에서 볼 수 있다. 애플리케이션 DB를 Azure SQL 인스턴스로 이동하고 Docker 지원을 애플리케이션에 추가하여 Azure Container Instances에서 애플리케이션을 실행한다.
이 랩에서 다루는 것
이 실습을 마치면 다음을 수행 할 수 있게 될 것이다.
- Azure의 SQL Server로 LocalDB 마이그레이션
- Visual Studio 2017의 Docker 도구를 사용하여 애플리케이션에 대한 Docker 지원 추가
- Azure Container Registry(ACR)에 Docker 이미지 게시
- ACR에서 ACI (Azure Container Instances)로 새 Docker 이미지 푸시
시작하기 전에
1. Microsoft Azure 계정 : Azure 랩에 대해 유효하고 활성인 Azure 계정이 필요하다. 없는 경우 무료 평가판에 등록 할 수 있다.
2. .Net Core SDK 및 Visual Studio 용 Azure 개발 도구가 설치된 Visual Studio 2017 최신 버전
3. Docker for windows를 설치해야 한다. Docker for windows에 대한 다운로드 및 설치 지침을 보려면 여기를 클릭한다.
환경 설정하기
1. 로컬 머신에서 https://github.com/spboyer/nerddinner-mvc4로부터 애플리케이션 리포지토리를 복제하고 Visual Studio 2017에서 솔루션을 연다. (이 실습에서는 Visual Studio 2019를 활용하도록 하겠다.)
2. 솔루션을 다시 빌드하고 애플리케이션을 로컬에서 실행하여 애플리케이션이 제대로 작동하는지 확인한다. 애플리케이션은 아래 그림과 같다.
실습 1: Azure의 SQL Server로 LocalDB 마이그레이션
이 실습에서는 SQL Azure 인스턴스를 만들고 애플리케이션 LocalDB를 Azure의 SQL Server로 마이그레이션한다.
1. Azure CLI 기반의 명령을 사용하여 새 SQL Azure 인스턴스를 만든다.
파라미터 값 설정
# 데이터베이스용 관리자 로그인 및 패스워드 설정 # Azure DNS에서 유일한 서버 이름 설정 (<server_name>.database.windows.net) # 데이터베이스 접근 가능 IP 주소 대역 설정 |
zerobig_devops@Azure:~$ resourceGroupName=azdo-ho-rg
zerobig_devops@Azure:~$ location=koreacentral
zerobig_devops@Azure:~$ adminlogin=azureuser
zerobig_devops@Azure:~$ password=Azure1234567!
zerobig_devops@Azure:~$ serverName=server-$RANDOM
zerobig_devops@Azure:~$ startip=0.0.0.0
zerobig_devops@Azure:~$ endip=0.0.0.0
리소스 그룹 및 서버 생성
# 리소스 그룹 생성
|
zerobig_devops@Azure:~$ az group create --name $resourceGroupName --location $location
{
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/azdo-ho-rg",
"location": "koreacentral",
"managedBy": null,
"name": "azdo-ho-rg",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
zerobig_devops@Azure:~$ az sql server create \
> --name $serverName \
> --resource-group $resourceGroupName \
> --location $location \
> --admin-user $adminlogin \
> --admin-password $password
{- Finished ..
"administratorLogin": "azureuser",
"administratorLoginPassword": null,
"fullyQualifiedDomainName": "server-19497.database.windows.net",
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/azdo-ho-rg/providers/Microsoft.Sql/servers/server-19497",
"identity": null,
"kind": "v12.0",
"location": "koreacentral",
"minimalTlsVersion": null,
"name": "server-19497",
"privateEndpointConnections": [],
"publicNetworkAccess": "Enabled",
"resourceGroup": "azdo-ho-rg",
"state": "Ready",
"tags": null,
"type": "Microsoft.Sql/servers",
"version": "12.0"
}
서버에 대한 방화벽 규칙 구성
az sql server firewall-rule create \ |
zerobig_devops@Azure:~$ az sql server firewall-rule create \
> --resource-group $resourceGroupName \
> --server $serverName \
> -n AllowYourIp \
> --start-ip-address $startip \
> --end-ip-address $endip
{
"endIpAddress": "0.0.0.0",
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/azdo-ho-rg/providers/Microsoft.Sql/servers/server-19497/firewallRules/AllowYourIp",
"kind": "v12.0",
"location": "Korea Central",
"name": "AllowYourIp",
"resourceGroup": "azdo-ho-rg",
"startIpAddress": "0.0.0.0",
"type": "Microsoft.Sql/servers/firewallRules"
}
단일 데이터베이스 생성
az sql db create \ |
zerobig_devops@Azure:~$ az sql db create \
> --resource-group $resourceGroupName \
> --server $serverName \
> --name nerddlinnerdb \
> --sample-name AdventureWorksLT \
> --edition GeneralPurpose \
> --compute-model Serverless \
> --family Gen5 \
> --capacity 2
{- Finished ..
"autoPauseDelay": 60,
"backupStorageRedundancy": "Geo",
"catalogCollation": "SQL_Latin1_General_CP1_CI_AS",
"collation": "SQL_Latin1_General_CP1_CI_AS",
"createMode": null,
"creationDate": "2020-12-12T01:50:02.643000+00:00",
"currentServiceObjectiveName": "GP_S_Gen5_2",
"currentSku": {
"capacity": 2,
"family": "Gen5",
"name": "GP_S_Gen5",
"size": null,
"tier": "GeneralPurpose"
},
"databaseId": "e6869516-d8ab-40ce-9bdc-11672cc67b09",
"defaultSecondaryLocation": "koreasouth",
"earliestRestoreDate": "2020-12-12T02:20:02.643000+00:00",
"edition": "GeneralPurpose",
"elasticPoolId": null,
"elasticPoolName": null,
"failoverGroupId": null,
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/azdo-ho-rg/providers/Microsoft.Sql/servers/server-19497/databases/nerddlinnerdb",
"kind": "v12.0,user,vcore,serverless",
"licenseType": null,
"location": "koreacentral",
"longTermRetentionBackupResourceId": null,
"managedBy": null,
"maxLogSizeBytes": 10307921510,
"maxSizeBytes": 34359738368,
"minCapacity": 0.5,
"name": "nerddlinnerdb",
"pausedDate": null,
"readReplicaCount": 0,
"readScale": "Disabled",
"recoverableDatabaseId": null,
"recoveryServicesRecoveryPointId": null,
"requestedServiceObjectiveName": "GP_S_Gen5_2",
"resourceGroup": "azdo-ho-rg",
"restorableDroppedDatabaseId": null,
"restorePointInTime": null,
"resumedDate": null,
"sampleName": null,
"sku": {
"capacity": 2,
"family": "Gen5",
"name": "GP_S_Gen5",
"size": null,
"tier": "GeneralPurpose"
},
"sourceDatabaseDeletionDate": null,
"sourceDatabaseId": null,
"status": "Online",
"tags": null,
"type": "Microsoft.Sql/servers/databases",
"zoneRedundant": false
}
2. SQL 데이터베이스가 Azure에서 프로비저닝되면 Visual Studio에서 SQL Server Object Explorer를 연다. Add Server 아이콘을 클릭하고 이전 단계에서 배포한 Azure SQL 서버에 연결한다.
3. 스키마를 LocalDB에서 새 SQL Azure 인스턴스로 이동하려면 LocalDB 인스턴스를 마우스 오른쪽 단추로 클릭하고 스키마 비교 옵션을 선택한다.
스키마 비교 마법사에서 대상을 Azure SQL 데이터베이스로 선택하고 Compare를 클릭한다.
(Delete를 Exclude 처리하고) 다음 마법사에서 Update를 클릭하여 스키마를 Azure SQL 데이터베이스로 업데이트한다.
4. 마찬가지로 LocalDB에서 SQL Azure 인스턴스로 데이터를 이동하여 LocalDB 인스턴스를 마우스 오른쪽 단추로 클릭하고 Data Comparison을 선택하고 SQL 데이터 비교 마법사를 안내한다.
마법사에서 대상을 Azure SQL 데이터베이스로 선택하고 비교를 클릭한다.
Update Target을 클릭하여 데이터를 Azure SQL 데이터베이스로 이동한다.
5. zero code change mantra를 달성하려면 web.config 변환을 사용하는 것이 가장 좋은 방법이다. 여기에서 새 항목이 있는 새 web.release.config를 추가한다. Visual Studio에서 web.release.config를 열고 아래 항목을 추가한다.
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=nerddinnerlabsql.database.windows.net;Initial Catalog=nerddinnerlab;Integrated Security=False;User ID=yourUserID;Password=yourdbpassword;Connect Timeout=30;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> </connectionStrings> |
참고 : 연결 문자열을 Azure SQL 데이터베이스 연결 문자열로 바꾼다.
이제 애플리케이션 LocalDB를 Azure SQL Db로 성공적으로 마이그레이션하고 Azure SQL을 참조하도록 연결 문자열도 업데이트했다.
실습 2: Docker 지원 추가 및 Visual Studio를 사용하여 Docker 컨테이너 내에서 로컬로 애플리케이션 디버그
1. Visual Studio는 Docker를 크게 지원한다. Docker를 사용하여 애플리케이션을 컨테이너화하려면 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 Add->Container Orchestrator Support를 선택하기 만하면 된다.
2. 그런 다음 Visual Studio는 Docker 파일을 추가하고 파일 및 특정 Docker 프로젝트를 솔루션에 구성한다. 또한 프로젝트를 검사하여 프로젝트에 사용할 적절한 기본 이미지를 결정한다.
그런 다음 Visual Studio는 Docker 파일을 추가하고 파일 및 특정 Docker 프로젝트를 솔루션에 구성한다. 또한 프로젝트를 검사하여 프로젝트에 사용할 적절한 기본 이미지를 결정한다.
Nerd Dinner의 경우 microsoft / aspnet : 4.7.1-windowsservercore-ltsc2016을 사용하도록 선택했다. 여기에 완전한 파일이 있다.
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
ARG source
WORKDIR /inetpub/wwwroot .
3. 애플리케이션을 로컬로 실행하고 Visual Studio를 사용하여 Docker 컨테이너 내에서 디버그하고 SQL Azure 인스턴스에 대한 연결을 테스트하려면 docker-compose를 시작 프로젝트로 설정하고 Docker Compose를 클릭한다.
Visual Studio는 기본 이미지를 다운로드 한 후 dev 이미지를 빌드한다.
(초기 빌드 시 이미지를 내려 받고 빌드하는데 상당 시간 소요된다.)
이미지가 다운로드되고 빌드가 완료되면 로컬 브라우저에서 애플리케이션이 시작되는 것을 볼 수 있다.
이제 애플리케이션이 로컬 도커에서 실행된다. Docker 이미지 목록을 보려면 다음 명령을 실행할 수 있다.
docker images docker ps |
이와 유사한 이미지가 표시된다.
PS C:\Users\zerobig> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nerddinner dev 647d30db7b39 26 hours ago 8.42GB
mcr.microsoft.com/dotnet/framework/aspnet 4.8-windowsservercore-ltsc2019 ddb56529f4ef 3 days ago 8.42GB
PS C:\Users\zerobig> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ec84ec31e44 nerddinner:dev "cmd /c 'start /B C:…" 14 minutes ago Up About a minute 0.0.0.0:61672->80/tcp NerdDinner
정상적으로 실행되지만 다음과 같은 오류가 발생한다. 본 실습 진행 상 문제가 없으므로 무시한다.
주의 : 지금 바로 2편으로 이어 실습을 하지 않는 경우라면, 위에서 생성한 Database 등의 리소스를 제거하여 과금 발생에 주의한다.
2편에서 계속
'Azure와 함께 하는 DevOps' 카테고리의 다른 글
64. Azure 파이프라인의 Selenium 테스트 자동화 (0) | 2020.12.28 |
---|---|
63. 기존 .NET 앱을 Windows 컨테이너로 배포 (.NET 앱 현대화) 2편 (2) | 2020.12.21 |
61. Eclipse와 Azure Repos 및 Azure Pipelines 통합하기 (추가편) (0) | 2020.12.07 |
60. Eclipse와 Azure Repos 및 Azure Pipelines 통합하기 2편 (0) | 2020.11.30 |
59. Eclipse와 Azure Repos 및 Azure Pipelines 통합하기 1편 (0) | 2020.11.23 |