Initコンテナを理解する

Pod を起動する処理で、Initコンテナを起動して、アプリコンテナが開始される前に実行される1つ以上のInitコンテナを持つことができます。

Initコンテナのユースケース

  • アプリコンテナを起動する前に、しばらく待つ。
  • 別のサービスが起動するのを待つ。
  • 共有ボリュームにGitリポジトリのクローンを作成する。
  • ポッドを下位APIからリモートサーバーに登録する。
  • 構成ファイルに値を配置し、テンプレートツールを実行して、メインアプリコンテナーの構成ファイルを動的に生成する。たとえばPOD_IP、構成に値を配置し、Jinjaを使用してメインアプリ構成ファイルを生成する。

Initコンテナとは、Pod内でアプリケーションコンテナの前に実行される特別なコンテナです。

Initコンテナにはアプリケーションコンテナのイメージに存在しないセットアップスクリプトやユーティリティーを含めることができます。

ポッドの Initコンテナを指定するには、アプリの配列と一緒に、コンテナinitContainersタイプのオブジェクトの配列としてフィールドをポッドの仕様に追加します。

Initコンテナのステータスは、コンテナ ステータスの配列としてフィールドに返されます。

initContainers:
  - image: <hub-user>/<repo-name><hub-user><repo-name>:<tag>
    name: <initialization container name>
</tag></repo-name></hub-user>

Initコンテナの使い方

Initコンテナの動作について理解するため、実際の動作を確認していきます。

 

step
1
curlとgitコマンドが使えるコンテナの作成

# Run a command in a new container
> docker run -it ubuntu:latest bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
83ee3a23efb7: Pull complete
db98fc6f11f0: Pull complete
f611acd52c6c: Pull complete
Digest: sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715
Status: Downloaded newer image for ubuntu:latest

# パッケージを管理しているDBを更新して、最新の状態にする。パッケージの更新自体はしません。
root@f4043bc2de3b:/# apt-get update Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB] ... Get:17 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 Packages [4301 B] Fetched 16.9 MB in 1min 1s (275 kB/s) Reading package lists... Done 
# パッケージのインストール/更新
root@f4043bc2de3b:/# apt-get install curl git -y Reading package lists... Done ... Running hooks in /etc/ca-certificates/update.d... done.
# コンテナを終了する
root@f4043bc2de3b:/# exit
 

step
2
コンテナをイメージ化

# 全てのコンテナを表示
>docker ps -a
CONTAINER ID   IMAGE           COMMAND   CREATED         STATUS                      PORTS     NAMES
f4043bc2de3b   ubuntu:latest   "bash"    7 minutes ago   Exited (0) 51 seconds ago             jolly_hodgkin

# コンテナの変更を元に新しいイメージを作成
>docker commit -m "git & curl client" f4043bc2de3b <repo-name>:<tag>
sha256:d0e1bce81503ff78959fd6687eb26acde24b70fefc2eab2108771c4d81d660c9

# Dockerイメージをリストする
>docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
<repo-name>  v1        d0e1bce81503   32 seconds ago   202MB
ubuntu       latest    f63181f19b2f   4 days ago       72.9MB
 

step
3
DockerHubへ登録

# Log in to a Docker registry
>docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username:
Password:
Login Succeeded

# Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
>docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

# Push an image or a repository to a registry
>docker push NAME[:TAG]
The push refers to repository [docker.io/<hub-user>/<repo-name>]
9e327534f66f: Pushed
02473afd360b: Pushed
dbf2c0f42a39: Pushed
9f32931c9d28: Pushed
v1: digest: sha256:a323c1566c0754e23262778e28bf5b98c60eaca7b75d2241672e6ee5f55be683 size: 1155

>docker images
REPOSITORY                                  TAG       IMAGE ID       CREATED          SIZE
<repo-name>                                 v1        d0e1bce81503   21 minutes ago   202MB
<hub-user>/<repo-name>                      v1        d0e1bce81503   21 minutes ago   202MB
ubuntu                                      latest    f63181f19b2f   4 days ago       72.9MB
 

step
4
初期化を行うコンテナを設定

Initコンテナの仕様を定義します。
初期化専用のコンテナを利用して、GitHubからコンテンツをクローンして、コンテンツをローカルに取得して、ポッドを起動します。 ポッドがマウントする共有ディスクにコンテンツをクローンし、Web サーバーや Application サーバーといったワークロード コンテナから、コンテンツにアクセスします。

以下が、今回の初期化コンテナの仕様を定義するコア部分です。

  initContainers:
  - image: <hub-user>/<repo-name>:<tag>
    name: <initialization container name>

この例では、1つのinitコンテナーを持つ単純なポッドを定義します。initコンテナーが完了すると、ポッドはそのspecセクションからアプリコンテナーを実行します。

apiVersion: v1
kind: Pod
metadata:
  name: containers
spec:
  containers:
  # メインアプリコンテナー #1
  - image: ubuntu:latest
    name: c-1
    volumeMounts:
    - mountPath: /var/www1
      name: cache-volume
    command: ["tail",  "-f", "/dev/null"]
  # メインアプリコンテナー #2
  - image: ubuntu:latest
    name: c-2
    volumeMounts:
    - mountPath: /var/www2
      name: cache-volume
    command: ["tail",  "-f", "/dev/null"]
  initContainers:
  # initコンテナー
  - image: <hub-user>/<repo-name>:<tag>
    name: c-3
    volumeMounts:
    - mountPath: /var/www3
      name: cache-volume
    command: ["git",  "clone", "https://github.com/OfficeDev/Microsoft-Teams-Samples.git", "/var/www3"]
  volumes:
  - name: cache-volume
    emptyDir: {}
 

step
5
Kubernetesクラスターの作成と起動

※コマンドプロンプトは、管理者権限で起動します。
PS C:\Windows\system32> minikube start
* Microsoft Windows 10 Pro 10.0.19041 Build 19041 上の minikube v1.17.0
* dockerドライバーが自動的に選択されました。他の選択肢:  hyperv, ssh
* コントロールプレーンのノード minikube を minikube 上で起動しています
* Kubernetes v1.20.2 のダウンロードの準備をしています
    > preloaded-images-k8s-v8-v1....: 491.22 MiB / 491.22 MiB  100.00% 86.78 Mi
* docker container (CPUs=2, Memory=2200MB) を作成しています
* Docker 20.10.2 で Kubernetes v1.20.2 を準備しています...
  - Generating certificates and keys ...
  - Booting up control plane ...
  - Configuring RBAC rules ...
* Kubernetes コンポーネントを検証しています...
* 有効なアドオン: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

minikube の起動( minikube start )に失敗するときは

一度、 "minikube delete" でコンテナを削除して "minikube start"でリトライしましょう。 

>minikube start
* Microsoft Windows 10 Pro 10.0.19041 Build 19041 上の minikube v1.17.0
* プロフィールを元に、 docker ドライバを使用します
* コントロールプレーンのノード minikube を minikube 上で起動しています
! StartHost failed, but will try again: Error loading existing host. Please try running [minikube delete], then run [minikube start] again.: filestore "minikube": open C:\Users\<ユーザー名>\.minikube\machines\minikube\config.json: The system cannot find the file specified.
* Failed to start docker container. Running "minikube delete" may fix it: Error loading existing host. Please try running [minikube delete], then run [minikube start] again.: filestore "minikube": open C:\Users\<ユーザー名>\.minikube\machines\minikube\config.json: The system cannot find the file specified.

X Exiting due to GUEST_NOT_FOUND: Failed to start host: Error loading existing host. Please try running [minikube delete], then run [minikube start] again.: filestore "minikube": open C:\Users\<ユーザー名>\.minikube\machines\minikube\config.json: The system cannot find the file specified.
* 提案: minikube is missing files relating to your guest environment. This can be fixed by running 'minikube delete'
* Related issue: https://github.com/kubernetes/minikube/issues/9130
 

step
6
コンテナ作成

> kubectl apply -f containers.yml
pod/containers created
> kubectl get pod -o wide
NAME         READY   STATUS     RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
containers   0/2     Init:0/1   0          2s    172.17.0.3   minikube   <none>           <none>
> kubectl get pod -o wide
NAME         READY   STATUS            RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
containers   0/2     PodInitializing   0          5s    172.17.0.3   minikube   <none>           <none>
> kubectl get pod -o wide
NAME         READY   STATUS            RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
containers   0/2     PodInitializing   0          7s    172.17.0.3   minikube   <none>           <none>
> kubectl get pod -o wide
NAME         READY   STATUS            RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
containers   0/2     PodInitializing   0          8s    172.17.0.3   minikube   <none>           <none>
> kubectl get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
containers   2/2     Running   0          10s   172.17.0.3   minikube   <none>           <none>
 

step
7
Initコンテナの動作結果を確認

いずれかのポッドのコンテナにログインし、GitHubから、コンテンツをクローンできている事を確認します。

>kubectl exec -c c-1 -it containers -- bash
root@containers:/#

root@containers:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         251G  3.6G  235G   2% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.1G     0  3.1G   0% /sys/fs/cgroup
/dev/sdc        251G  3.6G  235G   2% /var/www1
shm              64M     0   64M   0% /dev/shm
tmpfs           3.1G   12K  3.1G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           3.1G     0  3.1G   0% /proc/acpi
tmpfs           3.1G     0  3.1G   0% /sys/firmware

root@containers:/# cd /var/www1
root@containers:/var/www1# ls -al
total 48
drwxrwxrwx  4 root root  4096 Jan 25 23:26 .
drwxr-xr-x  1 root root  4096 Jan 25 23:26 ..
drwxr-xr-x  8 root root  4096 Jan 25 23:26 .git
-rw-r--r--  1 root root  6216 Jan 25 23:26 .gitignore
-rw-r--r--  1 root root  1141 Jan 25 23:26 LICENSE
-rw-r--r--  1 root root 16304 Jan 25 23:26 README.md
-rw-r--r--  1 root root  2780 Jan 25 23:26 SECURITY.md
drwxr-xr-x 25 root root  4096 Jan 25 23:26 samples

参考資料