tjtjtjのメモ

自分のためのメモです

Quarkus - Creating Your First Application

java コンテナイメージのサイズに悩んでいたところ、こんなニュースがあった。 高速起動にはあまり興味がないが、Quarkus のイメージサイズに興味を覚えた。

Quarkus ってなに?

https://yoshio3.com/2019/03/11/try-quarkus/ より

Quarkus を簡単にご説明すると、Javaソースコードを GraalVM を利用して Linux の Native バイナリを作成し、その Linux バイナリをコンテナ上で起動することにより、今まで Java アプリの課題であった起動時間を大幅に短縮することができる技術です。

GraalVM ってなに?

https://www.graalvm.org/ google翻訳

GraalVMは、JavaScriptPythonRuby、R、JavaScala、Kotlin、ClojureなどのJVMベースの言語、およびCやC ++などのLLVMベースの言語で作成されたアプリケーションを実行するための汎用仮想マシンです。

graalvm いれる

  • https://www.graalvm.org/downloads/
  • wget
  • tar xvf
  • mv graalvm-ce-1.0.0-rc13 /opt
  • export PATH=/opt/graalvm-ce-1.0.0-rc13/bin:$PATH
  • java -version openjdk version "1.8.0_202" OpenJDK Runtime Environment (build 1.8.0_202-20190206132807.buildslave.jdk8u-src-tar--b08) OpenJDK GraalVM CE 1.0.0-rc13 (build 25.202-b08-jvmci-0.55, mixed mode)

Quarkus - Creating Your First Application

チュートリアル 通りにやってみる。

getting-started ディレクトリ下にプロジェクトが生成される。

mvn io.quarkus:quarkus-maven-plugin:0.11.0:create \
    -DprojectGroupId=jp.acme \
    -DprojectArtifactId=getting-started \
    -DclassName="org.acme.quickstart.GreetingResource" \
    -Dpath="/hello"

アプリケーション起動(devモード)

$ cd ./getting-started
$ mvn compile quarkus:dev

アプリケーション確認

$ curl http://localhost:8080
> Congratulations, you have created a new Quarkus application.
> とかなんとか

$ curl http://localhost:8080/hello
hello
  1. Using injection

今度試す

  1. Development Mode バックグラウンドコンパイルによるホットデプロイが可能

なるほどいいね。次も今度試す。

  1. Testing
  2. Packaging and run the application
  3. Async

docker してみる

src/main/docker/Dockerfile を確認。イメージ生成手順が載っています。 target/*-runner を実行することが分かる。

####
# Before building the docker image run:
#
# mvn package -Pnative -Dnative-image.docker-build=true
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM registry.fedoraproject.org/fedora-minimal
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

target ディレクトリも見てみる。 target/*-runner は20MB

$ ls -alh target
合計 20M
drwxrwxr-x 14 tjtjtj tjtjtj 4.0K  3月 18 20:50 .
drwxrwxr-x  4 tjtjtj tjtjtj 4.0K  3月 18 22:50 ..
drwxrwxr-x  4 tjtjtj tjtjtj 4.0K  3月 18 19:59 classes
drwxrwxr-x  3 tjtjtj tjtjtj 4.0K  3月 18 19:39 generated-sources
drwxrwxr-x  3 tjtjtj tjtjtj 4.0K  3月 18 19:59 generated-test-sources
-rwxr-xr-x  1 root   root    20M  3月 18 20:50 getting-started-1.0-SNAPSHOT-runner
-rw-r--r--  1 root   root    36K  3月 18 20:04 getting-started-1.0-SNAPSHOT-runner.jar
-rw-rw-r--  1 tjtjtj tjtjtj 5.3K  3月 18 20:04 getting-started-1.0-SNAPSHOT.jar
drwxrwxr-x  2 tjtjtj tjtjtj 4.0K  3月 18 20:04 lib
drwxrwxr-x  2 tjtjtj tjtjtj 4.0K  3月 18 19:59 maven-archiver
drwxrwxr-x  3 tjtjtj tjtjtj 4.0K  3月 18 19:39 maven-status
-rw-rw-r--  1 tjtjtj tjtjtj 3.5K  3月 18 20:04 quarkus.log
drwxr-xr-x  2 root   root   4.0K  3月 18 20:33 reports
drwxrwxr-x  2 tjtjtj tjtjtj 4.0K  3月 18 19:59 surefire-reports
drwxrwxr-x  6 tjtjtj tjtjtj 4.0K  3月 18 19:59 test-classes
drwxrwxr-x  2 tjtjtj tjtjtj 4.0K  3月 18 19:59 transformed-classes
drwxrwxr-x  6 tjtjtj tjtjtj 4.0K  3月 18 19:59 wiring-classes
drwxrwxr-x  4 tjtjtj tjtjtj 4.0K  3月 18 19:39 wiring-devmode

ネイティブバイナリ生成。これが噂のlinuxに最適化されたバイナリ生成か。しっかし時間かかったね。ショボvm のせいもあり参考になさらず。

# mvn package -Pnative -Dnative-image.docker-build=true
:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  48:16 min
[INFO] Finished at: 2019-03-18T20:50:50+09:00
[INFO] ------------------------------------------------------------------------

イメージサイズ。125MBか。openjdk:8-jdk-alpine の121MB とあまり変わらないサイズ。

# docker images
REPOSITORY               TAG     IMAGE ID      CREATED             SIZE
quarkus/getting-started  latest  2bde28a5057f  About a minute ago  125MB

docker build

# docker build -f src/main/docker/Dockerfile -t quarkus/getting-started .

docker run。確かに一瞬で起動する。バイナリ生成時間をとるか、起動時間をとるか。

# docker run -i --rm -p 8080:8080 quarkus/getting-started

動作確認

$ curl http://localhost:8080/hello
hello

kubernetes してみる

タギング, docker-login, タグpush

docker tag quarkus/getting-started:latest 192.168.0.1:5000/quarkus/getting-started:latest
docker login 192.168.0.1:5000
docker push 192.168.0.1:5000/quarkus/getting-started:latest

イメージ確認

# docker image ls
REPOSITORY                                  TAG                          IMAGE ID            CREATED             SIZE
192.168.0.1:5000/quarkus/getting-started    latest                       2bde28a5057f        About an hour ago   125MB
quarkus/getting-started                     latest                       2bde28a5057f        About an hour ago   125MB

カタログ確認

# curl localhost:5000/v2/_catalog
{"repositories":["kbhello","quarkus/getting-started"]}

quarkusstarted-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: quarkusstarted-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: quarkusstarted
  template:
    metadata:
      labels:
        app: quarkusstarted
    spec:
      containers:
      - name: quarkusstarted
        image: 192.168.0.1:5000/quarkus/getting-started
        ports:
        - containerPort: 8080

デプロイ

$ kubectl apply -f quarkusstarted-deployment.yaml
deployment.apps/quarkusstarted-deployment created
$ kubectl get pod
NAME                                         READY   STATUS    RESTARTS   AGE
quarkusstarted-deployment-7896c77d8c-h7k4n   1/1     Running   0          19s
quarkusstarted-deployment-7896c77d8c-vh42p   1/1     Running   0          19s

ロードバランサ作成

$ kubectl expose deployment quarkusstarted-deployment --type=LoadBalancer --name=quarkusstarted-service
service/quarkusstarted-service exposed
$ kubectl get service
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
kubernetes               ClusterIP      10.96.0.1       <none>        443/TCP              33d
quarkusstarted-service   LoadBalancer   10.103.221.38   <pending>     8080:30423    /TCP   14s

確認

$ curl http://10.103.221.38:8080/hello
hello