ラベル Microservices の投稿を表示しています。 すべての投稿を表示
ラベル Microservices の投稿を表示しています。 すべての投稿を表示

[GraalVM] Oracle CloudでのGraalVM Enterprise EditionとMicronautを使ったマイクロサービスの開発/Developing Microservices with GraalVM Enterprise Edition + Micronaut on Oracle Cloud

原文はこちら


マイクロサービスはこのところ急発展しているテクノロジーのひとつであり、メインストリームでの適用が始まりつつあります。その理由としてコンテナやクラウドなどの他の新興のテクノロジーを挙げることもできますが、最も重要な理由はアジャイル、スケーラブル、高速性へのビジネス上の要求でしょう。Dion HinchcliffeによるWhy Microservices Will Become a Core Business Strategy for Most Organizationsという記事に、マイクロサービスがどのようなビジネス上のインパクトをもたらすのかについてよくまとめられています。

なぜOracle GraalVM Enterprise Editionなのか? 

GraalVM Enterprise Edition 19.0はOracleが製品化に向けた研究開発への数年間の投資の末にリリースした新製品で、商用デプロイメントの準備もできています。GraalVM Enterprise Editionは高性能、組み込み可能、ポリグロットな仮想マシンです。JavaScript、Python、Ruby、JavaやScala、KotlinといったJVMベースの言語、そしてCやC++のようなLLVMベースの言語で書かれたアプリケーションを稼働させることができ、プログラミング言語間での効率的なインターオペラビリティを提供します。GraalVM Enterprise Editionにどのような利点があるのかはこのウェブサイトでご覧になれます。

GraalVM Enterprise Editionとマイクロサービスが交わるところ

GraalVM Enterprise Editionの機能のひとつとしてネイティブイメージがあり(執筆時点ではEarly Adopterとして利用可能です)、これは多くのJavaのマイクロサービスフレームワークと組み合わせることができます。Quarkus、MicronautやHelidonといったプロジェクトがこの技術を受容し、ネイティブイメージで実行時のメモリ要求サイズと起動時間を大きく抑制しています。

この記事は?

この記事では、Oracle Cloud Infrastructure (OCI)上でGraalVM Enterprise EditionとMicronautを使用したマイクロサービスを開発する方法をご紹介します。上記の図は、ここで使うことになるクラウドサービスと、それらが互いにどのようにやり取りするかを示しています。

はじめてみよう(Windows 10を使った場合)

ステップの概覧
Summary of steps in this hands-on exercise

Step 1: 前提ソフトウェアのインストール

  • IntelliJ CE for Windows (わたしの好みです)
  • プラグイン: GIT, Terraform, Docker
  • Docker for Windows 10 (ネイティブイメージの生成時にシステムが終了してしまう場合はメモリ割り当てを増やしてください)
  • Micronaut
  • KubeCtl
  • OCI Tool for Windows

Step 2: ODCSでのプロジェクト作成

Project provisioning on ODCS
  • チームで実施している場合は、チームメンバーを追加して適切な権限を割り当ててください。

Step 3 (オプショナル): IntelliJを使って開発

コードや設定に変更を加えない場合はステップ4にそのまま進んでください。
  • プロジェクトをチェックアウト
  • IntelliJ → VCS | Checkout from Version Control | Git

Step 4: OCIRでのDockerリポジトリのセットアップ

  • リポジトリの作成――リポジトリ名はwercker.yml / kubernetes_deployment.template.yamlでの修正に使われます
  • リポジトリをパブリックに設定(これによりシークレットの設定のためのステップを省くことができます。K8Sシークレットの扱いになれているのであれば、プライベートに設定してそのステップを行ってください)

Step 5: OKEインスタンスのセットアップ

There are 2 ways that you can setup OKEのセットアップにはふたつのやりかたがあります。Web UIを使う方法(こちらにチュートリアルがあります)と、terraform scriptを使う方法です。
OKEインスタンスを無事に作成したら、ステップ8で必要になるWercker環境の変数を取得しておきましょう。
こちらのマニュアルにあるように、あなたのKubernetesが稼働していることを確認してください。
  • 自分のkubeconfigのダウンロード
  • 自分のKubernetes Dashboardを表示

Step 6: Werckerのセットアップ

  • Werckerにログインして、(+) をクリックして“Add Application”をクリック。出てくるウィザードを進めていきます。
  • ユーザーを選んで、SCMはOracle Developer Cloud Serviceを選んでください。
  • このプロジェクト用に作成しておいたリポジトリを選んで、セットアップウィザードは完了です。

Step 7: Werckerパイプラインの作成

サンプルコードでは、ワークフローの中でふたつのパイプラインが出てきます(build、deploy-to-oke)。このパイプラインはMasterブランチに新しいチェックインがプッシュされたときに起動されます。buildパイプラインでコードをコンパイルし、Dockerイメージを作成してイメージリポジトリにプッシュします。その後deploy-to-okeパイプラインが新しく作成されたイメージをOCIRから取得し、OKEにデプロイします。
こちらご覧いただくとWerckerの一般的な見本が見つかります。

Step 8: Wercker環境の定義

このチュートリアルで重要になる環境変数です。以下がWerckerパイプラインのために必要な変数です。

Step 9: 設定ファイルの修正とWerckerパイプラインの起動

  • wercker.ymlとkubernetes_deployment.template.yamlを修正します (#TODO:とマークされた行を編集します)
  • ファイルをコミットし、masterブランチにプッシュすることでWerckerパイプラインをトリガーします

Step 10: K8sダッシュボードをチェックし、アプリケーションにアクセス

  • http://<external_endpoints>/meetup/random をブラウザに入力(Random conferences)
  • http://<external_endpoints>/abs/java/<number> をブラウザに入力(Absolute number)

GraalVM Enterprise Editionに今すぐトライ
GraalVM Enterprise Editionは開発用途、評価用途には無料でOracle Technology Networkからダウンロードできます。 
GraalVM Enterprise Editionの購入も可能で、Oracle Cloud上では無料で利用可能です。
GraalVM Enterprise EditionのドキュメントはOracle documentationのページで閲覧可能です。
graalvm.orgのブログをウォッチして、新しい情報もゲットしましょう。
コードのクレジットはJoseph Cheにあります。

[Microservices]Hibernateを使ったHelidonマイクロサービスの作成とデプロイ パート3/ Building And Deploying A Helidon Microservice With Hibernate Part 3

原文はこちら

このブログシリーズではここまで長い道のりを旅してきました――マイクロサービスをデプロイするためのクラウドテナンシーを準備するところから、Helidonを使って初めてのマイクロサービスを書くところまで。このポストではついにマイクロサービスをOracle Cloudにデプロイします。あなたがこのシリーズは初めてだったら、キャッチアップするために先に以下のポストを読んでおいたほうがいいでしょう:

The first step in deploying our microservice to the Oracle Cloud is to build a Docker image containing our application and push that image to our OCIR Docker Registry that we configured previously. When we scaffolded the Helidon application from the Maven archetype you may or may not have noticed, but Helidon gave us a Dockerfile and app.yaml out of the box that looked similar to this:
Oracle Cloudへのマイクロサービスのデプロイの最初のステップは、アプリケーションを含んだDockerイメージを構成し、それを以前に準備したOCIR Docker Registryにプッシュすることです。HelidonアプリケーションをMavenアーキタイプから組み上げたときに、お気づきだったかわかりませんが、Helidonは以下のような Dockerfile と app.yaml を作っておいてくれています:
# 1st stage, build the app
FROM maven:3.5.4-jdk-9 as build
WORKDIR /helidon
# Create a first layer to cache the "Maven World" in the local repository.
# Incremental docker builds will always resume after that, unless you update
# the pom
ADD pom.xml .
RUN mvn package -DskipTests
# Do the Maven build!
# Incremental docker builds will resume here when you change sources
ADD src src
RUN mvn package -DskipTests
RUN echo "done!"
# 2nd stage, build the runtime image
FROM openjdk:8-jre-slim
WORKDIR /helidon
# Copy the binary built in the 1st stage
COPY --from=build /helidon/target/user-svc.jar ./
COPY --from=build /helidon/target/libs ./libs
CMD ["java", "-jar", "user-svc.jar"]
EXPOSE 8080
view rawDockerfile hosted with ❤ by GitHub
アプリケーションに何も変更を加えていなかったのであればこの Dockerfile をそのまま使ってイメージを構成、プッシュしてもよかったんですが、アプリケーションにいくつか手を加えているため、この Dockerfile には少し修正が必要です。OJDBCの依存モジュールを追加してローカルにインストールし、ビルドに含められるようにしておきます。他に必要となる修正として、Walletファイルがコンテナに入るようにし(これをVolumeとしてマウントするようにもできるんですが、このブログポストは初心者向けのシリーズなのでできるだけものごとをシンプルにしておきたいんです)、JARを起動したときに適切に設定が行われるようCMDを修正しておきます。
修正した Dockerfile は以下のようになります:
# 1st stage, build the app
FROM maven:3.5.4-jdk-9 as build
WORKDIR /helidon
ENV MAVEN_OPTS -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.nonProxyHosts= -Dmaven.repo.local=/usr/share/maven/ref/repository
ADD pom.xml .
ADD build-resource/libs/* /helidon/build-resource/libs/
RUN ["mvn", "install:install-file", "-Dfile=/helidon/build-resource/libs/ojdbc8.jar", "-DgroupId=com.oracle.jdbc", "-DartifactId=ojdbc8", "-Dversion=18.3.0.0", "-Dpackaging=jar"]
RUN ["mvn", "install:install-file", "-Dfile=/helidon/build-resource/libs/oraclepki.jar", "-DgroupId=com.oracle.jdbc", "-DartifactId=oraclepki", "-Dversion=18.3.0.0", "-Dpackaging=jar"]
RUN ["mvn", "install:install-file", "-Dfile=/helidon/build-resource/libs/osdt_core.jar", "-DgroupId=com.oracle.jdbc", "-DartifactId=osdt_core", "-Dversion=18.3.0.0", "-Dpackaging=jar"]
RUN ["mvn", "install:install-file", "-Dfile=/helidon/build-resource/libs/osdt_cert.jar", "-DgroupId=com.oracle.jdbc", "-DartifactId=osdt_cert", "-Dversion=18.3.0.0", "-Dpackaging=jar"]
ADD src src
RUN mvn package -DskipTests
# 2nd stage, build the runtime image
FROM openjdk:8-jre-slim
WORKDIR /helidon
# Copy the binary built in the 1st stage
COPY --from=build /helidon/target/user-svc.jar ./
COPY --from=build /helidon/target/libs ./libs
RUN mkdir wallet
COPY /build-resource/wallet/* ./wallet/
EXPOSE 8080
CMD ["sh", "-c", "java -jar -Ddatasource.username=$DB_USER -Ddatasource.password=$DB_PASSWORD -Ddatasource.url=$DB_URL -Doracle.net.wallet_location=/helidon/wallet -Doracle.net.authentication_services=\"(TCPS)\" -Doracle.net.tns_admin=/helidon/wallet -Djavax.net.ssl.trustStore=/helidon/wallet/cwallet.sso -Djavax.net.ssl.trustStoreType=SSO -Djavax.net.ssl.keyStore=/helidon/wallet/cwallet.sso -Djavax.net.ssl.keyStoreType=SSO -Doracle.net.ssl_server_dn_match=true -Doracle.net.ssl_version=1.2 user-svc.jar"]
view rawDockerfile hosted with ❤ by GitHub
これでイメージを以下のコマンドでビルドできるようになりました:
docker build -t phx.ocir.io/toddrsharp/cloud-native-microservice/user-svc-helidon:latest .
このコマンドは新しくビルドされたイメージをOCIRレジストリにプッシュするのに適切なフォーマットでタグ付けします。ここで私がPhoenixリージョンを使っていることに注意してください――もしあなたが他のリージョンを使っているのであれば、あなたのURLは変わります。OCIR URLのフォーマットは以下のようなかたちです:
[region].ocir.io/[tenancy]/[repository-name]/[docker-image-name]:[tag]
このイメージは以下のコマンドで実行することができます:
docker run                                                                                                                                                                     
--env DB_USER=[username] \
--env DB_URL="jdbc:oracle:thin:@[tnsname]?TNS_ADMIN=/helidon/wallet" \
--env DB_PASSWORD=[password] \
-p 8080:8080 \
-t phx.ocir.io/toddrsharp/cloud-native-microservice/user-svc-helidon:latest
view rawdocker-run.sh hosted with ❤ by GitHub
The app is now up and running in a local Docker container just as it did when we ran the JAR file locally in the last post. Stop the local container and let's move on to pushing the image to our OCIR registry. That's pretty simple too:
これでアプリケーションが起動され、この前のポストでJARファイルをローカルで動かしたときとちょうど同じように、ローカルDockerコンテナで稼働しています。ローカルコンテナを停止してOCIRレジストリへのプッシュに進みましょう。これもとてもかんたんです:
docker push phx.ocir.io/toddrsharp/cloud-native-microservice/user-svc-helidon:latest 
OCIRダッシュボードで以下のようにイメージが確認できます:
ではこのDockerイメージのKubernetesクラスターへのデプロイに進みましょう。ここでデプロイメントのためにふたつのKubernetesシークレットの作成が必要です。ひとつはKubernetesがイメージをプルするときの認証のためのDockerレジストリー認証情報で、もうひとつはDockerfileにハードコーディングせずにアプリケーションの認証情報をDockerコンテナに渡すために使うものです。
レジストリの認証情報を以下のように作りましょう(ここでパスワードはBase64エンコードされていません):
kubectl create secret docker-registry regcred \
--docker-server=[region].ocir.io \
--docker-username=[tenancy]/[docker user] \
--docker-password="[docker auth token]" \
--docker-email=[docker email (if set when creating user)]
view rawcreate-regcred.sh hosted with ❤ by GitHub
次にアプリケーションのシークレット用に、secret.yamlというファイルを作って以下のように記載しましょう(ご自身のBase64エンコードされた値を使ってください):
apiVersion: v1
kind: Secret
metadata:
  name: user-svc-helidon-secrets
data:
  dbUser: [base64 encoded username]
  dbPassword: [base64 encoded password]
  dbUrl: [base64 encoded URL]
---
view rawsecret.yaml hosted with ❤ by GitHub
クラスターでシークレットを作成するには以下を実行:
kubectl create -f secret.yaml
そして app.yaml を修正してKubernetesデプロイメントを完成させましょう。生成されたファイルにいくつかの修正を加えますが、これはとてもシンプルなフォーマットです。コンテナ起動時にわれわれのシークレットから渡された値が適切に使用されるように、DockerコンテナのCMDをオーバーライドする必要があることに注意してください。でなければ、ここでやっていることはクラスター上のわれわれのサービスとDockerコンテナを表すデプロイメントを公開するためのKubernetesサービスを作成することです。Kubernetesに対してイメージの場所(OCIR内)と、イメージをデプロイする際に置き換えるべきシークレットの設定およびプレースホルダーを伝えてやっています。
以下が私の場合の修正した app.yamlです:
kind: Service
apiVersion: v1
metadata:
  name: user-svc-helidon
  labels:
    app: user-svc-helidon
spec:
  type: LoadBalancer
  selector:
    app: user-svc-helidon
  ports:
  - port: 8080
    targetPort: 8080
    name: http
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: user-svc-helidon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: user-svc-helidon
        version: v1
    spec:
      containers:
      - name: user-svc-helidon
        image: phx.ocir.io/toddrsharp/cloud-native-microservice/user-svc-helidon:latest
        command: ["java", "-jar"]
        args:
        - "-Doracle.net.wallet_location=/helidon/wallet"
        - "-Doracle.net.authentication_services=(TCPS)"
        - "-Doracle.net.tns_admin=/helidon/wallet"
        - "-Djavax.net.ssl.trustStore=/helidon/wallet/cwallet.sso"
        - "-Djavax.net.ssl.trustStoreType=SSO"
        - "-Djavax.net.ssl.keyStore=/helidon/wallet/cwallet.sso"
        - "-Djavax.net.ssl.keyStoreType=SSO"
        - "-Doracle.net.ssl_server_dn_match=true"
        - "-Doracle.net.ssl_version=1.2"
        - "-Ddatasource.username=$(DB_USER)"
        - "-Ddatasource.password=$(DB_PASSWORD)"
        - "-Ddatasource.url=$(DB_URL)"
        - "user-svc.jar"
        env:
          - name: DB_USER
            valueFrom:
              secretKeyRef:
                name: user-svc-helidon-secrets
                key: dbUser
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: user-svc-helidon-secrets
                key: dbPassword
          - name: DB_URL
            valueFrom:
              secretKeyRef:
                name: user-svc-helidon-secrets
                key: dbUrl
        imagePullPolicy: Always
        ports:
          - containerPort: 8080
      imagePullSecrets:
      - name: regcred
---
view rawapp.yaml hosted with ❤ by GitHub
そして以下でデプロイできます:
kubectl create -f app.yaml
デプロイメントの確認は以下で:
kubectl get deployments
ポッドが作成されたことを確認するには:
kubectl get pods
最後に、サービスが作成されてIPアドレスが割り振られていること(これには数分かかります)を確認しましょう:
kubectl get services
全部うまくいっているかどうか、リクエストを投げてみましょう:
残念ながらエラーが発生しました!何が起きているのかポッドログを見てみましょう:
kubectl logs user-svc-helidon-69688b4fd6-l5gqt 
どうもわれわれのコードはJava 9の機能を使っているのにJava 8ベースのDockerイメージにデプロイしているということのようです。これはかんたんに修正できます。Dockerfileを修正して openjdk:9-jre-slim ランタイムイメージを使うようにしてから、Dockerイメージをリビルドして再度プッシュしましょう。アプリケーションの再デプロイのためにデプロイメントを再作成する必要はありません、単に既存のポッドを削除してやれば新しいポッドがOCIRからプルされた最新のイメージを使って作成されます:
kubectl delete pod user-svc-helidon-69688b4fd6-l5gqt
これでもういちどリクエストを投げてやると、全部うまくいくはずです!
ユーザーのリスト取得をすると適切なレスポンス(DB上にいくつかユーザーを既に作っているものと思ってください)を返しており、ATPへの接続がたしかにできていることがわかります:
というわけで以上です!このシリーズでは、マイクロサービス用にOracle Cloudテナンシーを準備し、初めてのサービスを書いてデプロイしました。今後のポストではマイクロサービスを作成する他のいくつかの方法を調べてみるつもりです、ものごとのコーディング面をもうちょっと楽にするために。