OpenShiftの再現環境作成のコツ - 第3回 ランタイムイメージの利用

OpenShiftの再現環境作成のコツ - 第3回 ランタイムイメージの利用

こんにちは、Red Hat Partner Technical Account Managerのイアンです。

シリーズの前回では、ローカルのソースコードをビルドし、OpenShiftにデプロイする方法を紹介しました。 しかし、ビルダーイメージをそのまま使っていましたので、ビルド用のツール(Maven、s2i)が残って、イメージのサイズが大きくなりました。

当記事では、ビルダーイメージとランタイムイメージの両方を使って、アプリのビルドとデプロイを行います。

当シリーズ

目次

事前準備

前回の記事を参照して、 helloworld-rs アプリを用意してください。

また、前回の sandbox のプロジェクトがあれば、一旦削除してから再作成してください。 当記事では同じプロジェクト名を使います。

ビルドの流れ

今までのビルドの流れは次です:

JBoss EAP Builder Imageの中にアプリのビルドを行い、eap-appというImageStreamにプッシュしました。

これからは、JBoss EAP Runtime Imageを加えて、ビルドの流れを次のように変更します。

eap-app のイメージを中間イメージとして使って、ランタイムイメージを使っているもう一つのビルドを実行し、最終イメージを作ります。

デプロイの流れ

大まかな流れは次です:

  1. ImageStreamと2つのBuildConfigを作成する
  2. ビルドを行う
  3. DeploymentConfigを作成する
  4. ServiceとRouteを作成し、アプリを公開する

ImageStreamの作成

中間イメージを管理するため、2つのImageStreamを作ります。

$ oc create imagestream eap-app
$ oc create imagestream eap-app-build-artifacts

前回のように、分かりやすいラベルも付けます。

$ oc label is/eap-app application=eap-app
$ oc label is/eap-app-build-artifacts application=eap-app

BuildConfigの作成

中間イメージ用

中間イメージのBuildConfigは前回とほぼ変わっていませんが、保存先を eap-app-build-artifacts:latestImageSteamに変更しました。

YAMLを buildconfig-artifacts.yaml に保存し、oc create -f buildconfig-artifacts.yamlコマンドでBuildConfigを作成します。

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: eap-app-artifacts
  labels:
    application: eap-app
spec:
  runPolicy: Serial
  source:
    type: Binary
  strategy:
    sourceStrategy:
      env:
      - name: GALLEON_PROVISION_LAYERS
        value: jaxrs-server
      from:
        kind: ImageStreamTag
        name: jboss-eap74-openjdk11-openshift:latest
        namespace: sandbox
    type: Source
  output:
    to:
      kind: ImageStreamTag
      name: eap-app-build-artifacts:latest

Runtimeイメージ用

次は、ランタイムイメージ用のBuildConfigを作ります。

内容はeap74-basic-s2iのテンプレートを参照して作りました。

YAMLを buildconfig-runtime.yaml に保存し、oc create -f buildconfig-runtime.yamlコマンドでBuildConfigを作成します。

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: eap-app
  labels:
    application: eap-app
spec:
  runPolicy: Serial
  source:
    dockerfile: |
      FROM jboss-eap74-openjdk11-runtime-openshift:latest
      COPY /server /opt/eap
      USER root
      RUN chown -R jboss:root /opt/eap && chmod -R ug+rwX /opt/eap
      USER jboss
      CMD /opt/eap/bin/openshift-launch.sh
    images:
    - from:
        kind: ImageStreamTag
        name: eap-app-build-artifacts:latest
      paths:
      - destinationDir: .
        sourcePath: /s2i-output/server
    type: Dockerfile
  strategy:
    dockerStrategy:
      from:
        kind: ImageStreamTag
        name: jboss-eap74-openjdk11-runtime-openshift:latest
        namespace: sandbox
    type: Docker
  output:
    to:
      kind: ImageStreamTag
      name: eap-app:latest
  triggers:
  - imageChange:
      from:
        kind: ImageStreamTag
        name: eap-app-build-artifacts:latest
    type: ImageChange
  - type: ConfigChange

このBuildConfigは中間イメージの eap-app-build-artifacts:latestImageStreamが更新されたら、自動的にビルドを開始するためのTriggerを使っています。

ビルド開始

helloworld-rs ディレクトリに移動し、次のoc start-build...を実行します。 中間イメージのビルド名 eap-app-build-artifacts を使っていることにご注意ください。

$ oc start-build eap-app-build-artifacts --from-dir=. -F
Uploading directory "." as binary input for the build ...

Uploading finished
build.build.openshift.io/eap-app-1 started
Receiving source from STDIN as archive ...
...
Writing manifest to image destination
Storing signatures
Successfully pushed image-registry.openshift-image-registry.svc:5000/sandbox/eap-app-build-artifacts@sha256:c2886f188bf30e9909ad7b2055640050f0e7ed42aa44a467fcdec9435131de51
Push successful

eap-app-build-artifacts のビルドが終わると、 eap-app のビルドが動きます。

oc statusコマンドで状況を確認できます。

DeploymentConfig作成

ランタイムイメージを使って、イメージを作成しました。 次はそのイメージを使ってアプリをデプロイします。

次のYAMLを deploymentconfig.yaml に保存し、oc create -f deploymentconfig.yamlコマンドでDeploymentConfigを作成します。

kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: eap-app
  labels:
    application: eap-app
spec:
  replicas: 1
  selector:
    deploymentconfig: eap-app
  template:
    metadata:
      labels:
        application: eap-app
        deploymentconfig: eap-app
    spec:
      containers:
      - env:
        - name: ENABLE_ACCESS_LOG
          value: "true"
        image: sandbox/eap-app
        imagePullPolicy: Always
        name: eap-app
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 30
  triggers:
  - type: ConfigChange
  - imageChangeParams:
      automatic: true
      containerNames:
      - eap-app
      from:
        kind: ImageStreamTag
        name: eap-app:latest
        namespace: sandbox
    type: ImageChange

デプロイの確認

DeploymentConfigが作成されたら、すぐアプリのデプロイが開始され、Podが起動されます。

$ oc get pods -l deploymentconfig=eap-app
NAME              READY   STATUS    RESTARTS   AGE
eap-app-1-f5v29   1/1     Running   1          50s

Pod上の稼働確認

第2回には、ServiceRouteの作成とアプリの公開方法を説明しましたので、今回は割愛します。

Podを起動しましたので、Podに入り、EAPアプリにアクセスしてみます。

$ oc rsh eap-app-1-f5v29
sh-4.4$ curl -w "\n" http://localhost:8080/rest/json
{"result":"Hello World!"}
sh-4.4$ exit
$

イメージサイズの確認

前回の最後の方に、ビルダーイメージのイメージサイズが 680MB ほどだったことを伝えました1

今回作ったランタイムイメージのサイズは 440MB ほどになりました2。 200MBぐらい小さくなりました。

再デプロイ

アプリを再デプロイしたい場合は、eap-app-build-artifacts のビルドのstart-buildをします。

eap-app ビルドとDeploymentConfigにイメージ変更時のTriggerを設定したため、自動的に再ビルドとデプロイが走ります。

まとめ

ビルダーイメージとランタイムイメージを合わせて、お客様が実際にご利用する s2i の仕組みに近づくことができました。

このシリーズで紹介したやり方を用いて、OpenShiftにサンプルアプリを簡単にデプロイすることができました。トラブルシュートするときは役に立てば幸いです。


  1. skopeoを使ってビルダーイメージの中の各レイヤーのサイズを合計します。

    skopeo inspect --tls-verify=false docker://default-route-openshift-image-registry.apps-crc.testing/sandbox/eap-app-build-artifacts | jq '[.LayersData[]|.Size]|add'
    683121920
    
  2. skopeoを使ってランタイムイメージの中の各レイヤーのサイズを合計します。

    skopeo inspect --tls-verify=false docker://default-route-openshift-image-registry.apps-crc.testing/sandbox/eap-app | jq '[.LayersData[]|.Size]|add'
    446811269
    

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。