LoginSignup
1
1

S2I (Source to Image)解説 - 2. S2Iを使って、Pythonのコンテナイメージをビルドする

Last updated at Posted at 2023-08-29

本記事は、前回の記事の続きである。本記事では、実際に自分のローカル環境を使い、Pythonの簡単な環境を構築するコンテナイメージをS2Iを使ってビルドしていく。

使用した環境

S2Iのダウンロード

WSL2のubuntuへS2Iをダウンロード手順を以下に示す:

  1. まず、S2Iを配置するための一時的なディレクトリを用意し、そのディレクトリへ移動する:
mkdir /tmp/s2i/ && cd /tmp/s2i/ 
  1. 次に、S2Iのバイナリパッケージアーカイブをダウンロードし、バイナリファイルを適切なディレクトリへ置く。S2Iのリリース情報はリリース情報にあるので、自分の環境に合わせてS2Iのバージョンは選んでいく。
    ディレクトリ/tmp/s2i/内でcurlを使用し、ここでは最新バージョンのS2Iをダウンロードする:
$ curl -s https://api.github.com/repos/openshift/source-to-image/releases/latest| grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4  | wget -qi -
  1. 次に、バイナリファイルの解凍を行う
$ tar xvf source-to-image*.gz
  1. S2IのPATHを次のように通す。例えばs2iという実行ファイルを/usr/local/binへ移動する:
sudo mv s2i /usr/local/bin
rm -rf /tmp/s2i/

ここで、一時的に作成したディレクトリ/tmp/s2i/は必要ないので、削除した。

  1. 最後に、S2Iの場所を以下で確認すると
which s2i
>
/usr/local/bin/s2i

と表示される。S2Iのバージョンを確認すると以下のように出力されるはずである:

$ s2i version  
s2i v1.3.8

S2Iビルドの実行

手順1. S2Iビルドを実行するためのディレクトリ作成

まず、S2Iのs2i createコマンドを使い、S2Iビルド実行用のひな形のディレクトリを作成する:

$ s2i create python-test python-test

今回はpython-testというディレクトリを作成した。実際にpython-testのディレクトリ構造を確認する:

$ cd python-test
~/python-test$ tree 
.
├── Dockerfile
├── Makefile
├── README.md
├── s2i
│   └── bin
│       ├── assemble
│       ├── run
│       ├── save-artifacts
│       └── usage
└── test
    ├── run
    └── test-app
        └── index.html

S2I builder imageをビルドするためには、Dockerfileに加え、S2Iスクリプトが必要である。directory構造では、s2i/bin配下にs2iで実行するためのS2I scriptが配置されている。必須のスクリプトはassemblerunこの2種類である。

手順2. Pythonを実行するファイルの作成

今回はtest/test-appディレクトリ内のアプリケーションソースコードをpythonの実行ファイルsample.pyrequirements.txtというファイルを追加しておく:

.
├── Dockerfile
├── Makefile
├── README.md
├── s2i
│   └── bin
│       ├── assemble
│       ├── run
│       ├── save-artifacts
│       └── usage
└── test
    ├── run
    └── test-app
        ├── sample.py
        └── requirements.txt

実際のPython用スクリプト sample.pyrequirements.txtを以下に示す:

sample.py
print("Hellow World!")
requirements.txt
numpy

手順3. DockerfileとS2I scriptの作成

今回、使用したDockerfileを以下に示す:
Dockerfile

Dockerfile
FROM python:latest
USER root
# TODO: Set labels used in OpenShift to describe the builder image
LABEL io.openshift.s2i.scripts-url=image://usr/libexec/s2i \
      io.openshift.tags="builder,python"

COPY ./s2i/bin/ /usr/libexec/s2i

# TODO: Set the default CMD for the image
CMD ["/usr/libexec/s2i/usage"]

次に、S2I scriptを作成していく。assemble.shrun.shを作成していく。

assembleについて

assembleでは、ソースコードからアプリケーションのアーティファクト(成果物)をビルドし、それらをイメージ内の適切なディレクトリに配置する。
実際にPythonのコンテナイメージを作成するためのスクリプト例 assemble.shを示す:
assemble scriptの実際の中身を実際に見てみると以下のようになっている。

assemble.sh
#!/bin/bash -e
if [[ "$1" == "-h" ]]; then
        exec /usr/libexec/s2i/usage
fi

# アプリケーション、例えば、sample.py, requirements.txtをアプリの実行を行うディレクトリへコピーし配置している
echo "---> Installing application source..."
cp -Rf /tmp/src/. ./

# requirements.txtを用いて、pip installでライブラリのインストールを行っている
echo "---> Building application from source..."
pip install --upgrade pip
if [ -f requirements.txt ]; then
    pip install -r requirements.txt
fi

上記にようにassembleではPythonモジュールのインストールを実施している。

runについて

実際にpythonスクリプト sample.pyを実行するスクリプトである:

run.sh
#!/bin/bash -e
python sample.py

手順4. S2I image builderを作成する

S2Iビルドを実行するために、docker buildを使って、S2I image builderをビルドする。docker buildDockerfileがあるディレクトリ内で実行する必要がある。今回は、S2I image builderの名前はpython-builderという名前にする:

$ docker build -t python-builder ./python-test

コマンドの説明

  • docker build : Dockerfileを使い、コンテナイメージをビルドする
  • -t python-builder : タグ付きでコンテナイメージ名をpython-builderにする
  • ./python-test : Dockerビルドを実行するディレクトリを指定する

実際にビルドされたコンテナイメージを確認してみる:

$ docker images
>
REPOSITORY                 TAG       IMAGE ID       CREATED         SIZE
python-builder                latest    039c8d89b767   2 minutes ago   426MB

mehcanism_S2I_py_1.png

手順5. S2Iビルド実行

手順2、3でアプリケーションソースコードとPython環境用のS2I builder imegaを作成した。これらを用いて、S2Iビルドにより、新たなコンテナイメージをビルドする。

$~/python-test s2i build test/test-app/ python-builder python-app
>
`WARNING: could not inspect the builder image for labels: reading manifest latest in docker.io/library/python-builder: requested access to the resource is denied`
---> Installing application source...
---> Building application from source...
Build completed successfully

コマンド説明

  • s2i build : S2Iビルドを実行し、新たなコンテナイメージをビルドする
  • test/test-app/ : アプリケーションソースコードのディレクトリを指定
  • python-builder : S2I builder imageのイメージ名を指定
  • python-app : 新しくS2Iビルドされるコンテナイメージの名前を指定

実際にビルドされたコンテナイメージを確認してみる:

$~/s2i-test/python-test$ docker images
>
REPOSITORY                 TAG       IMAGE ID       CREATED          SIZE
python-app                 latest    7561a8bc9e5a   10 seconds ago   426MB
python-builder                latest    039c8d89b767   3 minutes ago    426MB

python-appという最終的来なコンテナイメージがビルドされた。
mehcanism_S2I_py.png

注意点

S2Iでコンテナイメージのビルドを行う際の注意点を説明する。結論から言うと、S2Iビルド用のDockerfileLABELにイメージの場所io.openshift.s2i.scripts-urlを指定する必要がある。実際Dockerfileに書いたように

LABEL io.openshift.s2i.scripts-url=image://usr/libexec/s2i

と記述する必要がある。

起きた問題

はじめ、Dockerfileを以下のように記述し:

FROM python:latest
USER root

COPY ./s2i/bin/ /usr/libexec/s2i

CMD ["/usr/libexec/s2i/usage"]

S2Iビルドすると以下のようなエラーメッセージが出てきた:

could not inspect the builder image for labels: reading manifest latest in docker.io/library/pybuilder: requested access to the resource is denied
An error occurred: failed to install [assemble run]
Suggested solution: set the scripts URL parameter with the location of the S2I scripts, or check if the image has the "io.openshift.s2i.scripts-url" label set

まず、1つめのエラーは、イメージがdocker.ioに無かったのでローカルから探すという意味であり、これは無視する。2つ目のエラーはassemble runのインストールに失敗したことを意味する。3つ目のエラーはs2iスクリプトの場所を指定しろという意味をもつ。

そこで、エラーにある通りに、s2i builder imageを作成するためのDockerfileのLABELを以下のように記述し:

Dockerfile
LABEL io.openshift.scripts-url=image://usr/libexec/s2i

と記述するが、再び、同じエラーが出てしまった。

解決策

s2i buildをopenshift上ではなく、ローカル上で実行する場合、作成したs2i builder image(今回はpython-builderのこと)内のs2iスクリプトの場所をio.openshift.s2i.scripts-urlで指定する必要がある。

今回、Openshiftによって、用意されたベースイメージ(例えばopenshift/base-centos7)ではなく、Openshift以外によって用意されたベースイメージ(今回の場合だとpython:latest)を使用した。そのため、ローカルで用意したDockerfileにイメージの場所io.openshift.s2i.scripts-urlLABELで指定する必要があった。そのため、Dockerfile

LABEL io.openshift.s2i.scripts-url=image://usr/libexec/s2i

を記述すればよい。また、io.s2i.scripts-urlというLABELによる指定でも、ビルドは成功するが、現在は廃止されており、使わなことをお勧めする。

次回はS2Iの機能の一つである増分ビルドというものについて説明します

参考文献

1
1
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
1
1