そこはかとなく

見て聞いて触ったことの技術メモ

Helidon Getting Started 3 -Kubernetes-

この記事について

今回は前回の続き、Helidonで生成されたDockerfile、マニフェストファイル(yaml)を使ってKubernetes上にコンテナイメージをデプロイします。

Kubernetesの環境準備

今回はOracle Container Engine for Kubernetes(OKE)を使用します。
OKEの作成方法はチャーリー様のブログを御覧ください。 charleysdiary.hatenablog.com

コンテナレジストリの準備

今回コンテナレジストリは OCI Registry(OCIR)を使用します。
OCIRの利用方法は別途整理します。

コンテナレジストリへログイン

OCIRにログインするにはdocker login <OCIRリージョンコード> を実行します。
Usernameは<テナント名>/<ユーザー名>を指定します。(例:gse00014510/api.user)
Passwordは生成したトークン文字列を入力します。

$ docker login iad.ocir.io
Username: gse00014510/api.user
Password:
WARNING! Your password will be stored unencrypted in /home/vagrant/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

コンテナレジストリへイメージをPush

docker tagコマンドでイメージにタグを付加し、docker push コマンドでコンテナレジストリへイメージをPushします。
タグは<リージョンコード>/<テナント名>/<リポジトリ名>/quickstart-se:v1.0を指定します。

タグの生成

$ docker tag quickstart-se iad.ocir.io/gse00014510/test/quickstart-se:v1.0

イメージのPush

$ docker push iad.ocir.io/gse00014510/test/quickstart-se:v1.0

出力

The push refers to repository [iad.ocir.io/gse00014510/test/quickstart-se]
b7913ec2fe2b: Pushed
8f8cf55d8492: Pushed
9eed0f90b339: Pushed
9bca1faaa73e: Pushed
0c3170905795: Pushed
df64d3292fd6: Pushed
v1.0: digest: sha256:d44f34c60934ba859e6562b89fedbc91eba8b9c8754db334dfc8a5bad2e1c7e4 size: 1572

これでレジストリへイメージのPushが完了しました。

マニフェストyaml)の編集

Kubernetesクラスターにコンテナをデプロイするには、クラスター上の配置情報をマニフェストと呼ばれるファイルに記述しておく必要があります。 マニフェストに先程Pushしたコンテナイメージを指定します。

30行目 image: iad.ocir.io/gse00014510/test/quickstart-se:v1.0

kind: Service
apiVersion: v1
metadata:
  name: quickstart-se
  labels:
    app: quickstart-se
spec:
  type: NodePort
  selector:
    app: quickstart-se
  ports:
  - port: 8080
    targetPort: 8080
    name: http
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: quickstart-se
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: quickstart-se
        version: v1
    spec:
      containers:
      - name: quickstart-se
        image: iad.ocir.io/gse00014510/test/quickstart-se:v1.0 #ここを修正
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---

OKEにデプロイ

さて、いよいよKubernetesクラスターへデプロイします。
kubectl createコマンドでマニフェストファイルをKubernetesクラスターに作成(適用)します。

$ kubectl create -f app.yaml
service/quickstart-se created
deployment.extensions/quickstart-se created

リソースの起動確認

Podの起動を確認

$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
quickstart-se-58bd689f5c-dptr9   1/1     Running   0          56s

Serviceの起動を確認

$ kubectl get service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP          1h
quickstart-se   NodePort    10.96.98.114   <none>        8080:30734/TCP   1m

アプリの動作確認

デフォルトで生成されるマニフェストにはServiceタイプにNodePortが使用されています。
NodePortはクラスターが可動しているマシン(ここではOracle CloudのVMインスタンス)の特定のPortを公開し、
そこに来たトラフィックをコンテナに届けます。

kubectl get node コマンドでクラスターが可動しているマシンのIPアドレスを確認します。

$ kubectl get node
NAME             STATUS   ROLES   AGE   VERSION
132.145.XXX.AA   Ready    node    1h    v1.11.5
132.145.XXX.BB   Ready    node    1h    v1.11.5
132.145.XXX.CC   Ready    node    1h    v1.11.5

kubectl get service コマンドでNodePortに割り振られたPort番号を確認します。

$ kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP          1h
quickstart-se   NodePort    10.96.245.253   <none>        8080:30908/TCP   1m

IPアドレスとPort番号を指定してRESTサービスを呼び出します。

$ curl -X GET http://132.145.XXX.AA:30908/greet
{"message":"Hello World!"}

Kubernets上にコンテナデプロイしてアプリが動作しているのが確認できました!

これでHelidon Getting Startedは完了です。RESTサービスを僅かな手順で作成することができ、かつKubernetesへの展開を迅速に行うことが出来ます。
途中説明を省略してしまったOCIRの使用方法はまた別の機会に纏めたいと思います。

ご覧いただきありがとうございました。

この記事はOracle Cloud その2 Advent Calendar 2018 - Adventar18日目です。
3日連続の最終日です。(明後日も書きます。)

Helidon Getting Started 2 -Docker-

この記事について

今回は前回の続きで、生成されたDockerfileを起動させるところまでを行います。

Dockerfileの内容を確認

#FROM openjdk:8-jre-slim
FROM openjdk:8-jre-alpine

RUN mkdir /app
COPY libs /app/libs
COPY quickstart-se.jar /app

CMD ["java", "-jar", "/app/quickstart-se.jar"]

各行では以下を定義しています。

  • FROM "基となるイメージを指定":jre8がインストールされたAlpine Linuxイメージを基に
  • RUN "ビルド中に実行するコマンドを指定":mkdirコマンドでappディレクトリを作成し
  • COPY "ローカルファイルをコンテナの中にコピー":libsとビルドした.jarをコンテナにコピー
  • CMD "起動後のコンテナで実行したいコマンドを指定":java -jar /app/quickstart-se.jar を実行

Dockerイメージをビルド

$ docker build -t quickstart-se target

出力

Sending build context to Docker daemon  5.648MB
Step 1/5 : FROM openjdk:8-jre-alpine
 ---> 2e01f547f003
Step 2/5 : RUN mkdir /app
 ---> Using cache
 ---> 2a5f46165656
Step 3/5 : COPY libs /app/libs
 ---> 7cfb246e7503
Step 4/5 : COPY quickstart-se.jar /app
 ---> 6bcea4b41853
Step 5/5 : CMD ["java", "-jar", "/app/quickstart-se.jar"]
 ---> Running in 2cc62e0c9ea8
Removing intermediate container 2cc62e0c9ea8
 ---> a49d85fd641f
Successfully built a49d85fd641f
Successfully tagged quickstart-se:latest

作成されたDockerイメージを確認

$ docker image ls

出力

REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
quickstart-se                           latest              a49d85fd641f        30 second ago         88.6MB

Dockerイメージを起動

docker runコマンドでコンテナを起動します。 --rm フラグ:コンテナの終了時に、自動的にコンテナをクリーンアップしファイルシステムを削除します -p フラグ:外部からアクセスされるポート番号:コンテナ側のポート番号を指定します

$ docker run --rm -p 8080:8080 quickstart-se:latest

出力

[DEBUG] (main) Using Console logging
2018.12.17 07:45:07 INFO io.netty.util.internal.PlatformDependent Thread[main,5,main]: Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability.
2018.12.17 07:45:07 INFO io.helidon.webserver.netty.NettyWebServer Thread[nioEventLoopGroup-2-1,10,main]: Channel '@default' started: [id: 0xb76b2ecb, L:/0.0.0.0:8080]
WEB server is up! http://localhost:8080

アプリの動作確認

$ curl -X GET http://localhost:8080/greet
{"message":"Hello World!"}

Dockerイメージからコンテナを起動してアプリが動作しているのが確認できました。

つづいてKubernetesへのデプロイ…の前に一旦休憩します(深夜2時をまわってしまいました)。

ご覧いただきありがとうございました。

この記事はOracle Cloud その2 Advent Calendar 2018 - Adventar17日目です。

Helidon Getting Started

この記事について

この記事ではProject Helidonの簡単な紹介と動かすところまでをまとめます。

Project Helidonとは

Helidonはゆるキャラの名前ではありません。軽量なJavaオープンソース・マイクロサービス・フレームワークです。

Helidon

Java EEを使用してマイクロサービスを構築することもできますが、マイクロサービス構築のためにはフレームワークを一から設計したほうがよい、という考えから始まったプロジェクトです。マイクロサービスを作成するために開発者が必要とする基盤(構成、セキュリティ、Webサーバ)を提供してくれます。

Helidon SEとHelidon MPという 2つのバージョンから構成されます。

  • Helidon SE :モダンなリアクティブ・スタイルで開発されたシンプルで関数型、軽量なMicroframeworks(シンプルで小さな機能セット)
  • Helidon MP: Java EE/Jakarta EE開発者向けなEclipse Microprofile(やや重い)

他のJava向けのマイクロサービスフレームワークには以下があります。

f:id:scoto:20181216091134p:plain

もっとHelidonについて詳しく知りたい方はLogico様のブログをご覧ください。

orablogs-jp.blogspot.com

Helidon前提条件

HelidonにはJava 8(以上)とMavenが必要です。 今回はKubernetes上にコンテナをデプロイすることを想定してUbuntuにDockerとkubectlも配備しています。

バージョンの確認

java --version
mvn --version
docker --version
kubectl version --short

JAVA_HOMEの設定

$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

Helidon SEを試してみる

イントロダクションに沿って、Helidon SEでRESTサービスを作成してみます。 https://helidon.io/docs/latest/#/getting-started/02_base-example

Projectの作成

以下のMavenコマンドを実行しJava projectを作成します。

$ mvn archetype:generate -DinteractiveMode=false \
    -DarchetypeGroupId=io.helidon.archetypes \
    -DarchetypeArtifactId=helidon-quickstart-se \
    -DarchetypeVersion=0.10.5 \
    -DgroupId=io.helidon.examples \
    -DartifactId=quickstart-se \
    -Dpackage=io.helidon.examples.quickstart.se

出力ログ

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:3.0.1:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:3.0.1:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] Archetype repository not defined. Using the one from [io.helidon.archetypes:helidon-quickstart-se:0.10.5] found in catalog remote
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: helidon-quickstart-se:0.10.5
[INFO] ----------------------------------------------------------------------------
--- 略 ----
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.632 s
[INFO] Finished at: 2018-12-16T01:15:39+00:00
[INFO] Final Memory: 15M/61M
[INFO] ------------------------------------------------------------------------

完了です。 quickstart-se ディレクトリ以下に生成されたファイルを確認します。

:~/quickstart-se$ tree
.
├── pom.xml
├── README.md
└── src
    ├── main
    │   ├── docker
    │   │   └── Dockerfile
    │   ├── java
    │   │   └── io
    │   │       └── helidon
    │   │           └── examples
    │   │               └── quickstart
    │   │                   └── se
    │   │                       ├── GreetService.java
    │   │                       ├── Main.java
    │   │                       └── package-info.java
    │   ├── k8s
    │   │   └── app.yaml
    │   └── resources
    │       ├── application.yaml
    │       └── logging.properties
    └── test
        └── java
            └── io
                └── helidon
                    └── examples
                        └── quickstart
                            └── se
                                └── MainTest.java

18 directories, 10 files

なんと、DockerfileとKubernetesマニフェストファイル(yaml)が同時に生成されています。 これはコンテナ界隈のお兄さんたちも大喜びですね。

Dockerfile

FROM openjdk:8-jre-alpine

RUN mkdir /app
COPY libs /app/libs
COPY ${project.artifactId}.jar /app

CMD ["java", "-jar", "/app/${project.artifactId}.jar"]

app.yml

kind: Service
apiVersion: v1
metadata:
  name: ${project.artifactId}
  labels:
    app: ${project.artifactId}
spec:
  type: NodePort
  selector:
    app: ${project.artifactId}
  ports:
  - port: 8080
    targetPort: 8080
    name: http
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: ${project.artifactId}
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: ${project.artifactId}
        version: v1
    spec:
      containers:
      - name: ${project.artifactId}
        image: ${project.artifactId}
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---

パッケージを生成

以下のMavenコマンドでパッケージを生成します。

$ mvn package

出力ログ

[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< io.helidon.examples:quickstart-se >------------------
[INFO] Building quickstart-se 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ quickstart-se ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
---略---
[INFO]
[INFO] --- maven-jar-plugin:2.5:jar (default-jar) @ quickstart-se ---
[INFO] Building jar: /home/vagrant/quickstart-se/target/quickstart-se.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  17.838 s
[INFO] Finished at: 2018-12-16T02:42:31Z
[INFO] ------------------------------------------------------------------------

targetディレクトリにquickstart-se.jarが生成されたことを確認します。

$ ls target/quickstart-se.jar
target/quickstart-se.jar

アプリケーションを実行

$ java -jar target/quickstart-se.jar

出力ログ

[DEBUG] (main) Using Console logging
2018.12.16 02:48:36 INFO io.netty.util.internal.PlatformDependent Thread[main,5,main]: Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability.
2018.12.16 02:48:36 INFO io.helidon.webserver.netty.NettyWebServer Thread[nioEventLoopGroup-2-1,10,main]: Channel '@default' started: [id: 0x029b3dce, L:/0:0:0:0:0:0:0:0:8080]
WEB server is up! http://localhost:8080

これで完了です!ブラウザやcurlでアクセスしてみます。

$curl -X GET http://localhost:8080/greet
{"message":"Hello World!"}

$curl -X GET http://localhost:8080/greet/Joe
{"message":"Hello Joe!"}

$curl -X PUT http://localhost:8080/greet/greeting/Hola
{"greeting":"Hola"}

$curl -X GET http://localhost:8080/greet/Jose
{"message":"Hola Jose!"}

とても簡単にRESTサービスが作成できました。

今回はここまでにして、次回は生成されたDockerfile、yamlを使ってKubernetes上で起動してみたいと思います。

ご覧いただきありがとうございました。

ちなみに、Helidonはギリシア語でつばめ(swallow)を意味するのだそうです。 Wikipediaによると、細長い、合理化されたボディーと長い尖った羽根があり、素晴らしい操縦性と非常に効率的な飛行が可能な鳥だそうです。 雲(Cloud)の中を飛び回るのに最適ですね。

この記事はOracle Cloud その2 Advent Calendar 2018 - Adventar16日目です。