Java 앱 컨테이너화
이 단원에서는 Java 애플리케이션을 컨테이너화합니다.
앞서 설명한 것처럼 컨테이너는 기본적으로 다른 시스템 프로세스로 호스트 운영 체제, 커널 및 하드웨어를 기반으로 직접 실행됩니다. 컨테이너에는 더 적은 시스템 리소스가 필요하므로 사용 공간이 줄어들고 오버헤드가 줄어들며 애플리케이션 시작 시간이 빨라집니다. 이는 요청 시 크기 조정의 유용한 사용 사례입니다.
Windows 컨테이너 및 Linux 컨테이너가 있습니다. 이 모듈에서는 널리 사용되는 Docker 런타임을 활용하여 Linux 컨테이너 이미지를 빌드합니다. 그런 다음, 로컬 컴퓨터의 호스트 운영 체제에 Linux 컨테이너 이미지를 배포합니다. 마지막으로 Azure Kubernetes Service에 Linux 컨테이너 이미지를 배포합니다.
Docker 개요
Docker 런타임은 컨테이너 이미지를 빌드, 끌어오기, 실행, 푸시하는 데 사용됩니다. 다음 이미지에서는 이러한 사용 사례 및 각 사용 사례/Docker 명령에 대한 설명을 보여 줍니다.
Docker 명령 | 설명 |
---|---|
docker build |
컨테이너 이미지를 빌드합니다. 기본적으로 Docker가 이미지에서 실행 중인 컨테이너를 만드는 데 필요한 지침/계층입니다. 이 명령의 결과는 이미지입니다. |
docker pull |
컨테이너는 Azure Container Registry와 같은 레지스트리에서 가져온 이미지에서 초기화되며, 여기서 Azure Kubernetes Service를 가져옵니다. 이 명령의 결과는 Azure에서 발생하는 이미지의 네트워크 끌어오기입니다. 필요에 따라 이미지를 로컬로 끌어올 수 있습니다. 애플리케이션 서버와 같이 애플리케이션에 필요할 수 있는 종속성/계층이 필요한 이미지를 빌드할 때 일반적입니다. |
docker run |
이미지의 실행 중인 인스턴스는 컨테이너이며, 이 명령은 실행 중인 컨테이너 애플리케이션을 실행하고 상호 작용하는 데 필요한 모든 계층을 실행합니다. 이 명령의 결과는 호스트 운영 체제에서 실행 애플리케이션 프로세스입니다. |
docker push |
Azure Container Registry는 이미지를 바로 사용할 수 있고 Azure 배포 및 크기 조정을 위해 네트워크 근접하도록 저장합니다. |
Java 애플리케이션 복제
먼저 Flight Booking System for Airline Reservations 리포지토리를 복제하고 Airlines 웹 애플리케이션 프로젝트 폴더로 전환합니다.
참고
CLI 탭에서 Azure Kubernetes Service 만들기가 성공적으로 완료된 경우 해당 탭을 사용하고, 아직 실행 중인 경우 새 탭을 열고 Flight Booking System for Airline Reservations를 복제하려는 위치로 전환합니다.
CLI에서 다음 명령을 실행합니다.
git clone https://github.com/Azure-Samples/containerize-and-deploy-Java-app-to-Azure.git
CLI에서 다음 명령을 실행합니다.
cd containerize-and-deploy-Java-app-to-Azure/Project/Airlines
참고 항목
필요에 따라 Java 및 Maven이 설치된 경우 CLI에서 다음 명령을 실행하여 Docker 없이 애플리케이션을 빌드하는 환경을 파악할 수 있습니다. Java 및 Maven이 설치되어 있지 않은 경우 다음 섹션 인 Docker 파일 생성으로 안전하게 이동할 수 있습니다. 이 섹션에서는 Docker를 사용하여 Java 및 Maven을 끌어와서 사용자 대신 빌드를 실행합니다.
필요에 따라 Maven 및 JDK(8) 이상이 설치된 경우 CLI에서 다음 명령을 실행할 수 있습니다.
mvn clean install
참고 항목
이 명령을 사용하여 mvn clean install
다음에 다룰 Docker 다단계 빌드를 사용하지 않는 운영 문제를 설명했습니다. 이 단계는 선택 사항이며, 어느 쪽이든 Maven 명령을 실행하지 않아도 이동할 수 있습니다.
Maven은 다음 출력과 같이 항공 예약 웹 애플리케이션 보관 아티팩트 FlightBookingSystemSample-0.0.-SNAPSHOT.war에 대한 플라이트 예약 시스템을 성공적으로 빌드해야 합니다.
[INFO] Building war: /mnt/c/Users/chtrembl/dev/git/containerize-and-deploy-Java-app-to-Azure/Project/FlightBookingSystemSample/target/FlightBookingSystemSample-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.698 s
[INFO] Finished at: 2021-09-28T15:18:07-04:00
[INFO] ------------------------------------------------------------------------
Java 개발자이고 방금 빌드 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
한 것을 상상해 보십시오. 다음 단계는 운영 엔지니어와 협력하여 이 아티팩트를 온-프레미스 서버 또는 가상 머신에 배포하는 것입니다. 애플리케이션이 성공적으로 시작하고 실행되려면 서버 및 가상 머신이 사용할 수 있고 필요한 종속성을 사용하여 구성되어야 합니다. 이는 증가된 로드가 애플리케이션에 도달할 때 특히 온디맨드 방식으로 어렵고 시간이 많이 걸립니다. 컨테이너를 사용하면 이러한 문제가 완화됩니다.
Dockerfile 생성
이제 Dockerfile을 생성할 준비가 되었습니다. Dockerfile은 사용자가 명령줄에서 실행하여 컨테이너 이미지를 어셈블할 수 있는 모든 명령을 포함하는 텍스트 문서이며, 각 명령은 서로 위에 빌드되는 계층(효율성을 위해 캐시될 수 있음)입니다.
예를 들어 Flight Booking System for Airline Reservations는 애플리케이션 서버 내부에 배포되고 실행되어야 합니다. 애플리케이션 서버는 내부에 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
패키지되지 않습니다. 실행, HTTP 요청 수신 대기 및 처리, 사용자 세션 관리 및 플라이트 예약을 용이하게 하는 데 필요한 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
외부 종속성입니다. 컨테이너화되지 않은 기존의 배포인 경우에는 운영 엔지니어가 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
을 배포하기 전에 일부 물리적 서버 및/또는 가상 머신에 애플리케이션 서버를 설치하고 구성할 것입니다. 또한 이러한 운영 엔지니어는 컴퓨터에서 사용되는 JDK( mvn clean install
.war를 컴파일하는 데 사용했던 항목)가 애플리케이션 서버에서 사용되는 것과 동일한 JRE에 해당하는지 확인해야 합니다. 이러한 종속성을 관리하는 것은 어려운 일이며 시간이 많이 걸립니다.
Dockerfile을 사용하면 Flight Booking System for Airline Reservations에 Docker 컨테이너 런타임으로 배포하는 데 필요한 모든 종속성이 있는지 확인하는 데 필요한 단계를 계층화하여 이 작업을 자동으로 수행하는 데 필요한 명령(레이어)을 작성할 수 있습니다. 계획되지 않은 간격의 요청 시 크기 조정을 생각하기 시작하면 이는 매우 매력적입니다. 각 레이어는 각 명령 마일스톤 최적화 컴퓨팅 시간 및 재사용 시 컨테이너 이미지의 상태를 포함하는 Docker 캐시를 활용한다는 것은 언급할 가치가 있습니다. 레이어가 변경되지 않으면 캐시된 계층이 사용됩니다. 캐시된 레이어의 일반적인 사용 사례는 Java 런타임, 애플리케이션 서버 및/또는 기타 Flight Booking System for Airline Reservations 웹 애플리케이션 종속성입니다. 이전에 캐시된 계층에서 버전이 변경되면 캐시된 새 항목이 만들어집니다.
다음 이미지는 컨테이너 이미지의 레이어를 보여 줍니다. 모든 최상위 레이어는 이전 읽기 전용 레이어 위에 빌드된 읽기/쓰기 Flight Booking System for Airline Reservations 웹 애플리케이션 레이어이며, 모두 Dockerfile의 명령에서 생성됩니다.
또한 Docker에는 더 나은 캐싱 및 더 작은 보안 공간을 사용하여 더 작은 컨테이너 이미지를 만들 수 있는 기능인 다단계 빌드의 개념이 있으므로 시간이 지남에 따라 Dockerfile의 최적화 및 기본 강화됩니다. 예를 들어 애플리케이션 컴파일(FlightBookingSystemSample-0.0.1-SNAPSHOT.war
)과 컨테이너 이미지 자체의 빌드를 모두 수행하는 데 사용할 수 있는 지침입니다. 컴파일의 잔재를 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
남겨 두면 공간이 더 작아집니다. 장기적으로, 이러한 이미지가 네트워크를 이동하는 것을 생각하면 수지가 맞습니다. 다단계 빌드를 사용하면 Dockerfile에서 여러 FROM 문을 사용합니다. 각 FROM 명령은 다른 베이스를 사용할 수 있으며, 이러한 문은 각각 클린 슬레이트로 시작하여 캐싱 레이어에서 일반적으로 캐시될 수 있는 불필요한 파일을 제거합니다.
런타임에 컨테이너 이미지에서 격리되는 동일한 JRE에 해당하는 동일한 JDK가 애플리케이션을 빌드하도록 해야 합니다. 다음 예제에서는 특정 버전의 Maven과 특정 버전의 JDK를 활용하여 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
를 컴파일하는 빌드 스테이지를 볼 수 있습니다. 이 스테이지는 이 스테이지를 실행하는 모든 Docker 런타임이 Dockerfile 작성자가 지정한 대로 생성된 바이트 코드를 얻도록 보장합니다(그렇지 않다면 운영 엔지니어가 Java 및 애플리케이션 서버 런타임을 개발자의 런타임과 상호 참조해야 함). 그런 다음 패키지 스테이지에서는 빌드 스테이지의 JDK에 해당하는 특정 버전의 Tomcat 및 JRE를 사용합니다. 다시 한 번, 이는 모든 종속성(JDK(Java Development Kit), JRE(Java 런타임 환경), 애플리케이션 서버)을 제어하고 격리하여 이 이미지가 실행되는 모든 컴퓨터에서 예상된 동작을 볼 수 있도록 하기 위한 것입니다.
또한 이 다단계 빌드를 사용하면 기술적으로 Maven 및 Java를 시스템에 설치할 필요가 없다는 점도 주목할 가치가 있습니다. Docker는 애플리케이션 런타임뿐만 아니라 애플리케이션을 빌드하는 데 사용할 수 있도록 풀다운하여 잠재적인 버전 관리 충돌 및 예기치 않은 동작을 방지합니다. 물론 코드를 컴파일하고 Docker 외부에서 아티팩트 빌드하지 않는 한
다음 이미지는 Dockerfile에 지정된 명령에 따라 다단계 빌드 및 각 단계에서 발생하는 작업을 보여 줍니다. 스테이지 0, 즉 빌드 스테이지에서는 Flight Booking System for Airline Reservations 웹 애플리케이션이 컴파일되고 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
가 생성되는 위치를 알 수 있습니다. 이 단계에서는 이 애플리케이션을 컴파일하는 데 사용되는 Maven 및 Java 버전의 일관성을 허용합니다. FlightBookingSystemSample-0.0.1-SNAPSHOT.war
가 만들어지면 이것이 스테이지 1(런타임 스테이지)에 필요한 유일한 레이어이며 이전 레이어는 모두 삭제될 수 있습니다. 그런 다음, Docker는 스테이지 0에서 이 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
레이어를 사용하여 런타임에 필요한 나머지 레이어를 생성합니다. 이 경우 애플리케이션 서버를 구성하고 애플리케이션을 시작합니다.
프로젝트 루트 containerize-and-deploy-Java-app-to-Azure/Project/Airlines 내에서 Dockerfile이라는 파일을 만듭니다.
vi Dockerfile
Dockerfile에 다음 내용을 추가한 다음, ESC를 누르고 :wq!를 입력하고 Enter 키를 눌러 저장하고 종료합니다.
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
WORKDIR /build
COPY pom.xml .
COPY src ./src
COPY web ./web
RUN mvn clean package
#
# Package stage
#
FROM tomcat:8.5.72-jre11-openjdk-slim
COPY tomcat-users.xml /usr/local/tomcat/conf
COPY --from=build /build/target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war
EXPOSE 8080
CMD ["catalina.sh", "run"]
참고 항목
필요한 경우 프로젝트 루트의 Dockerfile_Solution에 필요한 내용이 포함되어 있습니다.
이 Dockerfile 빌드 스테이지에는 다음 6가지 지침이 있습니다.
Docker 명령 | 설명 |
---|---|
FROM |
FROM maven 는 이 빌드를 실행하는 모든 컴퓨터에서 동일한 바이트 코드 컴파일이 FlightBookingSystemSample-0.0.1-SNAPSHOT.war 수행되도록 하기 위해 이 빌드가 빌드되는 기본 계층, 특정 버전의 Maven 및 특정 버전의 JDK가 됩니다. |
WORKDIR |
WORKDIR 는 지정된 시간에 컨테이너의 작업 디렉터리를 정의하는 데 사용됩니다. 이 경우 컴파일된 아티팩트가 상주합니다. |
COPY |
COPY 는 Docker 클라이언트의 현재 디렉터리에서 파일을 추가합니다. Maven이 컴파일하는 데 필요한 파일을 설정합니다. pom.xml이 Docker 컨텍스트에서 필요합니다. |
COPY |
Maven이 컴파일하는 데 필요한 파일을 설정합니다. Docker 컨텍스트에는 항공 예약용 항공편 예약 시스템 웹 애플리케이션이 포함된 src 폴더가 필요합니다. |
COPY |
Maven이 컴파일하는 데 필요한 파일을 설정합니다. 웹 Docket 컨텍스트에는 항공편 예약 시스템 for Airline Reservations 웹 애플리케이션 종속성이 포함된 폴더가 필요합니다. |
실행 | 이 RUN mvn clean package 명령은 현재 이미지 위에 있는 모든 명령을 실행하는 데 사용됩니다. 이 경우 RUN은 Maven 빌드를 실행하는 데 사용됩니다. 그러면 FlightBookingSystemSample-0.0.1-SNAPSHOT.war 가 컴파일됩니다. |
이 Docker 파일 패키지 스테이지에는 다음 5개의 명령이 있습니다.
Docker 명령 | 설명 |
---|---|
FROM |
FROM tomcat 은 컨테이너 이미지를 빌드할 기준 계층이 됩니다. Flight Booking System for Airline Reservations 컨테이너 이미지는 tomcat 이미지 위에 빌드되는 이미지입니다. Docker 런타임은 로컬에서 tomcat 이미지를 찾으려고 시도합니다. 이 버전이 없으면 레지스트리에서 하나를 끌어옵니다. 여기서 참조되는 tomcat 이미지를 검사한 경우 다른 많은 계층을 사용하여 빌드된 것을 알 수 있습니다. 이 모든 계층을 통해 Java 애플리케이션을 배포할 때 전 세계에서 사용할 수 있는 하나의 패키지된 애플리케이션 서버 컨테이너 이미지로 재사용할 수 있습니다. 이 모듈을 위해 tomcat:8.5.72-jre11-openjdk-slim 을 선택하고 테스트했습니다. Docker가 이 두 번째 FROM 명령을 인식하면 첫 번째 빌드 스테이지의 이전 계층이 모두 사라집니다. |
COPY |
COPY tomcat-users.xml 는 항공사 예약 사용자용 플라이트 예약 시스템(Tomcat ID를 사용하여 소스 제어 내에서 관리됨, 일반적으로 외부 ID 관리 시스템에 있음)을 관리하는 tomcat-users.xml 파일을 tomcat 컨테이너 이미지에 복사하여 컨테이너 이미지가 만들어질 때마다 컨테이너 이미지에 존재합니다. |
ADD |
ADD target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war 는 Tomcat 이미지 웹앱 폴더에 컴파일된 FlightBookingSystemSample-0.0.1-SNAPSHOT.war maven을 복사하여 Tomcat이 초기화될 때 애플리케이션 서버에 설치할 것을 찾을 FlightBookingSystemSample-0.0.1-SNAPSHOT.war 수 있도록 합니다. |
EXPOSE |
EXPOSE 8080 은 Tomcat이 포트 8080에서 트래픽을 수신하도록 구성되었기 때문에 필요합니다. 이렇게 하면 Docker 프로세스가 이 포트에서 수신 대기합니다. |
CMD |
CMD 명령은 컨테이너를 실행할 때 실행할 명령을 설정합니다. 이 경우 CMD ["catalina.sh", "run"] 은 Docker에 Tomcat 애플리케이션 서버를 초기화하도록 지시합니다. |
참고 항목
줄에 버전 태그가 FROM tomcat
없으면 최신 버전이 적용됩니다. 일반적으로 버전 태그를 활용하려고 합니다(캐싱이 적용되므로 계층이 지속적으로 변경되는 경우 테스트되지 않은 빌드/계층의 대역폭, 대기 시간, 컴퓨팅 시간 및/또는 부작용이 발생함). 이 모듈을 위해 런타임에 FlightBookingSystemSample-0.0.1-SNAPSHOT.war
에서 작동하는 것으로 테스트된 특정 Maven, Tomcat, Java JRE/JDK 태그를 미리 선택했습니다.
Dockerfile 생성에 대한 자세한 내용은 Dockerfile 참조를 참조 하세요.