티스토리 뷰

이번 편에서는 컨테이너라이징을 통한 앱의 현대화 관련된 실습을 시행하고자 한다.

간단한 자바 스프링부트 앱을 컨테이너화 하여 이를 Azure의 컨테이너 서비스인 Azure Container Instances, Web App for Container, Azure Container Apps 그리고 Azure Kubernetes Service를 대상으로 배포하는 내용을 다루고자 한다.

 

참고로 이 실습을 따라 하기 위해서는 지난 Part1, Part2에서 다룬 Azure SA 업무 환경 구성이 필요하다.

 

먼저 Azure 컨테이너 서비스에 대해 간단하게 개요를 살펴보도록 한다.

 

 

 

1. 서비스 개요

<참고> 

Azure Container Instances : https://learn.microsoft.com/ko-kr/azure/container-instances/container-instances-overview?AZ-MVP-5004005
Web App for Container :
https://learn.microsoft.com/ko-kr/azure/app-service/overview?AZ-MVP-5004005
Azure Container Apps :  
https://learn.microsoft.com/ko-kr/azure/container-apps/overview?AZ-MVP-5004005https://learn.microsoft.com/ko-kr/azure/container-apps/overview?AZ-MVP-5004005

 

 

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는 ASP.NET Core | Open-source web framework for .NET , ASP.NET Core | Open-source web framework for .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를 사용하여 다음을 수행할 수 있다.

 

 

2. 배포 준비

 

중지한 VM을 켜고 실습을 준비한다. 이후 작업은 WSL 환경에서 작업이 이루어 진다.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\zerobig> wsl
zerobig@win11vm-sa:/mnt/c/Users/zerobig$

 

 

2.1 소스 준비하기

진행에 앞서 다음 링크를 참조하여 maven을 설치한다.

설치가 정상적으로 이루어 지면 다음과 같은 결과가 확인되어야 한다.

# Maven 버전 확인
mvn -version

# Java 버전 확인
java -version
zerobig@win11vm-sa:/mnt/c/Users/zerobig$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.22, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "5.15.146.1-microsoft-standard-wsl2", arch: "amd64", family: "unix"
zerobig@win11vm-sa:/mnt/c/Users/zerobig$ java -version
openjdk version "11.0.22" 2024-01-16
OpenJDK Runtime Environment (build 11.0.22+7-post-Ubuntu-0ubuntu222.04.1)
OpenJDK 64-Bit Server VM (build 11.0.22+7-post-Ubuntu-0ubuntu222.04.1, mixed mode, sharing)
zerobig@win11vm-sa:/mnt/c/Users/zerobig$

 

 

이제 여기에서 실습에 필요한 코드를 복제한다.

 

git clone 하여 샘플 소스를 다운 받고 소스 디렉토리로 이동한다.

git clone https://github.com/zer0big/gs-spring-boot-aks.git
cd gs-spring-boot-aks

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig$ git clone https://github.com/zer0big/gs-spring-boot-aks.git
Cloning into 'gs-spring-boot-aks'...
remote: Enumerating objects: 418, done.
remote: Counting objects: 100% (26/26), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 418 (delta 6), reused 5 (delta 2), pack-reused 392
Receiving objects: 100% (418/418), 144.74 KiB | 1.98 MiB/s, done.
Resolving deltas: 100% (135/135), done.
zerobig@win11vm-sa:/mnt/c/Users/zerobig$ cd gs-spring-boot-aks/
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$

 

 

 

2.2 App 빌드 및 검증하기

별도의 bash 창에서 mvn clean package 명령으로 컴파일을 수행하고 컴파일 한다. 참고로 clean 옵션은 maven build 시 생성된 모든 것들을 삭제한다.

mvn clean package -DskipTests

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ 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] ------------------------------------------------------------------------
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$

 

 

target 디렉토리 생성을 확인하고 해당 디렉토리로 이동하여 gs-spring-boot-docker-0.1.0.jar 파일 생성을 확인한다.

cd target
ls -rlth

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ cd target/
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks/target$ ls -rlht
total 16M
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 generated-sources
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 maven-status
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 classes
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 generated-test-sources
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 test-classes
drwxrwxrwx 1 zerobig zerobig 4.0K Mar 17 22:52 maven-archiver
-rwxrwxrwx 1 zerobig zerobig 2.8K Mar 17 22:52 gs-spring-boot-docker-0.1.0.jar.original
-rwxrwxrwx 1 zerobig zerobig  16M Mar 17 22:52 gs-spring-boot-docker-0.1.0.jar

 

java -jar 명령을 통해 로컬에서 샘플 소스의 유효성을 검증한다.

java -jar gs-spring-boot-docker-0.1.0.jar

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks/target$ java -jar gs-spring-boot-docker-0.1.0.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.0.RELEASE)

2024-03-17 22:53:21.447  INFO 4723 --- [           main] hello.Application                        : Starting Application v0.1.0 on win11vm-sa with PID 4723 (/mnt/c/Users/zerobig/gs-spring-boot-aks/target/gs-spring-boot-docker-0.1.0.jar started by zerobig in /mnt/c/Users/zerobig/gs-spring-boot-aks/target)
2024-03-17 22:53:21.457  INFO 4723 --- [           main] hello.Application                        : No active profile set, falling back to default profiles: default
2024-03-17 22:53:25.759  INFO 4723 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-03-17 22:53:25.803  INFO 4723 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-03-17 22:53:25.804  INFO 4723 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.35]
2024-03-17 22:53:26.071  INFO 4723 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-03-17 22:53:26.072  INFO 4723 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 4375 ms
2024-03-17 22:53:26.750  INFO 4723 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2024-03-17 22:53:27.375  INFO 4723 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2024-03-17 22:53:27.410  INFO 4723 --- [           main] hello.Application                        : Started Application in 8.601 seconds (JVM running for 9.819)

 

 

별도의 Windows 터미널 탭을 띄워서 다음 명령을 실행한다.

start http://localhost:8080

 

결과 확인 후 Ctrl + C를 눌러 실행된 자바 프로세스를 종료한다.

다음 명령을 시행하여 gs-spring-boot-aks 디렉토리로 이동한다.

cd ..

 

컨테이너 노출 포트 변경 : 8080 --> 80

현재 노출되고 있는 컨테이너의 8080 포트를 80으로 변경하도록 하겠다.
VS Code 및 VI를 이용하여 src - main - resources 이하에 application.yml 파일을 열어 port를 80으로 변경하고 저장한다.

이후 VS Code 창을 닫고 다시 App 빌드를 수행한다.
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ mvn clean package -DskipTests
[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] Deleting /mnt/c/Users/zerobig/gs-spring-boot-aks/target
[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/zerobig/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/zerobig/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/zerobig/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/zerobig/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:  4.307 s
[INFO] Finished at: 2024-03-17T23:02:24Z
[INFO] ------------------------------------------------------------------------
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$​

 

 

 

2.3 Docker Build 및 검증하기

 

Docker Build

다시 gs-spring-boot-aks 디렉토리로 이동하여 샘플 소스 내 준비된 Dockerfile을 열고 EXPOSE 포트 정보를 80으로 변경하고 저장한다.

FROM openjdk:8-jdk-alpine
EXPOSE 80  // 변경 필요
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ vi Dockerfile
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ cat Dockerfile
FROM openjdk:8-jdk-alpine
EXPOSE 80
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

 

이제 Docker를 빌드하고 로컬환경에서 그 결과를 검증한다.

# Docker 빌드
docker build -t appmod-demo-cicd .

# 빌드 결과 확인
docker images

# Docker 실행 
docker run -d -p 8888:80 appmod-demo-cicd

 

 

주의 : WSL에서 docker 명령 실행 시 다음과 같은 에러가 발생한다면, Docker Desktop을 실행하고 다시 시도한다.
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker ps

The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

For details about using Docker Desktop with WSL 2, visit:

https://docs.docker.com/go/wsl2/​

 

 

docker build 명령을 수행하여 docker images를 생성한다.

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker build -t appmod-demo-cicd .
[+] Building 9.4s (7/7) FINISHED                                                                         docker:default
 => [internal] load build definition from Dockerfile                                                               0.1s
 => => transferring dockerfile: 161B                                                                               0.0s
 => [internal] load metadata for docker.io/library/openjdk:8-jdk-alpine                                            2.6s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load build context                                                                                  0.7s
 => => transferring context: 16.47MB                                                                               0.6s
 => [1/2] FROM docker.io/library/openjdk:8-jdk-alpine@sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f  5.1s
 => => resolve docker.io/library/openjdk:8-jdk-alpine@sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f  0.0s
 => => sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f2283343547b3 1.64kB / 1.64kB                     0.0s
 => => sha256:44b3cea369c947527e266275cee85c71a81f20fc5076f6ebb5a13f19015dce71 947B / 947B                         0.0s
 => => sha256:a3562aa0b991a80cfe8172847c8be6dbf6e46340b759c2b782f8b8be45342717 3.40kB / 3.40kB                     0.0s
 => => sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10 2.76MB / 2.76MB                     0.4s
 => => sha256:f910a506b6cb1dbec766725d70356f695ae2bf2bea6224dbe8c7c6ad4f3664a2 238B / 238B                         0.5s
 => => sha256:c2274a1a0e2786ee9101b08f76111f9ab8019e368dce1e325d3c284a0ca33397 70.73MB / 70.73MB                   3.6s
 => => extracting sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10                          0.2s
 => => extracting sha256:f910a506b6cb1dbec766725d70356f695ae2bf2bea6224dbe8c7c6ad4f3664a2                          0.0s
 => => extracting sha256:c2274a1a0e2786ee9101b08f76111f9ab8019e368dce1e325d3c284a0ca33397                          1.1s
 => [2/2] ADD target/*.jar app.jar                                                                                 1.2s
 => exporting to image                                                                                             0.1s
 => => exporting layers                                                                                            0.1s
 => => writing image sha256:4040d182a20db321665dc94c48e45e55d98e081e235903247bb069b2f2b82fa3                       0.0s
 => => naming to docker.io/library/appmod-demo-cicd                                                                0.0s

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
appmod-demo-cicd   latest    4040d182a20d   5 seconds ago   121MB
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker run -d -p 8888:80 appmod-demo-cicd
a615f49020d11d8c2ef943621972dcb9a3ad0d7b17131d5951554ce03b916029
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$

 

 

docker run 실행 후 다음과 같이 팝업이 뜨면 Allow를 선택한다.

 

별도의 Windows 터미널 탭을 띄워서 다음 명령을 실행한다.

start http://localhost:8888

 

 

로컬 브라우저를 통해 결과를 검증한다.

 

 

 

 

2.4 이미지 ACR로 푸시하기

Azure Container Registry 생성

이제 로컬 환경에서 컨테이너에 대한 검증을 완료했으니 이를 Azure Container Registry에 올려보자. 먼저 다음 명령을 수행하여 ACR을 생성하고 결과를 확인한다.

# AZ Login
az login

# 변수 선언
//ACR_NAME은 각자 고유한 이름으로 할당
ACR_NAME=zeroacrdemo2024

RESOURCE_GROUP=RG-Demo-CICD-202403
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
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ ACR_NAME=zeroacrdemo2024
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ RESOURCE_GROUP=RG-Demo-CICD-202403
REGION_NAME=koreacentral
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ az group create \
--resource-group $RESOURCE_GROUP \
--location $REGION_NAME
{
  "id": "/subscriptions/1199b626-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx/resourceGroups/RG-Demo-CICD-202403",
  "location": "koreacentral",
  "managedBy": null,
  "name": "RG-Demo-CICD-202403",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ az acr create \
--resource-group $RESOURCE_GROUP \
--location $REGION_NAME \
--name $ACR_NAME \
--sku Standard
{
  "adminUserEnabled": false,
  "anonymousPullEnabled": false,
  "creationDate": "2024-03-17T23:15:28.256633+00:00",
  "dataEndpointEnabled": false,
  "dataEndpointHostNames": [],
  "encryption": {
    "keyVaultProperties": null,
    "status": "disabled"
  },
  "id": "/subscriptions/1199b626-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx/resourceGroups/RG-Demo-CICD-202403/providers/Microsoft.ContainerRegistry/registries/zeroacrdemo2024",
  "identity": null,
  "location": "koreacentral",
  "loginServer": "zeroacrdemo2024.azurecr.io",
  "name": "zeroacrdemo2024",
  "networkRuleBypassOptions": "AzureServices",
  "networkRuleSet": null,
  "policies": {
    "azureAdAuthenticationAsArmPolicy": {
      "status": "enabled"
    },
    "exportPolicy": {
      "status": "enabled"
    },
    "quarantinePolicy": {
      "status": "disabled"
    },
    "retentionPolicy": {
      "days": 7,
      "lastUpdatedTime": "2024-03-17T23:15:35.675091+00:00",
      "status": "disabled"
    },
    "softDeletePolicy": {
      "lastUpdatedTime": "2024-03-17T23:15:35.675127+00:00",
      "retentionDays": 7,
      "status": "disabled"
    },
    "trustPolicy": {
      "status": "disabled",
      "type": "Notary"
    }
  },
  "privateEndpointConnections": [],
  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "resourceGroup": "RG-Demo-CICD-202403",
  "sku": {
    "name": "Standard",
    "tier": "Standard"
  },
  "status": null,
  "systemData": {
    "createdAt": "2024-03-17T23:15:28.256633+00:00",
    "createdBy": "zerobig.kim@gmail.com",
    "createdByType": "User",
    "lastModifiedAt": "2024-03-17T23:15:28.256633+00:00",
    "lastModifiedBy": "zerobig.kim@gmail.com",
    "lastModifiedByType": "User"
  },
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries",
  "zoneRedundancy": "Disabled"
}
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ az acr list -o table
NAME             RESOURCE GROUP       LOCATION      SKU       LOGIN SERVER                CREATION DATE         ADMIN ENABLED
---------------  -------------------  ------------  --------  --------------------------  --------------------  ---------------
zeroacrdemo2024  RG-Demo-CICD-202403  koreacentral  Standard  zeroacrdemo2024.azurecr.io  2024-03-17T23:15:28Z  False
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$
 
 
 
 
 

Docker Tag

docker tag, push 명령을 수행하여 생성한 ACR에 images를 Push한다.

az acr login -n $ACR_NAME
docker tag appmod-demo-cicd $ACR_NAME.azurecr.io/appmod-demo-cicd
docker push $ACR_NAME.azurecr.io/appmod-demo-cicd

 

zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ az acr login -n $ACR_NAME
Login Succeeded
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker tag appmod-demo-cicd $ACR_NAME.azurecr.io/appmod-demo-cicd
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$ docker push $ACR_NAME.azurecr.io/appmod-demo-cicd
Using default tag: latest
The push refers to repository [zeroacrdemo2024.azurecr.io/appmod-demo-cicd]
2f07e3d96fec: Pushed
ceaf9e1ebef5: Pushed
9b9b7f3d56a0: Pushed
f1b5933fe4b5: Pushed
latest: digest: sha256:c735d474e7d8b4e6f1ce8385eba86b02e86df403c81933f6c3a36d04a24dc47d size: 1159
zerobig@win11vm-sa:/mnt/c/Users/zerobig/gs-spring-boot-aks$

 

 

 

혹시 인증/인가 에러가 발생하면. az acr login 명령을 수행하여 인증을 득하고 다시 명령을 수행한다.

az acr login -n $ACR_NAME
docker push $ACR_NAME.azurecr.io/appmod-demo-cicd\

 

 

 

Azure 포털의 리포지토리로 이동하여 결과를 확인한다. 

 

 

다음 편에 계속 이어 가겠다.

 

결과가 확인 되었으면 필히 VM을 중지하여 원치 않는 비용이 발생하지 않도록 한다.
 
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함