Quarkus - Creating Your First Application
java コンテナイメージのサイズに悩んでいたところ、こんなニュースがあった。 高速起動にはあまり興味がないが、Quarkus のイメージサイズに興味を覚えた。
- Javaフレームワーク「Quarkus」登場。Javaコードからネイティブバイナリを生成し瞬時にJavaアプリが起動、コンテナへの最適化を実現。Red Hatがリリース
- Quarkus: コンテナ上で 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は、JavaScript、Python、Ruby、R、Java、Scala、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
- Using injection
今度試す
なるほどいいね。次も今度試す。
- Testing
- Packaging and run the application
- 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