TheKoguryo's 기술 블로그

Version 2023.09.08

7.2.1 GraalVM 기반 컨테이너 이미지 만들기

여기서는 향상된 just-in-time(JIT) 컴파일러를 통한 가장 간편한 방법으로 코드 변경없이 자바 애플케이션의 성능 개선하는 방벙으로 알아보겠습니다.

GraalVM 제공 컨테이너 이미지

GraalVM은 오픈소스로 제공하는 Community 버전과 상업용 Enterprise 버전을 제공하고 있습니다. Enterprise 버전은 더 높은 최적화 기능을 제공하고 있습니다. GraalVM은 Oracle Java SE 구독 모델에 포함되어 있으며, Oracle Cloud Infrastructure 내 자원에서는 별도 비용없이 사용할 수 있습니다.

  • GraalVM Download

    • GraalVM 커뮤니티 컨테이너 이미지: GitHub 컨테이너 레지스트리에 등록되어 있어, 별도 인증없이 가져가 사용할 수 있습니다.
    • GraaVM 엔터프라이즈 컨테이너 이미지: 상업용 버전으로 오라클 컨테이너 레지스트리에 등록되어 있고, OTN 계정으로 인증이 필요합니다.

    image-20220427103805484

  • 에디션별 비교

    image-20220426164317927

GraalVM-CE기반 Container Image 사용하기

GraalVM Community Images

  1. 앞서 만든 Spring Boot 앱의 코드로 이동합니다.

  2. GraalVM-CE에서 실행하기 위해서는 Dockerfile을 아래와 같이 만듭니다. 기존 openjdk:8-jdk-alpine 베이스 이미지에서 GraalVM-CE 버전으로 변경합니다.

    • 현재 Cloud Shell에 기본 설치된 JDK 8을 기준으로 빌드가 되어 GraalVM-CE 21 버전을 사용하였습니다.
    • GraalVM CE 컨테이너 이미지는 GitHub Registry에 등록되어 Public하게 개방되어 바로 가져와서 사용할 수 있습니다. 사용가능한 JDK 컨테이너 이미지 중에서 선택합니다.
    # Dockerfile.graalvm-ce
    FROM ghcr.io/graalvm/jdk:ol7-java8-21.2
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} app.jar
    ENTRYPOINT ["java","-jar","app.jar"]
    
  3. 이미지를 빌드합니다.

    docker build -t spring-boot-greeting:graalvm-ce-1.0 -f Dockerfile.graalvm-ce .
    
  4. OCIR로 빌드된 이미지를 Push합니다.

    docker tag spring-boot-greeting:graalvm-ce-1.0 ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ce-1.0
    docker push ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ce-1.0
    
  5. 기본 배포된 Kubernetes Deployment를 변경된 이미지로 수정반영합니다. 직접 수정하거나, kubectl set 명령어를 통해 이미지를 변경합니다.

    kubectl edit deployment spring-boot-greeting-deployment
    또는
    kubectl set image deployment spring-boot-greeting-deployment spring-boot-greeting=ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ce
    
  6. 실행된 컨테이너에 접속하여 자바 버전을 확인합니다.

    winter@cloudshell:rest-service (ap-chuncheon-1)$ kubectl get pod
    NAME                                               READY   STATUS    RESTARTS   AGE
    spring-boot-greeting-deployment-7d7d7b5cf7-frtdg   1/1     Running   0          114s
    winter@cloudshell:rest-service (ap-chuncheon-1)$ kubectl exec -it spring-boot-greeting-deployment-7d7d7b5cf7-frtdg -- java -version
    openjdk version "1.8.0_302"
    OpenJDK Runtime Environment (build 1.8.0_302-b07)
    OpenJDK 64-Bit Server VM GraalVM CE 21.2.0 (build 25.302-b07-jvmci-21.2-b08, mixed mode
    

GraalVM-EE기반 Container Image 사용하기

GraalVM Enterprise 이미지 가져오기
  1. GraalVM Enterprise 이미지를 사용하기 위해서는 Oracle Container Registry에서 Oracle Account 인증을 통해 Pull 할수 있습니다. 사용하기 전에 최초 한번 Oracle Account로 로그인 후 라이센스 동의가 필요합니다.

  2. Oracle Container Registry에 접속하여, GraalVM 저장소로 이동합니다.

    image-20220427112811109

  3. 저장소 중에서 jdk-ee를 선택합니다.

    image-20220427113035444

  4. 라이센스 동의를 위해 로그인합니다.

    image-20220427113938889

  5. Oracle Account로 로그인합니다. 계정이 없는 경우, 계정을 만듭니다.

    image-20220427113339137

  6. Continue를 클릭합니다.

    image-20220427114033701

  7. 라이센스 내용을 확인후 Accept 합니다. 그러면 다음과 같이 표시됩니다.

    image-20220427114402158

  8. docker login 명령으로 Oracle Container Registry로 로그인합니다. 앞서 사용한 Oracle Account로 로그인합니다.

    $ docker login container-registry.oracle.com
    Username: <oracle sso username>
    Password: <oracle sso password>
    ...
    Login Succeeded
    
  9. docker pull을 통해 이미지를 잘 가져오는 지 확인합니다.

    $ docker pull container-registry.oracle.com/graalvm/jdk-ee:ol8-java8-21.3.2
    Trying to pull repository container-registry.oracle.com/graalvm/jdk-ee ... 
    ol8-java8-21.3.2: Pulling from container-registry.oracle.com/graalvm/jdk-ee
    e4430e06691f: Pull complete 
    998ed91b929f: Pull complete 
    652cb5fdd8a8: Pull complete 
    Digest: sha256:dbfd2607dd1192c97304a68743eeb91342f9d64634f18f908d719e0bc60aac13
    Status: Downloaded newer image for container-registry.oracle.com/graalvm/jdk-ee:ol8-java8-21.3.2
    container-registry.oracle.com/graalvm/jdk-ee:ol8-java8-21.3.2
    
  10. 사용가능한 이미지 리스트는 앞서 Oracle Container Registry 웹페이지 아래쪽 화면에서 확인할 수 있습니다. 서울, 춘천 미러사이트도 제공하고 있습니다.

    image-20220427120204020

GraalVM Enterprise 이미지 사용하기
  1. 앞서 만든 Spring Boot 앱의 코드로 이동합니다

  2. GraalVM-EE에서 실행하기 위해서는 Dockerfile을 아래와 같이 만듭니다.

    jdk-ee:ol8-java8-21.3.2 이미지의 기본 홈 디렉토리는 /app입니다. ENTRYPOINT에서 실행시 /app.jar라고 하면 해당 위치에 app.jar 파일이 없기 때문에 에러가 발생합니다.

    # Dockerfile.graalvm-ee
    FROM container-registry.oracle.com/graalvm/jdk-ee:ol8-java8-21.3.2
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} app.jar
    ENTRYPOINT ["java","-jar","app.jar"]
    
  3. 이미지를 빌드합니다.

    docker build -t spring-boot-greeting:graalvm-ee-1.0 -f Dockerfile.graalvm-ee .
    
  4. OCIR로 빌드된 이미지를 Push합니다.

    docker tag spring-boot-greeting:graalvm-ee-1.0 ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ee-1.0
    docker push ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ee-1.0
    
  5. 기본 배포된 Kubernetes Deployment를 변경된 이미지로 수정반영합니다. 직접 수정하거나, kubectl set 명령어를 통해 이미지를 변경합니다.

    kubectl edit deployment spring-boot-greeting-deployment
    또는
    kubectl set image deployment spring-boot-greeting-deployment spring-boot-greeting=ap-chuncheon-1.ocir.io/${tenancy_namespace}/spring-boot-greeting:graalvm-ee-1.0
    
  6. 실행된 컨테이너에 접속하여 자바 버전을 확인합니다.

    winter@cloudshell:rest-service (ap-chuncheon-1)$ kubectl get pod
    NAME                                               READY   STATUS    RESTARTS   AGE
    spring-boot-greeting-deployment-656c49d9b6-mqjmb   1/1     Running   0          14s
    winter@cloudshell:rest-service (ap-chuncheon-1)$ kubectl exec -it spring-boot-greeting-deployment-656c49d9b6-mqjmb -- java -version
    java version "1.8.0_331"
    Java(TM) SE Runtime Environment (build 1.8.0_331-09)
    Java HotSpot(TM) 64-Bit Server VM GraalVM EE 21.3.2 (build 25.331-b09-jvmci-21.3-b11, mixed mode)
    


이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.

Last updated on 26 Apr 2022