めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

OpenShift OriginによるDockerイメージ管理(1)〜イメージストリームを理解する

はじめに

OpenShift OriginでDockerイメージを管理する方法を学ぶ連載です。

今回は、イメージ管理の基礎となる「イメージストリーム(ImageStream)」を解説します。OpenShiftで管理するDockerイメージは専用の内部レジストリーに保存されますが、レジストリー内部のタグではなく、独自の「イメージストリーム」を通して管理する形になります。

(参考資料)
OpenShift Origin Latest/Architecture/Core Concepts/Builds and Image Streams

事前準備

まずは、こちらの手順でOpenShift Originの環境を構築します。

enakai00.hatenablog.com

ローカルで作成したイメージを内部レジストリーにPushするなどの操作をするので、この後は、「Dockerが動いているLinuxにクライアントツールを導入した環境」で作業を進めます。上記の環境であれば、マスターのrootユーザーで作業するのがよいでしょう。OpenShiftの一般ユーザー(enakai)から、テスト用のプロジェクト「project01」を作成しておきます。

# oc login -u enakai
# oc new-project project01 --description="Project to learn image management process" --display-name="Learning Image Management"

イメージのPushによるイメージストリームの作成

内部レジストリーにイメージをPushすると、対応するイメージストリームが自動的に作成されます。Docker HubからCentOS7の公式イメージを取ってきて、Pushしてみます。

# docker pull centos:7
# docker login -u enakai -e enakai@example.com -p $(oc whoami -t) registry.oso.example.com
# docker tag docker.io/centos:7 registry.oso.example.com/project01/centos7:latest
# docker push registry.oso.example.com/project01/centos7:latest

内部レジストリーにPushする際は、「<レジストリー>/<プロジェクト名>/<リポジトリー>:<タグ>」というイメージ名を用います。また、内部レジストリーにログインする際は、「oc whoami -t」で取得されるクレデンシャルを用いると、<プロジェクト名>の部分に、このユーザーが所属するプロジェクトを利用できるようになります。

この時、次のようにリポジトリー「centos7」のイメージストリーム(is)が作成されています。

# oc get is
NAME      DOCKER REPO                           TAGS      UPDATED
centos7   172.30.84.64:5000/project01/centos7   latest    7 seconds ago

# oc describe is centos7
ame:                   centos7
Created:                24 seconds ago
Labels:                 <none>
Annotations:            openshift.io/image.dockerRepositoryCheck=2015-12-28T11:32:19Z
Docker Pull Spec:       172.30.84.64:5000/project01/centos7

Tag     Spec            Created         PullSpec                                                                                                        Image
latest  <pushed>        24 seconds ago  172.30.84.64:5000/project01/centos7@sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9          

イメージストリームのタグ「latest」は、Pushしたイメージのタグを元に付けられたものです。「Spec」はタグ付けの由来を示すもので、「pushed」は、Push時のタグをコピーしたという意味です。イメージストリームのタグは、レジストリー内のタグとは独立しているので注意してください。あくまでPushした際のタグを利用しているだけで、イメージストリーム側でタグを変更しても、レジストリー内のタグは変わりません。「PullSpec」は、レジストリーから実際にこのイメージを取得する方法(「docker pull」の引数)を示します。「172.30.84.64:5000」はレジストリーの内部IPアドレスで、ノードがイメージを取得する時は、このIPアドレスを使用します。(外部から取得する際は、「registry.oso.example.com」に置き換えます。)

そして、ここが重要な点になりますが、OpenShiftからイメージを管理する際は、レジストリー内のタグは意識しないようにしてください。レジストリー内のイメージには、それぞれ、SHA256のハッシュ値が割り当てられており、タグではなく、ハッシュ値で区別されています。上記の「PullSpec」に示された「sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9」という部分がハッシュ値になります。

たとえば、イメージストリーム「centos7」における、タグ「latest」のイメージを取得する場合は、次のように指定します。

# docker pull registry.oso.example.com/project01/centos7@sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9

この時、「docker images」でローカルのイメージを確認すると、タグ名の無いイメージとしてダウンロードされています。次のように「--digests」オプションでハッシュ値が表示されるので、このイメージを指定する際は、上記のように「@sha256:<ハッシュ値>」を付与します。

# docker images --digests
REPOSITORY                                   TAG                 DIGEST                                                                    IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos                             7                   <none>                                                                    60e65a8e4030        3 days ago          196.6 MB
registry.oso.example.com/project01/centos7   latest              <none>                                                                    60e65a8e4030        3 days ago          196.6 MB
registry.oso.example.com/project01/centos7   <none>              sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9   60e65a8e4030        3 days ago          196.6 MB

イメージストリームに話を戻します。イメージストリームでは、過去にイメージをPushした履歴が残ります。イメージをアップデートして、先ほどと同じ「latest」のタグでPushしてみます。

# mkdir work
# cat <<EOF >work/Dockerfile
FROM registry.oso.example.com/project01/centos7:latest
MAINTAINER E.Nakai
RUN yum -y install net-tools
EOF
# docker build -t registry.oso.example.com/project01/centos7:latest work
# docker push registry.oso.example.com/project01/centos7:latest

イメージストリームを見ると次のようになっています。

# oc describe is centos7
Name:                   centos7
Created:                3 minutes ago
Labels:                 <none>
Annotations:            openshift.io/image.dockerRepositoryCheck=2015-12-28T11:32:19Z
Docker Pull Spec:       172.30.84.64:5000/project01/centos7

Tag     Spec            Created         PullSpec                                                                                                        Image
latest  <pushed>        8 seconds ago   172.30.84.64:5000/project01/centos7@sha256:50a63bb73ede37fe35b1448bae81868c63a7ad310b9051f37385818b43a3a188     
                        3 minutes ago   172.30.84.64:5000/project01/centos7@sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9     

イメージストリーム上も後からPushしたイメージに「latest」のタグが付け変わっていますが、以前のイメージの情報も残ってます。これにより、このリポジトリーのイメージがどのように更新されたかが確実にトラッキングできて、かつ、ハッシュ値を指定すれば、過去のイメージを取得することも可能になります。Gitによるソースコード管理では、一度、Commitした情報は未来永劫残り続けますが、これと同じことが実現できているわけです。

イメージストリームへの既存イメージの取り込み

既存のイメージをイメージストリームに取り込むことも可能です。この際、取り込み先のイメージストリームでタグ名を付ける必要があります。次は、イメージストリーム「centos7」の「latest」で指定されるイメージを新たなイメージストリーム「baseos」にタグ名「deploy」で取り込みます。

# oc tag centos7:latest baseos:deploy
# oc describe is baseos
Name:                   baseos
Created:                8 seconds ago
Labels:                 <none>
Annotations:            openshift.io/image.dockerRepositoryCheck=2015-12-28T11:35:39Z
Docker Pull Spec:       172.30.84.64:5000/project01/baseos

Tag     Spec                                                                            Created         PullSpec                                                                                                        Image
deploy  centos7@sha256:50a63bb73ede37fe35b1448bae81868c63a7ad310b9051f37385818b43a3a188 8 seconds ago   172.30.84.64:5000/project01/centos7@sha256:50a63bb73ede37fe35b1448bae81868c63a7ad310b9051f37385818b43a3a188     

この場合、「centos7:latest」がその時点で指しているイメージが取り込まれます。「Spec」の部分には、取り込んだイメージ名が示されています。「centos7」の側でタグ名「latest」を新たなイメージに付け替えても、こちらは変化しません。こちらのタグも新しいイメージに付け替えるには、上記の「oc tag」コマンドを再実行します。

これは、テスト中のイメージと本番利用するイメージを区別するのに有効です。たとえば、「centos7:latest」はテスト中の最新のイメージで、「baseos:deploy」は本番利用のイメージという約束にしておけば、テストが終わって本番利用可能になった時点で、上記の「oc tag」コマンドを実行して本番イメージを切り替えます。後ほど説明する「デプロイ設定(DeploymentConfig)」を利用すると、イメージストリームのタグが付け変わったタイミングで、自動的にコンテナを再デプロイすることも可能です。