1. 서비스 개요
1.1 Azure Container Instances
컨테이너는 클라우드 애플리케이션을 패키지, 배포 및 관리하기 위한 기본 방법으로 도입되고 있습니다. Azure Container Instances는 어떠한 가상 머신도 관리하지 않고 또 더 높은 수준의 서비스를 채택하지 않고도 Azure에서 컨테이너를 실행하는 가장 빠르고 간단한 방법을 제공합니다.
Azure Container Instances는 VM을 프로비전 및 관리할 필요 없이 Azure에서 몇 초 안에 컨테이너를 시작할 수 있습니다.
Azure Container Instances는 간단한 애플리케이션, 작업 자동화 및 빌드 작업 등 격리된 컨테이너에서 작동할 수 있는 모든 시나리오에 적합한 솔루션입니다. 여러 컨테이너 간 서비스 검색, 자동 크기 조정 및 조정된 애플리케이션 업그레이드를 포함하여 전체 컨테이너 오케스트레이션이 필요한 시나리오에는 AKS(Azure Kubernetes Service)를 사용하는 것이 좋습니다. 컨테이너 인스턴스를 배포할 때 모범 사례를 이해하려면 고려 사항 및 제한 사항과 FAQ를 읽어보는 것이 좋습니다.
주요 기능
Container 액세스 : IP 주소 및 FQDN(정규화된 도메인 이름)을 사용하여 컨테이너 그룹을 인터넷에 직접 노출할 수 있습니다. 컨테이너 인스턴스를 만들 때 사용자 지정 DNS 이름 레이블을 지정할 수 있습니다. customlabel.azureregion.azurecontainer.io
Custom 사이즈 : CPU 코어 및 메모리의 정확한 사양을 허용하여 최적의 활용도를 제공합니다. 필요한 만큼 비용을 초 단위로 지불하므로 실제로 필요한 양에 따라 지출을 미세하게 조정할 수 있습니다.
Persistent 스토리지 : Azure Files 공유를 직접 탑재하는 기능을 제공합니다.
Linux 및 Windows 컨테이너 : Windows의 경우 볼륨 탑재 및 GPU 리소스 등에 대한 제약 존재
Virtual network 배포 : Azure Container Instances를 사용하면 컨테이너 인스턴스를 Azure 가상 네트워크에 배포할 수 있습니다. 가상 네트워크 내의 서브넷에 배포되는 경우 컨테이너 인스턴스는 온-프레미스(VPN Gateway 또는 ExpressRoute를 통해)를 포함하여 가상 네트워크의 다른 리소스와 안전하게 통신할 수 있습니다.
스폿 컨테이너 배포 : 일반 우선 순위 ACI 컨테이너에 비해 최대 70% 할인된 가격으로 사용하지 않는 Azure 용량에서 중단 가능한 컨테이너화된 워크로드를 실행할 수 있습니다. ACI 스폿 컨테이너는 Azure에서 잉여 용량 부족이 발생할 때 선점될 수 있으며 엄격한 가용성 요구 사항이 없는 워크로드에 적합합니다.
1.2 Web App for Container
Azure App Service를 사용하면 인프라를 관리할 필요 없이 선택한 프로그래밍 언어로 웹앱, 모바일 백 엔드 및 RESTful API를 빌드하고 호스트할 수 있습니다. 여기서는 자동 크기 조정 및 고가용성을 제공하고, Windows 및 Linux를 모두 지원하며, GitHub, Azure DevOps 또는 Git 리포지토리에서 자동화된 배포를 사용합니다.
Azure App Service는 Docker 컨테이너 기술을 사용하여 기본 제공 이미지와 사용자 지정 이미지를 모두 호스팅합니다.
Azure App Service on Linux는 .NET, PHP, Node.js 등과 같은 언어 지원을 통해 Linux에서 미리 정의된 애플리케이션 스택을 제공합니다. Docker 컨테이너 기술을 사용하여 기본 제공 이미지와 사용자 지정 이미지를 모두 호스팅합니다.
주요 기능 (Web App)
여러 언어 및 프레임워크 - App Service는http://ASP.NET , http://ASP.NET Core, Java, Node.js, PHP 또는 Python에 대한 최고 수준의 지원을 제공합니다. PowerShell 및 기타 스크립트 또는 실행 파일을 백그라운드 서비스로 실행할 수도 있습니다.
관리되는 프로덕션 환경 - App Service는 OS 및 언어 프레임워크를 자동으로 패치하고 유지 관리합니다.
컨테이너화 및 Docker - 앱을 Docker화하고 App Service에서 사용자 지정 Windows 또는 Linux 컨테이너를 호스팅합니다. Docker Compose를 사용하여 다중 컨테이너 앱을 실행하세요. Docker 기술을 App Service로 직접 마이그레이션하세요.
DevOps 최적화 - Azure DevOps, GitHub, BitBucket, Docker Hub 또는 Azure Container Registry를 사용하여 지속적인 통합 및 배포를 설정합니다. 테스트 및 스테이징 환경을 통해 업데이트를 승격합니다.
고가용성을 갖춘 글로벌 확장 - 수동 또는 자동으로 확장 또는 확장합니다. Microsoft의 글로벌 데이터 센터 인프라 어디에서나 앱을 호스팅하세요. App Service SLA는 고가용성을 보장합니다.
SaaS 플랫폼 및 온-프레미스 데이터에 대한 커넥트 - 엔터프라이즈 시스템(예: SAP), SaaS 서비스(예: Salesforce), 인터넷 서비스(예: Facebook)를 위한 수백 개의 커넥터 중에서 선택하세요. 하이브리드 연결 및 Azure 가상 네트워크를 사용하여 온-프레미스 데이터에 액세스합니다.
보안 및 규정 준수 - App Service는 ISO, SOC 및 PCI 규격을 준수합니다. IP 주소 제한 및 관리형 서비스 ID를 만듭니다. 하위 도메인 인수를 방지합니다.
인증 - 내장된 인증 구성 요소를 사용하여 사용자를 인증합니다. Microsoft Entra ID, Google, Facebook, Twitter 또는 Microsoft 계정으로 사용자를 인증합니다.
애플리케이션 템플릿 - WordPress, Joomla, Drupal 등 Azure Marketplace의 광범위한 애플리케이션 템플릿 목록에서 선택하세요.
Visual Studio와 Visual Studio Code 통합 - Visual Studio 및 Visual Studio Code의 전용 도구는 생성, 배포, 디버깅 작업을 간소화합니다.
Java 도구 통합 - Maven, Gradle, Visual Studio Code, IntelliJ, Eclipse와 같은 선호하는 개발 도구를 남기지 않고 Azure에 개발하고 배포합니다.
API 및 모바일 기능 - App Service는 RESTful API 시나리오에 대한 턴키 CORS 지원을 제공하고 인증, 오프라인 데이터 동기화, 푸시 알림 등을 사용하도록 설정하여 모바일 앱 시나리오를 간소화합니다.
서버리스 코드 - 인프라를 명시적으로 프로비전하거나 관리할 필요 없이 주문형 코드 조각 또는 스크립트를 실행하고 코드가 실제로 사용하는 컴퓨팅 시간에 대해서만 비용을 지불합니다(Azure Functions 참조).
1.3 Azure Container Apps
Azure Container Apps는 복잡한 인프라를 오케스트레이션하지 않고 코드 또는 컨테이너에서 앱을 배포하는 데 도움이 되는 완전 관리형 Kubernetes 기반 애플리케이션 플랫폼입니다. 생산성을 높이기 위해 통합된 중앙 집중식 네트워킹, 통합 가시성, 동적 확장 및 구성을 사용하여 이기종 최신 앱 또는 마이크로서비스를 빌드하세요. Dapr을 완벽하게 지원하는 탄력적인 마이크로서비스와 KEDA 기반의 동적 확장을 통해 탄력적인 마이크로서비스를 설계합니다.
기능
Azure Container Apps를 사용하여 다음을 수행할 수 있습니다.
다른 Azure 인프라를 관리할 필요 없이 HTTPS 또는 TCP 인그레스를 사용하도록 설정합니다.
Dapr 을 사용하여 마이크로 서비스를 빌드하고 풍부한 API 집합에 액세스합니다.
주문형, 일정 또는 이벤트에 따라 작업을 실행합니다.
여러 컨테이너 버전을 실행하고 컨테이너 앱의 애플리케이션 수명 주기를 관리합니다.
KEDA 지원 확장 트리거를 기반으로 앱을 자동 스케일링합니다. 대부분의 애플리케이션은 01까지 확장할 수 있습니다. → 1CPU 또는 메모리 부하에 따라 확장되는 애플리케이션은 0으로 확장할 수 없습니다.
Blue/Green 배포 및 A/B 테스트 시나리오를 위해 애플리케이션의 여러 버전에 걸쳐 트래픽을 분할합니다.
DNS 기반 서비스 검색이 내장된 안전한 내부 전용 엔드포인트를 위해 내부 인그레스 및 서비스 검색을 사용합니다.
Docker Hub 및 ACR(Azure Container Registry)을 포함하여 퍼블릭 또는 프라이빗에 해당하는 모든 레지스트리에서 컨테이너를 실행합니다.
애플리케이션에서 직접 비밀을 안전하게 관리합니다.
Azure Log Analytics를 사용하여 로그를 모니터링합니다.
2. 서비스 배포
2.1 소스 준비하기
일감을 처리하가 위해서는 로컬 작업 환경에 다음의 전제 조건이 충족되어야 한다.
먼저 https://github.com/zer0big/gs-spring-boot-aks.git 로부터 Fork를 수행하여 자신의 리포지토리를 기준으로 작업을 진행한다.
자신의 리포지토리 우측 상단의 Code를 클릭하여 복제할 HTTPS 주소를 복사한다.
git clone 하여 샘플 소스를 다운 받고 소스 디렉토리로 이동한다.
VS Code가 설치 된 경우 code 명령을 수행하여 소스 코드 내용을 살펴본다.
git clone https://github.com/zer0big/gs-spring-boot-aks.git cd gs-spring-boot-aks code . |
2.2 App 빌드 및 검증하기
별도의 bash 창에서 mvn clean package 명령으로 컴파일을 수행하고 컴파일 한다. 참고로 clean 옵션은 maven build 시 생성된 모든 것들을 삭제한다.
mvn clean package -DskipTests |
appmod-demo# mvn clean package -DskipTests WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/usr/share/maven/lib/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release [INFO] Scanning for projects... [INFO] [INFO] -------------< org.springframework:gs-spring-boot-docker >-------------- [INFO] Building Spring Boot Docker 0.1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ gs-spring-boot-docker --- [INFO] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ gs-spring-boot-docker --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ gs-spring-boot-docker --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /mnt/c/Users/youngdae.kim/gs-spring-boot-aks/target/classes [INFO] [INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ gs-spring-boot-docker --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /mnt/c/Users/youngdae.kim/gs-spring-boot-aks/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ gs-spring-boot-docker --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /mnt/c/Users/youngdae.kim/gs-spring-boot-aks/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ gs-spring-boot-docker --- [INFO] Tests are skipped. [INFO] [INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ gs-spring-boot-docker --- [INFO] Building jar: /mnt/c/Users/youngdae.kim/gs-spring-boot-aks/target/gs-spring-boot-docker-0.1.0.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.3.0.RELEASE:repackage (repackage) @ gs-spring-boot-docker --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.557 s [INFO] Finished at: 2022-04-19T15:00:31+09:00 [INFO] ------------------------------------------------------------------------ appmod-demo# |
target 디렉토리 생성을 확인하고 해당 디렉토리로 이동하여 gs-spring-boot-docker-0.1.0.jar 파일 생성을 확인한다.
cd target ls -rlth |
appmod-demo# appmod-demo# ls -rlht total 44K -rwxrwxrwx 1 zerobig zerobig 131 Apr 19 14:53 Dockerfile -rwxrwxrwx 1 zerobig zerobig 378 Apr 19 14:53 README.md -rwxrwxrwx 1 zerobig zerobig 1.1K Apr 19 14:53 azure-pipelines.yml -rwxrwxrwx 1 zerobig zerobig 771 Apr 19 14:53 build.gradle drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 14:53 gradle -rwxrwxrwx 1 zerobig zerobig 5.9K Apr 19 14:53 gradlew -rwxrwxrwx 1 zerobig zerobig 3.0K Apr 19 14:53 gradlew.bat drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 14:53 k8s -rwxrwxrwx 1 zerobig zerobig 11K Apr 19 14:53 mvnw -rwxrwxrwx 1 zerobig zerobig 6.7K Apr 19 14:53 mvnw.cmd -rwxrwxrwx 1 zerobig zerobig 1.6K Apr 19 14:53 pom.xml drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 14:53 src drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 2022 target appmod-demo# appmod-demo# cd target/ appmod-demo# ls -rlht total 16M drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 generated-sources drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 maven-status drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 classes drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 generated-test-sources drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 test-classes drwxrwxrwx 1 zerobig zerobig 4.0K Apr 19 15:00 maven-archiver -rwxrwxrwx 1 zerobig zerobig 2.9K Apr 19 15:00 gs-spring-boot-docker-0.1.0.jar.original -rwxrwxrwx 1 zerobig zerobig 16M Apr 19 15:00 gs-spring-boot-docker-0.1.0.jar appmod-demo# |
java -jar 명령을 통해 로컬에서 샘플 소스의 유효성을 검증한다.
java -jar gs-spring-boot-docker-0.1.0.jar |
appmod-demo# java -jar gs-spring-boot-docker-0.1.0.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.0.RELEASE) 2022-04-19 15:03:21.292 INFO 586 --- [ main] hello.Application : Starting Application v0.1.0 on youngdae_kim with PID 586 (/mnt/c/Users/youngdae.kim/gs-spring-boot-aks/target/gs-spring-boot-docker-0.1.0.jar started by zerobig in /mnt/c/Users/youngdae.kim/gs-spring-boot-aks/target) 2022-04-19 15:03:21.298 INFO 586 --- [ main] hello.Application : No active profile set, falling back to default profiles: default 2022-04-19 15:03:25.029 INFO 586 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-04-19 15:03:25.058 INFO 586 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-04-19 15:03:25.058 INFO 586 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.35] 2022-04-19 15:03:25.300 INFO 586 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-04-19 15:03:25.300 INFO 586 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3826 ms 2022-04-19 15:03:25.937 INFO 586 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2022-04-19 15:03:26.547 INFO 586 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-04-19 15:03:26.574 INFO 586 --- [ main] hello.Application : Started Application in 6.957 seconds (JVM running for 7.842) |
별도의 Windows 터미널 탭을 띄워서 다음 명령을 실행한다.
start http://localhost:8080 |
팝업 된 웹 브라우저에서 실행 결과를 확인한다.
결과 확인 후 Ctrl + C를 눌러 실행된 자바 프로세스를 종료한다.
다음 명령을 시행하여 gs-spring-boot-aks 디렉토리로 이동한다.
cd .. |
2.3 Docker Build 및 검증하기
Azure Container Registry 생성
다음 명령을 수행하여 ACR을 생성하고 결과를 확인한다.
# AZ Login az login # 변수 선언 //ACR_NAME은 각자 고유한 이름으로 할당 ACR_NAME=zerobigacrdemo RESOURCE_GROUP=RG-Demo4TDG-CICD REGION_NAME=koreacentral # Resource Group 생성 az group create \ --resource-group $RESOURCE_GROUP \ --location $REGION_NAME # ACR 생성 az acr create \ --resource-group $RESOURCE_GROUP \ --location $REGION_NAME \ --name $ACR_NAME \ --sku Standard # 생성 결과 확인 az acr list -o table |
Docker Build
다시 gs-spring-boot-aks 디렉토리로 이동하여 샘플 소스 내 준비된 Dockerfile 내용을 검토한다.
FROM openjdk:8-jdk-alpine EXPOSE 8080 ARG JAR_FILE=target/*.jar ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] |
docker build 명령을 수행하여 docker images를 생성한다.
docker build -t appmod-demo4tdg-cicd . docker images |
appmod-demo# docker build -t appmod-demo4tdg-cicd "docker build" requires exactly 1 argument. See 'docker build --help'. Usage: docker build [OPTIONS] PATH | URL | - Build an image from a Dockerfile appmod-demo# appmod-demo# appmod-demo# docker build -t appmod-demo4tdg-cicd . [+] Building 16.1s (8/8) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 176B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/openjdk:8-jdk-alpine 15.7s => [auth] library/openjdk:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.2s => => transferring context: 16.47MB 0.2s => CACHED [1/2] FROM docker.io/library/openjdk:8-jdk-alpine@sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f 0.0s => [2/2] ADD target/*.jar app.jar 0.1s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:6f8522b00ab4dd75e013983d972f5dd84cfab2d32bc085d0109e304eaea2178f 0.0s => => naming to docker.io/library/appmod-demo4tdg-cicd 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them appmod-demo# appmod-demo# docker images REPOSITORY TAG IMAGE ID CREATED SIZE appmod-demo4tdg-cicd latest 6f8522b00ab4 32 seconds ago 121MB eerkunt/terraform-compliance latest 51f9a525daa5 3 weeks ago 349MB appmod-demo# |
docker run 명령을 수행하여 로컬에서 동작 유효성을 검증한다.
appmod-demo# docker run -d -p 8888:8080 appmod-demo4tdg-cicd 72f76c1112c0a1a4b4e52a051d6dcf5cf542d34ffea7c52580b6ccd1ad0e2be7 appmod-demo# |
로컬 브라우저를 통해 결과를 검증한다.(전시되는 메시지 내용을 상이할 수 있다.)
2.4 이미지 ACR로 푸시하기
Docker Tag
docker tag, push 명령을 수행하여 생성한 ACR에 images를 Push한다.
az acr login -n $ACR_NAME docker tag appmod-demo4tdg-cicd $ACR_NAME.azurecr.io/appmod-demo4tdg-cicd docker push $ACR_NAME.azurecr.io/appmod-demo4tdg-cicd |
appmod-demo# docker tag appmod-demo4tdg-cicd zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd appmod-demo# appmod-demo# docker images REPOSITORY TAG IMAGE ID CREATED SIZE appmod-demo4tdg-cicd latest 6f8522b00ab4 23 minutes ago 121MB zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd latest 6f8522b00ab4 23 minutes ago 121MB eerkunt/terraform-compliance latest 51f9a525daa5 3 weeks ago 349MB appmod-demo# appmod-demo# docker push zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd Using default tag: latest The push refers to repository [zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd] ebc99b57ef7e: Preparing ceaf9e1ebef5: Preparing 9b9b7f3d56a0: Preparing f1b5933fe4b5: Preparing unauthorized: authentication required, visit https://aka.ms/acr/authorization for more information. appmod-demo# |
인증/인가 에러가 발생한다. az acr login 명령을 수행하여 인증을 득하고 다시 명령을 수행한다.
az acr login -n zeroacrdemo docker push zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd |
appmod-demo# az acr login -n $ACR_NAME Login Succeeded appmod-demo# docker push zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd Using default tag: latest The push refers to repository [zeroacrdemo.azurecr.io/appmod-demo4tdg-cicd] ebc99b57ef7e: Pushed ceaf9e1ebef5: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed latest: digest: sha256:2aca8d1526c48874d3eb61bae6ec758d1a5fc8fa9babd195def9fc3180fe17fb size: 1159 appmod-demo# |
Azure 포털의 리포지토리로 이동하여 결과를 확인한다.
2.5 AKS 클러스터 배포하기
다음 명령을 수행하여 AKS를 생성한다.
# 변수 선언 //AKS_NAME은 각자 고유한 이름으로 할당 AKS_CLUSTER_NAME=zerobigaksdemo RESOURCE_GROUP=RG-Demo4TDG-CICD REGION_NAME=koreacentral VNET_NAME=aks-vnet SUBNET_NAME=aks-subnet # VNET 생성 az network vnet create \ --resource-group $RESOURCE_GROUP \ --location $REGION_NAME \ --name $VNET_NAME \ --address-prefixes 10.0.0.0/8 \ --subnet-name $SUBNET_NAME \ --subnet-prefixes 10.240.0.0/16 # SUBNET 생성 SUBNET_ID=$(az network vnet subnet show \ --resource-group $RESOURCE_GROUP \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --query id -o tsv) # AKS 생성 (약 3분 소요) az aks create \ --resource-group $RESOURCE_GROUP \ --name $AKS_CLUSTER_NAME \ --vm-set-type VirtualMachineScaleSets \ --node-count 2 \ --load-balancer-sku standard \ --location $REGION_NAME \ --network-plugin azure \ --vnet-subnet-id $SUBNET_ID \ --service-cidr 10.2.0.0/24 \ --dns-service-ip 10.2.0.10 \ --docker-bridge-address 172.17.0.1/16 \ --enable-managed-identity \ --generate-ssh-keys # AKS 자격증명 획득 az aks get-credentials \ --resource-group $RESOURCE_GROUP \ --name $AKS_CLUSTER_NAME # AKS 노드 정보 확인 kubectl get node |
appmod-demo# kubectl get node NAME STATUS ROLES AGE VERSION aks-nodepool1-18801987-vmss000000 Ready agent 75s v1.22.6 aks-nodepool1-18801987-vmss000001 Ready agent 69s v1.22.6 |
2.6 AKS-ACR 통합하기
다음 명령을 수행하여 AKS-ACR을 통합한다.
# ACR - AKS 통합 az aks update -n $AKS_CLUSTER_NAME -g $RESOURCE_GROUP --attach-acr $ACR_NAME |
appmod-demo# az aks update -n $AKS_CLUSTER_NAME -g $RESOURCE_GROUP --attach-acr $ACR_NAME AAD role propagation done[############################################] 100.0000%{ "aadProfile": null, "addonProfiles": null, "agentPoolProfiles": [ { "availabilityZones": null, "count": 2, <중략> "tags": null, "type": "Microsoft.ContainerService/ManagedClusters", "windowsProfile": { "adminPassword": null, "adminUsername": "azureuser", "enableCsiProxy": true, "licenseType": null } } appmod-demo# |
이제 "로컬 환경 작업" Issue는 Done으로 이동시키고 "Azure Resource 작업"을 Doing으로 이동시키고 자신에게 Issue를 할당한다.
2.7 Modern App 샘플 준비하기
Repos 화면으로 이동하여 Import를 클릭한다.
자신의 git 리포지토리의 git clone URL을 복사하여 붙여 넣고 Import를 클릭한다.
성공하면 다음의 메시지가 전시된다.
성공적으로 Import한 결과는 다음과 같다.
복제한 리포지토리 내 k8s - deploy-svc.yaml 파일을 열어 각자의 상황에 맞게 이미지 관련 정보 업데이트 후 커밋을 시행한다.
2.8 서비스 커넥션 구성하기
AKS, ACR 등에 대한 서비스 커넥션을 구성하기 위해서는 해당 Azure 리소스에 대하여 적절한 권한이 부여되어야 한다. 본 튜토리얼에서는 이미 권한이 할당되어 있는 것으로 간주한다. 관련한 자세한 내용은 서비스 커넥션 관리 를 참조한다. |
좌측 하단의 Project Settings > Pipelines > Service Connections 를 선택하고 다음 Create service connection을 클릭한다.
docker 라고 키워드를 입력하여 검새 결과 중 Docker Registry를 선택하고 Next를 클릭한다.
다음의 순서에 따라 구성하고 Save를 클릭 한다.
Registry type : Azure Container Registry 선택
Subscription : 해당 구독 선택
Azure container registry : 생성 ACR 선택
Service connection name : SvcConn4Acr 입력
Grant access permission to all pipeliness 선택
우측 상단의 New service connection을 선택한다.
kuber라고 키워드를 입력하여 검새 결과 중 Kubernetes를 선택하고 Next를 클릭한다.
다음의 순서에 따라 구성하고 Save를 클릭 한다.
Registry type : Azure Container Registry 선택
Subscription : 해당 구독 선택
Azure container registry : 생성 ACR 선택
Service connection name : SvcConn4Acr 입력
Grant access permission to all pipeliness 선택
구성이 모두 완료된 결과는 다음과 같다.
2.9 CI 파이프라인 구성하기
Pipelines > Pipelines에서 Create pipeline을 선택한다.
Connect 탭 화면에서 Azure Repos Git를 선택한다.
Select 탭 화면에서 2023_TDG_AKS_CICD_Demo를 선택한다.
기본 구성해 둔 azure-pipelines.yml 이 자동으로 로딩 된다.
만약 자동으로 로딩이 되지 않으면 기본 제공되는 파일 내용을 삭제 하고 다음 내용을 복사하여 붙여 넣는다.
# Maven # Build your Java project and run tests with Apache Maven. # Add steps that analyze code, save build artifacts, deploy, and more: # https://docs.microsoft.com/azure/devops/pipelines/languages/java trigger: - main steps: - task: Maven@3 displayName: 'Maven Build' - task: Docker@2 displayName: 'Docker Build' inputs: containerRegistry: 'SvcConn4Acr' repository: 'appmod-demo4btc' command: 'buildAndPush' Dockerfile: 'Dockerfile' tags: | $(Build.BuildId) latest - task: Docker@2 displayName: 'Docker Push' inputs: containerRegistry: 'SvcConn4Acr' repository: 'appmod-demo4btc' command: 'buildAndPush' Dockerfile: 'Dockerfile' tags: | $(Build.BuildId) latest - task: Bash@3 displayName: 'Tag Update' inputs: targetType: 'inline' script: 'sed -i "s/latest/$(Build.BuildId)/g" k8s/deploy-svc.yaml' - task: PublishBuildArtifacts@1 displayName: 'Build Artifact Publish' inputs: PathtoPublish: 'k8s/deploy-svc.yaml' ArtifactName: 'drop' publishLocation: 'Container' |
서비스 커넥션 정보 및 리포지토리 정보를 각자 상황에 맞게 선택/입력 및 업데이트 하고 Save 한다.
Azure 파이프라인 관련 상세 내용 : Azure CI/CD Pipeline 구축 가이드 참조 |
CI 파이프라인 설명Triggermain 브랜치의 코드 변경이 감지되면 CI 파이프라인이 트리거 된다. trigger: - main Maven 빌드Maven을 통해 애플리케이션을 빌드 한다. steps: - task: Maven@3 displayName: 'Maven Build' Docker 빌드, 태그 및 푸시Maven 빌드의 결과물로(war 또는 jar) Docker 이미지를 빌드, 태그하여 ACR로 푸시를 수행한다. - task: Docker@2 displayName: 'Docker Build' inputs: containerRegistry: 'SvcConn4Acr' repository: 'appmod-demo4btc' command: 'buildAndPush' Dockerfile: 'Dockerfile' tags: | $(Build.BuildId) latest - task: Docker@2 displayName: 'Docker Push' inputs: containerRegistry: 'SvcConn4Acr' repository: 'appmod-demo4btc' command: 'buildAndPush' Dockerfile: 'Dockerfile' tags: | $(Build.BuildId) latest YAML 파일 태그 정보 업데이트Kubernetes 배포를 위한 YAML 파일 내 이미지 태그를 최신 빌드 번호로 업데이트 한다. - task: Bash@3 displayName: 'Tag Update' inputs: targetType: 'inline' script: 'sed -i "s/latest/$(Build.BuildId)/g" k8s/deploy-svc.yaml' 빌드 Artifact 게시빌드 산출물인 YAML 파일을 drop 디렉토리에 위치 시킨다. - task: PublishBuildArtifacts@1 displayName: 'Build Artifact Publish' inputs: PathtoPublish: 'k8s/deploy-svc.yaml' ArtifactName: 'drop' publishLocation: 'Container' |
소스의 k8s/deploy-svc.yaml로 이동하여 Edit을 선택하고 image 정보 부분을 각자의 상황에 맞게 수정 후 Commit을 클릭한다.
apiVersion: apps/v1 kind: Deployment metadata: name: zerobigaksdemo spec: replicas: 1 selector: matchLabels: app: zero-aks-app template: metadata: labels: app: zero-aks-app spec: containers: - name: zero-aks-demo image: zeroacrdemo.azurecr.io/appmod-demo4btc:latest //자신의 ACR 정보로 업데이트 한다. ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: zero-aks-app spec: ports: - name: http-port port: 80 targetPort: 8080 selector: app: zero-aks-app type: LoadBalancer |
우측 상단의 Save and run을 클릭한다.
Commit 메시지를 입력하고 Commit을 클릭한다.
CI 파이프라인을 최초 실행하는 경우에는 다음과 같이 리소스 접근에 대한 퍼미션 Confirm을 요구할수도 있다. Permit을 클릭하여 파이프라인을 실행한다. |
파이프라인 실행결과를 확인하고 정상이면 1 artifact를 클릭하여 빌드 결과물을 확인한다.
deploy-svc.yaml 파일에 Image 정보를 확인하여, ACR에 푸시된 최근 이미지 정보가 맞는지 확인한다.
더불어 Azure 포털의 ACR 리포지토리로 이동하여 빌드 이미지의 푸시 여부를 확인한다.
2.10 CD 파이프라인 구성하기
Pipelines > Releases에서 New pipeline을 선택한다.
Kubernetes 키워드를 입력 후 결과 중 Deploy to a Kubernetes cluster를 선택하여 Apply 한다.
Stage 이름을 입력하고 (ex) DEV) 우측 상단에 X를 클릭하여 창을 닫는다.
파이프라인 이름을 적당한 이름으로 변경하고 Pipelines 탭의 Add an artifact 을 선택한다.
Source (build pipeline)에서 소스 CI 파이프라인을 선택 후 Add를 클릭한다.
Stage 이름 아래 1job, 1task를 클릭한다.
kubectl 잡을 선택한다.
다음의 순서에 따라 구성을 진행한다.
Kubernetes service connection : 앞서 구성한 해당 서비스 커넥션을 선택한다.
Namespace : default 를 선택한다.
Command : apply를 선택한다.
Use Configuration files : 체크박스를 선택한다.
Configuration file : ... 버튼을 클릭하여 deploy-svc.yaml 파일의 위치를 찾아 선택한다.
선택 및 입력한 내용을 Save 하고 Create a release를 클릭한다.
파이프라인 실행 결과를 확인한다.
AKS의 Services and ingresses 블레이드에서 External IP를 확인하여 파이프라인의 배포 결과를 브라우저에서 확인한다.
2.11 CI/CD 검증하기
CI/CD를 검증하기 위해서는 각각 트리거 설정이 필요하다.
CI의 경우에는 이미 main 브랜치에 대하여 설정이 되어있다.
CD에 대한 트리거 설정을 위해 Pipelines > Releases에서 우측 상단 Edit을 선택한다.
Artifacts에서 다음 1번을 선택 후 Continuous deployment trigger를 Enabled 신킨 후 우측 상단에 X를 클릭하여 창을 닫는다.
우측 상단에 Save 를 선택하여 설정을 저장한다.
이제 Repos > Files 화면에서 src/main/java/hello/Application.java 파일에서 메시지를 변경하고 Commit을 수행한다.
기존 : Hello, You are ...
변경 : Hi, You are ...
Pipeline 으로 이동하면 CI 파이프라인이 트리거 되어 실행되는 것을 확인할 수 있다.
CI 파이프라인이 정상적으로 종료되면, 바로 CD 파이프라인이 트리거 되어 실행되는 것을 확인할 수 있다.
CD 파이프라인이 성공적으로 종료되면 브라우저를 새로고침하여 실행 및 배포 결과를 확인한다.
이로서 CI/CD 파아프라인이 정상적으로 구성된 것을 확인할 수 있다.
3. Backlog 완료하기
Boards > Boards로 이동하여 Azure DevOps 작업 Issue를 Done으로 이동하고 모든 Backlog를 완료한다.
0 Comments