8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kotling Boot(Kotlin + Spring Boot)をGKEで動かす

Last updated at Posted at 2018-08-26

概要

  • Spring Boot + KotlinHello Worldを作成
  • 作成したSpring Bootアプリが起動するDockerイメージを作成し、GKE(Google Kubernetes Engine)で動かす
  • 地味にWebFluxを使ってるので、Nettyのイベントループで動いている

GitHub

必要なファイル

.
├── build.gradle
├── Dockerfile
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── kotlin
    │   │   └── com
    │   │       └── sugikeitter
    │   │           └── kotlinboot
    │   │               ├── controller
    │   │               │   └── HelloController.kt
    │   │               ├── data
    │   │               │   └── Hello.kt
    │   │               └── KotlinbootApplication.kt
    │   └── resources
    │       └── application.yml
    └── test
        └── kotlin
            └── com
                └── sugikeitter
                    └── kotlinboot
                        └── KotlinbootApplicationTests.kt
16 directories, 12 files

Kotling Bootアプリの作成

Project作成

  • IntelliJ IDEA UlitimateSpring Intializerからプロジェクトを作成する機能を使う
    • "Create New Project"
      image
    • "Spring Initializer"
      image
    • "Type: Gradle1", "Language: Kotlin"
      image
    • "Reacrive Web"
      image
    • "FINISH"
      image
    • "OK"
      image

Contllerクラス作成

  • src/main/kotlin/com/sugikeitter/kotlingboot/controllerパッケージを作成し、HelloController.ktを作成

    • クラスに@RestControllerをつけることでURLマッピング対象クラスに
    • メソッドに@GetMapping("/hello")をつけることで、GET /helloのエントリポイントに対応
    package com.sugikeitter.kotlingboot.controller
    
    import com.sugikeitter.kotlingboot.data.Hello
    import org.springframework.web.bind.annotation.GetMapping
    import org.springframework.web.bind.annotation.RestController
    
    @RestController
    class HelloController {
        @GetMapping("/hello")
        fun hell(): Hello {
            return Hello()
        }
    }
    

dataクラス作成

  • src/main/kotlin/com/sugikeitter/kotlingboot/dataパッケージを作成し、Hello.ktを作成

    • Kotlinのdataクラスの機能を利用
    package com.sugikeitter.kotlingboot.data
    
    import java.util.Date
    
    data class Hello (
            val message: String = "Hello. World.",
            val date: Date = Date()
    )
    

設定ファイルの作成

  • 今回はsrc/main/resources/application.ymlを作成し、ここに設定を追記する

    • 利用するポートを8888にしてみた
    server:
      port: 8888
    

動作確認

  • GradleプラグインのbootRunを使ってビルド&起動
$ ./gradlew bootRun

> Task :bootRun

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.4.RELEASE)

2018-08-26 23:14:33.612  INFO 10271 --- [           main] c.s.k.KotlingBootApplicationKt           : Starting KotlingBootApplicationKt on MBP-13UAU-034 with PID 10271 (/Users/kesugimo/IdeaProjects/kotlingboot/build/classes/kotlin/main started by kesugimo in /Users/kesugimo/IdeaProjects/kotlingboot)
2018-08-26 23:14:33.619  INFO 10271 --- [           main] c.s.k.KotlingBootApplicationKt           : No active profile set, falling back to default profiles: default
2018-08-26 23:14:33.679  INFO 10271 --- [           main] onfigReactiveWebServerApplicationContext : Refreshing org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@6a400542: startup date [Sun Aug 26 23:14:33 JST 2018]; root of context hierarchy
2018-08-26 23:14:34.729  INFO 10271 --- [           main] s.w.r.r.m.a.RequestMappingHandlerMapping : Mapped "{[/hello],methods=[GET]}" onto public com.sugikeitter.kotlingboot.data.Hello com.sugikeitter.kotlingboot.controller.HelloController.hell()
2018-08-26 23:14:34.798  INFO 10271 --- [           main] o.s.w.r.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.reactive.resource.ResourceWebHandler]
2018-08-26 23:14:34.799  INFO 10271 --- [           main] o.s.w.r.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.reactive.resource.ResourceWebHandler]
2018-08-26 23:14:34.969  INFO 10271 --- [           main] o.s.w.r.r.m.a.ControllerMethodResolver   : Looking for @ControllerAdvice: org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@6a400542: startup date [Sun Aug 26 23:14:33 JST 2018]; root of context hierarchy
2018-08-26 23:14:35.436  INFO 10271 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-08-26 23:14:35.535  INFO 10271 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext     : Started HttpServer on /0:0:0:0:0:0:0:0:8888
2018-08-26 23:14:35.535  INFO 10271 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8888
2018-08-26 23:14:35.539  INFO 10271 --- [           main] c.s.k.KotlingBootApplicationKt           : Started KotlingBootApplicationKt in 2.414 seconds (JVM running for 2.805)
<==========---> 80% EXECUTING [12s]
> :bootRun

  • リクエストが帰ってくることを確認
curl http://localhost:8888/hello
---
{"message":"Hello. World.","date":"2018-08-26T14:15:02.436+0000"}
---

Dockerfileの作成

  • 最初にjavaビルド環境用のimageを作成し、Gradleでビルドしてjarファイルを作成する
  • 必要なjarファイルだけを配備してサイズを小さくし、container起動時にjarを起動させるimageを作成
  • かなりえいやで作ったので他に良い方法がないかは調べたい
FROM openjdk:8-slim
RUN mkdir -p /opt/kotlingboot
ADD . /opt/kotlingboot
WORKDIR /opt/kotlingboot
RUN ./gradlew build

FROM openjdk:8-slim
COPY --from=0 /opt/kotlingboot/build/libs/kotlingboot-0.0.1-SNAPSHOT.jar /opt/app.jar
ENV PORT 8888
CMD ["java", "-jar", "/opt/app.jar"]

GKEで動作させる

初期設定

  • 環境変数などを設定
# リージョンはとりあえず東京で
gcloud config set compute/zone asia-northeast1-c
# チュートリアルの通りPROJECT_IDを環境変数にしておく
export PROJECT_ID="$(gcloud config get-value project -q)"

Docker imageのビルドとプッシュ

# 作成したリポジトリをclone
git clone https://github.com/sugikeitter/KotlingBoot.git
# アプリのルートディレクトリへ移動
cd ./KotlingBoot
# imageのビルド(しばらく待つ)
docker build -t gcr.io/${PROJECT_ID}/hello-app-kotlingboot:v1 .
# 確認したら、ベースイメージ、ビルド用の一時イメージ(名無し)、最終イメージの3つが確認できる
docker images
---
REPOSITORY                                    TAG                 IMAGE ID            CREATED              SIZE
gcr.io/kube-01-212312/hello-app-kotlingboot   v1                  4af1f5b45ade        About a minute ago   264MB
<none>                                        <none>              89727e75f7f8        About a minute ago   492MB
openjdk                                       8-slim              e12b22a5b022        11 days ago          244MB
---
# Googleのリポジトリにpush
gcloud docker -- push gcr.io/${PROJECT_ID}/hello-app-kotlingboot:v1

プッシュしたimageをローカルで動作確認

# 8888ポートで起動
docker run --rm -p 8888:8888 gcr.io/${PROJECT_ID}/hello-app-kotlingboot:v1
  • 別でGoogle Cloud Shellを開く
# 動作確認成功
curl http://localhost:8888/hello
---
{"message":"Hello. World.","date":"2018-08-26T15:16:59.591+0000"}
---
  • KotlingBootを停止させる
# KotlingBootを起動しているShellで"Ctrl + c"
~
^C2018-08-26 15:19:00.735  INFO 1 --- [       Thread-7] onfigReactiveWebServerApplicationContext : Closing org.springframework.boot.web.reactive.contex
t.AnnotationConfigReactiveWebServerApplicationContext@b065c63: startup date [Sun Aug 26 15:16:41 UTC 2018]; root of context hierarchy
2018-08-26 15:19:00.744  INFO 1 --- [       Thread-7] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2018-08-26 15:19:00.757  INFO 1 --- [       Thread-7] r.ipc.netty.tcp.BlockingNettyContext     : Stopped HttpServer on /0.0.0.0:8888

kubernetesでアプリを動作させる

クラスタ作成

# node3つでクラスタ作成(しばらく待つ)
gcloud container clusters create kotlingboot --num-nodes=3
# クラスタ作成確認
gcloud container clusters list
---
NAME         LOCATION           MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
kotlingboot  asia-northeast1-c  1.9.7-gke.6     35.200.10.183  n1-standard-1  1.9.7-gke.6   3          RUNNING
---
# 完了したらクラスタ認証情報を取得
gcloud container clusters get-credentials kotlingboot

デプロイ

# アプリのデプロイ
kubectl run hello-kotlingboot --image=gcr.io/${PROJECT_ID}/hello-app-kotlingboot:v1 --port 8888
# podが作成されていることを確認
kubectl get pods
---
NAME                                 READY     STATUS              RESTARTS   AGE
hello-kotlingboot-7c7dfcfdcc-t6s6n   0/1       ContainerCreating   0          7s
---

# 外部公開できるLBの作成
kubectl expose deployment hello-kotlingboot --type=LoadBalancer --port 80 --target-port 8888
# LBが作成されていることを確認
kubectl get deployment hello-kotlingboot
---
NAME                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-kotlingboot   1         1         1            1           1m
---
# 外部公開されているIPの確認
kubectl get service
---
NAME                TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
hello-kotlingboot   LoadBalancer   10.31.254.26   35.221.107.65   80:31484/TCP   1m
kubernetes          ClusterIP      10.31.240.1    <none>          443/TCP        5m
---

動作確認

  • 公開されたIPを利用しhttp://10.31.254.26/helloへブラウザからリクエスト
    image

スケールさせてみる

# レプリカを3に
kubectl scale deployment hello-kotlingboot --replicas=3

# deploymentが増えている
kubectl get deployment hello-kotlingboot
---
NAME                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-kotlingboot   3         3         3            3           10m
---

# podも増えている
kubectl get pods
---
NAME                                 READY     STATUS    RESTARTS   AGE
hello-kotlingboot-7c7dfcfdcc-4vk5l   1/1       Running   0          21s
hello-kotlingboot-7c7dfcfdcc-t6s6n   1/1       Running   0          10m
hello-kotlingboot-7c7dfcfdcc-wl8pl   1/1       Running   0          21s
---

作成したリソースのお掃除

# サービスを削除
kubectl delete service hello-kotlingboot
# ロードバランサが削除されるのを待つ
gcloud compute forwarding-rules list
# コンテナ クラスタを削除
gcloud container clusters delete kotlingboot

蛇足

  • Kotlin + Spring Bootを勝手にKotling Boot(KotlingBoot)と呼んでみる
    • 2018/08/26時点でkotlingboot, "kotling boot"を検索してヒットしなかったので、しょうもなさすぎて誰も公には名乗っていないっぽい
      • image
      • image

参考資料

公式ドキュメント

Qiita

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?