[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テナンシーを準備し、初めてのサービスを書いてデプロイしました。今後のポストではマイクロサービスを作成する他のいくつかの方法を調べてみるつもりです、ものごとのコーディング面をもうちょっと楽にするために。

0 件のコメント:

コメントを投稿