IT/DevOps

jib 이용 시 자바 에이전트 추가하기

Aaron's papa 2021. 7. 31. 17:04
반응형

지난번 글에서 jib를 이용해서 자바 앱을 컨테이너화 하는 방법에 대해 살펴봤습니다. ./gradlew jib 라는 한 줄의 명령을 통해서 간편하게 자바 애플리케이션을 컨테이너화 할 수 있었습니다. 오늘은 jib를 이용해서 자바 애플리케이션을 컨테이너화 할 때 APM 에이전트와 같은 외부 라이브러리를 포함시키는 방법에 대해서 살펴보겠습니다.


이미지에 파일을 추가하기

기존과 같은 Dockerfile을 이용해서 컨테이너 이미지를 만들었다면 COPY 명령을 통해서 필요로 하는 외부 라이브러리를 추가할 수 있습니다. 그렇다면 jib에서는 어떻게 할 수 있을까요? jib에는 extraDirectories라는 설정을 통해서 할 수 있습니다.

extraDirectories 설정 (https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin)

그리고 extraDirectoriespaths 속성은 (project-dir)/src/main/jib 라는 기본값을 가지고 있습니다. 즉, 이 디렉터리에 우리가 원하는 외부 라이브러리 파일을 위치시키면 jib로 컨테이너 이미지를 만들 때 / 디렉터리로 포함된다는 이야기입니다.

src/main/jib 파일이 컨테이너에 포함되는 과정 (https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#adding-arbitrary-files-to-the-image)

그럼 바로 진행해 보겠습니다.

hello-jib 애플리케이션의 디렉터리 구성은 아래와 같습니다.

❯ tree
.
├── HELP.md
├── build
├── build.gradle
├── gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── alden
    │   │           └── hellojib
    │   │               └── HelloJibApplication.java
    │   └── resources
    │       └── application.properties
    └── test
        └── java
            └── com
                └── alden
                    └── hellojib
                        └── HelloJibApplicationTests.java

이제 src/main 밑에 jib 라는 디렉터리를 하나 만들어서 자바 APM 에이전트를 복사해 보겠습니다.


뉴렐릭 자바 APM 에이전트 설치하기

먼저 뉴렐릭 자바 APM 에이전트를 다운로드합니다.

뉴렐릭 자바 APM 에이전트 다운로드 하기 (https://docs.newrelic.com/docs/agents/java-agent/installation/install-java-agent/)

그리고 다운로드한 파일의 압축을 풀어 줍니다.

-rw-r--r--@  1 alden  staff     11357  7 15 17:02 LICENSE
-rw-r--r--@  1 alden  staff     70883  7 15 17:02 THIRD_PARTY_NOTICES.md
-rw-r--r--@  1 alden  staff      4804  7 15 17:02 extension-example.xml
-rw-r--r--@  1 alden  staff     18840  7 15 17:02 extension.xsd
-rw-r--r--@  1 alden  staff    221551  7 15 17:09 newrelic-api-javadoc.jar
-rw-r--r--@  1 alden  staff     41886  7 15 17:09 newrelic-api-sources.jar
-rw-r--r--@  1 alden  staff     54607  7 15 17:04 newrelic-api.jar
-rw-r--r--@  1 alden  staff  20490624  7 15 17:09 newrelic.jar
-rw-r--r--@  1 alden  staff     13825  7 15 17:02 newrelic.yml

이제 여기 있는 파일들 중 newrelic.jar 파일을 복사해 주겠습니다. newrelic.yml 파일에 필요한 설정을 해서 같이 복사할 수도 있지만 환경별로 newrelic 설정이 달라져야 하기 때문에 필요한 설정들은 환경변수로 넣어 주는 것이 좋습니다.

❯ mkdir -p ~/Desktop/Project/hello-jib/src/main/jib/newrelic
❯ cp newrelic.jar ~/Desktop/Project/hello-jib/src/main/jib/newrelic

그리고 hello-jib 애플리케이션에는 divide/{num} 라는 라우팅 경로와 함수를 추가해 줍니다. 만약 num 으로 0이 들어오면 java.lang.ArithmeticException 이 발생하게 되겠죠.

@RequestMapping("/divide/{num}")
public int divide(@PathVariable("num") int num) {
    return 100/num;
}

이제 jib를 이용해서 애플리케이션을 컨테이너화 해 주기 위해 jib 설정을 수정해 줍니다. tagsapm_enabled로 변경해 주었고, jvmFlags에 뉴렐릭 자바 APM 에이전트 설정을 추가해 주었습니다. 우리는 뉴렐릭 자바 APM 에이전트를 src/main/jib/newrelic/newrelic.jar 에 복사해 주었으니 컨테이너 이미지가 될 때 /newrelic/newrelic.jar 로 복사됩니다.

지난번 글에서는 JAVA 16을 사용했지만 APM 에이전트가 JAVA 15까지 지원하기 때문에 JAVA 15로 버전을 낮춰 줍니다.
jib {
    from {
        image = "adoptopenjdk/openjdk15:x86_64-alpine-jre-15.0.2_7"
    }
    to {
        image = "sepiro2000/hello-jib"
        tags = ["apm_enabled"]
    }
    container {
        jvmFlags = ["-Xms128m", "-Xmx128m", "-javaagent:/newrelic/newrelic.jar"]
    }
}

jib로 컨테이너 이미지를 만들어 줍니다.

apm_enabled 이미지 생성 화면

docker pull 명령으로 apm_enabled 태그를 가진 이미지를 가져오겠습니다.

❯ docker pull sepiro2000/hello-jib:apm_enabled
apm_enabled: Pulling from sepiro2000/hello-jib
5843afab3874: Already exists
8bc50dd1755c: Pull complete
fe9f865fe2cf: Pull complete
8e5a2ca795c6: Pull complete
3abe67bfcfac: Pull complete
a78fa1d5de9b: Pull complete
90c7c4122f60: Pull complete
a87030976dd9: Pull complete
Digest: sha256:2edcd8956d11fedaadfad7dba79920cfb83bd82060cae23496733844aaf00dae
Status: Downloaded newer image for sepiro2000/hello-jib:apm_enabled
docker.io/sepiro2000/hello-jib:apm_enabled

~/Desktop/Project/hello-jib
❯ docker images
REPOSITORY             TAG           IMAGE ID       CREATED        SIZE
sepiro2000/hello-jib   latest        cebd289c1070   51 years ago   381MB
sepiro2000/hello-jib   apm_enabled   db4eb2926467   51 years ago   229MB

잘 설정되었고 자바 APM 에이전트도 정상적으로 동작하는지 docker pull 명령으로 이미지를 가져온 후 실행해 보겠습니다. 실행할 때는 -e 옵션을 통해서 필요한 환경 변수들을 꼭 포함시켜줘야 정상적으로 동작합니다.

뉴렐릭 자바 APM 에이전트를 실행하기 위해 필요한 환경 변수들은 https://docs.newrelic.com/docs/agents/java-agent/additional-installation/install-new-relic-java-agent-docker 이곳에서 확인하시면 됩니다.
❯ docker run -p 8080:8080 -e NEW_RELIC_API_KEY=XXXXX -e NEW_RELIC_ACCOUNT_ID=XXXXX -e NEW_RELIC_APP_NAME=hello-jib -e NEW_RELIC_LOG_FILE_NAME=STDOUT -e NEW_RELIC_LICENSE_KEY=XXXXX db4eb2926467

뉴렐릭 페이지에 접속하면 아래와 같이 정상적으로 APM 데이터를 수집하는 것을 볼 수 있습니다.

뉴렐릭 APM 대시보드

curl 명령을 이용해서 일부 API를 호출해보고 divide/{num} 쪽에 에러도 발생시켜 봅니다.

❯ curl http://localhost:8080/
hello, jib!
~
❯ curl http://localhost:8080/divide/0
{"timestamp":"2021-07-30T15:22:27.434+00:00","status":500,"error":"Internal Server Error","path":"/divide/0"}
~
❯ curl http://localhost:8080/divide/0
{"timestamp":"2021-07-30T15:23:35.179+00:00","status":500,"error":"Internal Server Error","path":"/divide/0"}
~
❯ curl http://localhost:8080/divide/0
{"timestamp":"2021-07-30T15:23:35.846+00:00","status":500,"error":"Internal Server Error","path":"/divide/0"}
~
❯ curl http://localhost:8080/divide/1
100

그럼 아래와 같이 APM 대시보드에서 에러가 수집되고 에러 내용도 볼 수 있는 것을 확인할 수 있습니다.

뉴렐릭 APM 대시보드


마치며

이번 글을 통해서 jib 를 사용했을 때 외부 라이브러리를 컨테이너에 설치하는 과정에 대해 살펴봤습니다. jibDockerfile을 통해 할 수 있는 대부분의 작업들을 지원하고 있습니다. 이제 다음 글에서는 마지막으로 Github Actions와 연동해서 소스 코드 머지 후 자동으로 jib를 통해 컨테이너화 하고 APM 에이전트도 설치해서 도커 허브에 이미지를 푸시하는 과정까지 살펴보겠습니다. 이를 통해서 CI/CD 파이프라인에 jib를 어떻게 활용할 수 있을지 살펴 보겠습니다. 감사합니다.

반응형