22
9

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 3 years have passed since last update.

OpenShiftAdvent Calendar 2019

Day 16

OpenShift ImageStream は何をしてくれるのか

Last updated at Posted at 2019-12-15

ImageStream 概要

ImageStream1 は OpenShift のリソースの 1 つです。コンテナイメージそのものは含まず、コンテナイメージを参照を行うためのリソースとなります。コンテナイメージの参照を抽象化し、ImageStream とタグによって利用可能なイメージを管理します。
OpenShift DeploymentConfig に指定することができますが、ImageStream を指定せずに直接コンテナイメージの URL やタグを指定することも可能です。

疑問点

ここで 1つ 気になる点が出てきます。ImageStream を DeploymentConfig に指定せずに利用できるのであれば、ImageStream の存在意義とは何でしょうか? ImageStream を利用することで、DeploymentConfig の ImageChange Trigger2 を利用することができますが、それだけでしょうか? コンテナイメージ変更を契機に Pod の Updaet を行わない場合は不要となるのでしょうか。

ImageStream を利用しない場合

DeploymentConfig によるコンテナのデプロイ

サンプルとして OpenShift で私がよくデプロイする ruby-ex アプリケーションを利用します。デプロイに必要なリソースは oc new-app コマンドで予め作成しておきます。

oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git

コマンド実行完了後、利用しない DeploymentConfig を削除しておきます。

oc delete dc ruby-ex

ここで ImageStream を利用しない方法で DeploymentConfig を定義してみます。

oc create -f ruby-ex-without-is.yaml

ruby-ex-without-is.yaml の詳細は次のとおりです。spec.template.containers[0].image に直接コンテナイメージの URL とタグが記載されています。

dc/ruby-ex-without-is.yaml
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  creationTimestamp: null
  generation: 1
  labels:
    app: ruby-ex
  name: ruby-ex
  selfLink: /apis/apps.openshift.io/v1/namespaces/without-is/deploymentconfigs/ruby-ex
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    app: ruby-ex
    deploymentconfig: ruby-ex
  strategy:
    activeDeadlineSeconds: 21600
    resources: {}
    rollingParams:
      intervalSeconds: 1
      maxSurge: 25%
      maxUnavailable: 25%
      timeoutSeconds: 600
      updatePeriodSeconds: 1
    type: Rolling
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: ruby-ex
        deploymentconfig: ruby-ex
    spec:
      containers:
      - image: docker-registry.default.svc:5000/without-is/ruby-ex:latest
        imagePullPolicy: Always
        name: ruby-ex
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  test: false
  triggers:
  - type: ConfigChange
status:
  availableReplicas: 0
  latestVersion: 0
  observedGeneration: 0
  replicas: 0
  unavailableReplicas: 0
  updatedReplicas: 0

Pod が正常にデプロイされていることを確認します。

# oc get pod
NAME              READY     STATUS      RESTARTS   AGE
ruby-ex-1-build   0/1       Completed   0          4m
ruby-ex-4-5ffss   1/1       Running     0          32s

レプリカ数を 2 に変更してみます。

# oc scale dc/ruby-ex --replicas 2

コンテナのイメージIDを確認します。とちらの Pod も同じ Image ID を参照していることがわかります。

]# oc describe pod -l app=ruby-ex | grep "Image ID:"
    Image ID:       docker-pullable://docker-registry.default.svc:5000/sample-is/ruby-ex@sha256:ea3dccca08d1cedb5f42d952519c40b6bc8db9b857d280b60180017107f6fc5a
    Image ID:       docker-pullable://docker-registry.default.svc:5000/sample-is/ruby-ex@sha256:ea3dccca08d1cedb5f42d952519c40b6bc8db9b857d280b60180017107f6fc5a

ここでコンテナをビルドし直します。

# oc start-build ruby-ex

ビルド完了後にレプリカ数を 3 へ変更し、Pod が参照している Image ID を確認してみます。ことなるコンテナイメージを参照している Pod が存在していることがわかります。

# oc describe pod -l app=ruby-ex | grep "Image ID:"
    Image ID:       docker-pullable://docker-registry.default.svc:5000/sample-is/ruby-ex@sha256:ea3dccca08d1cedb5f42d952519c40b6bc8db9b857d280b60180017107f6fc5a
    Image ID:       docker-pullable://docker-registry.default.svc:5000/sample-is/ruby-ex@sha256:9e0dfb3183cf741b3092d5482467e4a327040e5cc9646017828213dc438f4665
    Image ID:       docker-pullable://docker-registry.default.svc:5000/sample-is/ruby-ex@sha256:ea3dccca08d1cedb5f42d952519c40b6bc8db9b857d280b60180017107f6fc5a

何が起きたのでしょうか。DeploymentConfig に指定したコンテナイメージの URL とタグは変更していません。

そうです。タグは変えていませんが、先程実施したコンテナビルドにより、タグが参照しているイメージが変更となりました。

ImageStream を利用した場合

ImageStream を指定した場合の DeploymentConfig

まず、ImageStream を利用した DeploymentConfig を作成します。ImageStream を利用した DeploymentConfig の一番簡単な作成方法は oc new-app を利用することです。

oc コマンドでプロジェクト作成時にサンプルとして出力される例をそのまま利用します。

oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git
出力例
--> Found Docker image dc0e72c (4 weeks old) from Docker Hub for "centos/ruby-25-centos7"

    Ruby 2.5 
    -------- 
    Ruby 2.5 available as container is a base platform for building and running various Ruby 2.5 applications and frameworks. Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, and extensible.

    Tags: builder, ruby, ruby25, rh-ruby25

    * An image stream tag will be created as "ruby-25-centos7:latest" that will track the source image
    * A source build using source code from https://github.com/sclorg/ruby-ex.git will be created
      * The resulting image will be pushed to image stream tag "ruby-ex:latest"
      * Every time "ruby-25-centos7:latest" changes a new build will be triggered
    * This image will be deployed in deployment config "ruby-ex"
    * Port 8080/tcp will be load balanced by service "ruby-ex"
      * Other containers can access this service through the hostname "ruby-ex"

--> Creating resources ...
    imagestream.image.openshift.io "ruby-25-centos7" created
    imagestream.image.openshift.io "ruby-ex" created
    buildconfig.build.openshift.io "ruby-ex" created
    deploymentconfig.apps.openshift.io "ruby-ex" created
    service "ruby-ex" created
--> Success
    Build scheduled, use 'oc logs -f bc/ruby-ex' to track its progress.
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose svc/ruby-ex' 
    Run 'oc status' to view your app.

Image更新を検出して勝手にアップデートされないようにトリガーはオフにします。

oc set triggers dc/ruby-ex  --manual

設定が完了した DeploymentConfig は次のとおりです。ImageStream がない場合の違いがあります。Image に指定されているのがURLとタグではなく、URLとハッシュタグとなりました。
また、triggers が設定されており、ImageChange に ImageStream とタグが指定されています。

dc/ruby-ex.yaml
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: null
  generation: 1
  labels:
    app: ruby-ex
  name: ruby-ex
  selfLink: /apis/apps.openshift.io/v1/namespaces/is/deploymentconfigs/ruby-ex
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    app: ruby-ex
    deploymentconfig: ruby-ex
  strategy:
    activeDeadlineSeconds: 21600
    resources: {}
    rollingParams:
      intervalSeconds: 1
      maxSurge: 25%
      maxUnavailable: 25%
      timeoutSeconds: 600
      updatePeriodSeconds: 1
    type: Rolling
  template:
    metadata:
      annotations:
        openshift.io/generated-by: OpenShiftNewApp
      creationTimestamp: null
      labels:
        app: ruby-ex
        deploymentconfig: ruby-ex
    spec:
      containers:
      - image: docker-registry.default.svc:5000/is/ruby-ex@sha256:ad60376e709fec2764d249327cc8a1cb6f5b085c392f95b8c786ff67875e74bf
        imagePullPolicy: Always
        name: ruby-ex
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  test: false
  triggers:
  - imageChangeParams:
      containerNames:
      - ruby-ex
      from:
        kind: ImageStreamTag
        name: ruby-ex:latest
        namespace: is
    type: ImageChange
status:
  availableReplicas: 0
  latestVersion: 0
  observedGeneration: 0
  replicas: 0
  unavailableReplicas: 0
  updatedReplicas: 0

Pod のレプリカ数を 2 に変更します。

# oc scale dc/ruby-ex --replicas 2

Pod のイメージIDを確認します。どちらも同じイメージが参照されています。

 oc describe pod -l app=ruby-ex | grep "Image ID:"
    Image ID:       docker-pullable://docker-registry.default.svc:5000/is/ruby-ex@sha256:8ebf0e1e2016241077934270246353d15742afa2d45b521d77fac399c9e0e32b
    Image ID:       docker-pullable://docker-registry.default.svc:5000/is/ruby-ex@sha256:8ebf0e1e2016241077934270246353d15742afa2d45b521d77fac399c9e0e32b

コンテナイメージをビルドします。

# oc start-build ruby-ex

レプリカ数を 3 に変更した後に、コンテナイメージの ID を確認します。すべて同じイメージを参照していることがわかります。

# oc describe pod -l app=ruby-ex | grep "Image ID:"
    Image ID:       docker-pullable://docker-registry.default.svc:5000/is/ruby-ex@sha256:e7e2ce3f129d1d98b615ed8efd157a281a0aeee5760efb04e074c3cda39df78b
    Image ID:       docker-pullable://docker-registry.default.svc:5000/is/ruby-ex@sha256:e7e2ce3f129d1d98b615ed8efd157a281a0aeee5760efb04e074c3cda39df78b
    Image ID:       docker-pullable://docker-registry.default.svc:5000/is/ruby-ex@sha256:e7e2ce3f129d1d98b615ed8efd157a281a0aeee5760efb04e074c3cda39df78b

まとめ

タグを変えずにコンテナイメージをビルドした場合、Pod をスケールさせた場合異なるバージョンのイメージを参照してしまう事象を確認しました。これを回避するためには、タグを分けるという手段もありますが、ImageStream を利用すればハッシュ値を利用してこの問題を解決することも可能であるということがわかりました。

今回は ImageSteam の1つの役割について確認しました。その他の ImageStream の詳細については製品ドキュメント3を参照して貰えればと思います。

  1. OpenShift Container Platform 4.2 - Understanding containers, images, and imagestreams

  2. OpenShift Container Platform 4.2 - Deployment triggers

  3. OpenShift Container Platform 4.2 - Using imagestreams

22
9
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
22
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?