わからないなりに理解したい Podman ⑥ ~ Pod って何だ?

こんにちは。サイオステクノロジー OSS サポート担当 山本 です。

今回は、例えば「2つ以上のコンテナが密接に連携して動作をする必要がある」場合などに力を発揮する Pod についてと、
これまで話し忘れていたコンテナ内のネットワークについて、確認していきたいと思います。

■Pod とは?

以前の記事では「コンテナはそれぞれ独自の隔離空間 (=仮想環境) を持つ」とお話ししましたが、
対して Pod は概ね「コンテナを入れることができる器となる隔離空間だけを先に作ってしまおう」というものです。

Pod には複数のコンテナを入れることができ、Pod 内のコンテナは Pod のネットワークやストレージなどのリソースを共有します。

…とだけ言われても何のことやらという感じなので、とりあえず Pod を作ってみましょう。

■Pod の作成

Pod を作るためのコマンドは以下のような形です。

podman pod create [オプション]

今回はここで作成した Pod に入れるコンテナにはいつもの quay.io の httpd を使いますが、これまでは “podman run” コマンドにつけていた “-p” オプションは、Pod を使う場合はこの “podman pod create” コマンドのほうにつける必要があります。※”podman run” コマンドで “-p” オプションを使おうとするとエラーになります。
更に後に判別・使用する際に便利なように、”–name” オプションで「pod-sample」という名前も付けるとすると、以下のようなコマンドを実行すれば OK です。

[ ~]$ podman pod create -p 8080:8443 --name pod-sample
329ac423b6539303bd7a71ffee3d5c00923f712c769b05121a3ad9f184200314
[ ~]$

Pod が作成できたかは、Pod の一覧を表示する “podman pod ps” コマンドなどで確認するとよいでしょう。

[ ~]$ podman pod ps
POD ID        NAME        STATUS      CREATED         INFRA ID      # OF CONTAINERS
329ac423b653  pod-sample  Created     11 seconds ago  4f6a4896730a  1
[ ~]$

■Pod にコンテナを入れてみる

続いて、作成した Pod にコンテナを入れてみます。これはこれまで使ってきた “podman run” コマンドで行うことができます。
ただし、先述のとおり Pod に入れるコンテナを作成する際は “-p” オプションは使用できず、代わりに “–pod (Pod 名)” オプションの追加が必要になります。

[ ~]$ podman run -dt --name httpd_in_pod --pod pod-sample quay.io/centos7/httpd-24-centos7
 :
Storing signatures
dee32e4511aa3dc36aeee432f51ce4c7d60c44f0b8cca4928b6fbd1b40040037
[ ~]$

これで Pod にコンテナを入れることができました。
このコンテナは、基本的にはこれまでに見てきた単体で動作しているコンテナと同じように扱うことができます

[ ~]$  podman exec -it httpd_in_pod /bin/bash
bash-4.2$
bash-4.2$ echo -e "This is test page." > /opt/rh/httpd24/root/var/www/html/test_content.html
bash-4.2$
bash-4.2$ exit
[ ~]$
[ ~]$ curl -k https://localhost:8080/test_content.html
This is test page.
[ ~]$

■Pod の削除

Pod と Pod に入れたコンテナについて簡単にですが確認できたので、一旦作成した Pod を片づけます。
Pod 自体にも起動/停止などの状態があり、以下のようなコマンドでそれぞれ Pod の停止・起動・削除ができます。

podman pod stop (Pod 名)
podman pod start (Pod 名)
podman pod rm (Pod 名)

Pod 内のコンテナは、Pod の停止/起動/削除に合わせて停止/起動/削除されます
そのことを確認しながら、Pod を停止/削除してみましょう。

[ ~]$ podman ps -a
CONTAINER ID  IMAGE                                    COMMAND               CREATED        STATUS            PORTS                   NAMES
4f6a4896730a  k8s.gcr.io/pause:3.5                                           8 minutes ago  Up 7 minutes ago  0.0.0.0:8080->8443/tcp  329ac423b653-infra
dee32e4511aa  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  7 minutes ago  Up 7 minutes ago  0.0.0.0:8080->8443/tcp  httpd_in_pod
[ ~]$
[ ~]$ podman pod stop pod-sample
329ac423b6539303bd7a71ffee3d5c00923f712c769b05121a3ad9f184200314
[ ~]$ podman ps -a
CONTAINER ID  IMAGE                                    COMMAND               CREATED        STATUS                    PORTS                   NAMES
4f6a4896730a  k8s.gcr.io/pause:3.5                                           9 minutes ago  Exited (0) 5 seconds ago  0.0.0.0:8080->8443/tcp  329ac423b653-infra
dee32e4511aa  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  8 minutes ago  Exited (0) 5 seconds ago  0.0.0.0:8080->8443/tcp  httpd_in_pod
[ ~]$
[ ~]$ podman pod rm pod-sample
329ac423b6539303bd7a71ffee3d5c00923f712c769b05121a3ad9f184200314
[ ~]$ podman ps -a
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
[ ~]$

■コンテナのネットワークと “podman run” の “-p” オプション

ここで話題は一旦 Pod から離れて、コンテナ単体のほうのお話になります。

■”-p” オプションの左側の数値について

今までの記事で動作確認のために利用してきた手順をもう一度見てみます。

[ ~]$ podman run -dt -p 8080:8443/tcp --name test-container quay.io/centos7/httpd-24-centos7
 :
[ ~]$ podman exec -it test-container /bin/bash
bash-4.2$
bash-4.2$ echo -e "This is test page." > /opt/rh/httpd24/root/var/www/html/test_content.html
bash-4.2$
bash-4.2$ exit
[ ~]$ 
[ ~]$ curl -k https://localhost:8080/test_content.html
This is test page.
[ ~]$

このように、httpd コンテナを動かしているサーバ上で「localhost:8080」と自身の 8080 番ポートに接続することで、コンテナ内の httpd のコンテンツにアクセスできていました。
ところでこの手順では、コンテナを起動する “podman run” コマンドのオプションの一つとして “-p 8080:8443” を設定しています。

もうお気付きかと思いますが、”podman run” の “-p” オプションの左側の数字は、コンテナを動作させているサーバ上の何番のポートに接続するとそのコンテナに接続できるようにするかを設定しています。

なので例えば、一度先の手順のコンテナを消した後に “-p 9111:8443″ として再び同じような確認を行うと、
「localhost:8080」では接続できず、代わりに「localhost:9111」で接続できることが確認できるかと思います。

[ ~]$ podman stop test-container
[ ~]$ podman rm test-container
[ ~]$
[ ~]$ podman run -dt -p 9111:8443/tcp --name test-container2 quay.io/centos7/httpd-24-centos7
 :
[ ~]$ podman exec -it test-container2 /bin/bash
bash-4.2$
bash-4.2$ echo -e "This is test page." > /opt/rh/httpd24/root/var/www/html/test_content.html
bash-4.2$
bash-4.2$ exit
[ ~]$ 
[ ~]$ curl -k https://localhost:8080/test_content.html
curl: (7) Failed to connect to localhost port 8080: Connection refused
[ ~]$ 
[ ~]$ curl -k https://localhost:9111/test_content.html
This is test page.
[ ~]$

このように、”podman run” の “-p” オプションの左側の数字はコンテナを動作させているサーバ側で使うポートを設定するものであるため、
コンテナ作成時に他のプログラムや他のコンテナなどで既に使用されているポートを指定するとエラーが発生します。

■”-p” オプションの右側の数値について

では “podman run” の “-p” オプションの右側の数字は何者でしょう?
勿論、先ほどのコンテナを動作させているサーバにこのポート番号で接続しようとしても接続できません。

[ ~]$ curl -k https://localhost:8443/test_content.html
curl: (7) Failed to connect to localhost port 8443: Connection refused
[ ~]$

これの正体は、コンテナ内の httpd が使用しているポートを見ればわかります。
コンテナ内の httpd の設定ファイルから、httpd が接続を受け付けるポートを設定する “Listen” の設定値を確認してみると、このとおり “podman run” の “-p” オプションの右側に指定していた「8443」が出てきます。

[ ~]$ podman exec -it test-container2 /bin/bash
bash-4.2$
bash-4.2$ grep -rn "Listen" /etc/httpd/*/*.conf
/etc/httpd/conf.d/ssl.conf:5:Listen 0.0.0.0:8443 https
/etc/httpd/conf/httpd.conf:34:# Listen: Allows you to bind Apache to specific IP addresses and/or
/etc/httpd/conf/httpd.conf:38:# Change this to Listen on specific IP addresses as shown below to
/etc/httpd/conf/httpd.conf:41:#Listen 12.34.56.78:80
/etc/httpd/conf/httpd.conf:42:Listen 0.0.0.0:8080
bash-4.2$

この設定とコンテナ外からはこのポート番号で接続できなかったことから、コンテナ内にはコンテナを動作させているサーバのものとは別の、仮想的なネットワークが存在することがなんとなくわかるかと思います。
そして、”podman run” の “-p” オプションの右側の数字は接続先としてコンテナ内の仮想ネットワーク側で使うポートの番号であることも読み取れるかと思います。

このため、”podman run” の “-p” オプションの右側の数字はコンテナ内の設定に合わせる必要があります。

■コンテナの内部ネットワーク

ところで、コンテナ内に仮想ネットワークがあるとしたら、コンテナ内における localhost とはどこを指すでしょう?
もうお分かりのとおり、これはコンテナ内部の仮想ネットワークを指します。
そのため、先ほどのコンテナ内から curl を使う場合、先の設定ファイルで確認したとおり「localhost:8443」でコンテナ内のコンテンツにアクセスできます。

[ ~]$ podman exec -it test-container2 /bin/bash
bash-4.2$
bash-4.2$ curl -k https://localhost:8443/test_content.html
This is test page.
bash-4.2$

また、Podman で作成したコンテナには、コンテナ内部でのみ使用できる、コンテナ名と同名の DNS 名が付与されており、コンテナ内部で通信を行う場合はこれを使用することもできます。

bash-4.2$ curl -k https://test-container2:8443/test_content.html
This is test page.
bash-4.2$

■Pod のネットワークリソースの共有を確認してみる

では、”Pod 内のコンテナ同士はリソースを共有する” ことを確認してみたいと思います。
今回は、全く実用性のない例ですが httpd コンテナ 2つを同じ Pod に入れて、(仮想) ネットワークが共有されていることを見てみたいと思います。

まずは Pod の作成をして、その Pod 上に httpd コンテナを 2つ作成します。
なお、”podman pod create” の “-p” オプションは、先のセクションで説明した “podman run” の “-p” オプションとほぼ同じ役割です。

[ ~]$ podman pod create -p 8080:8443 --name pod-test
490793555f6f2c77de0092951ddcedce3dc71073ef028ee4a19c9da0d84caa57
[ ~]$ podman run -dt --name httpd_A --pod pod-test quay.io/centos7/httpd-24-centos7
8fc8615aa5a31d18f08728c4149ba4a941a10375703ce2901a941a3ff23ac71a
[ ~]$ podman run -dt --name httpd_B --pod pod-test quay.io/centos7/httpd-24-centos7
5cbaac2b77f90eb26bdf7d041e00612c7ef3a3f16ce7bd1f378be9d7caa1ce0f
[ ~]$

さて、作成できたら念のため “podman ps -a” でコンテナの状態を確認してみると…後に作成したほうのコンテナの “STATUS” が何故か “Exited” になっています。

[ ~]$ podman ps -a
CONTAINER ID  IMAGE                                    COMMAND               CREATED         STATUS                     PORTS                   NAMES
eca8fcbe3115  k8s.gcr.io/pause:3.5                                           30 seconds ago  Up 28 seconds ago          0.0.0.0:8080->8443/tcp  490793555f6f-infra
8fc8615aa5a3  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  27 seconds ago  Up 27 seconds ago          0.0.0.0:8080->8443/tcp  httpd_A
5cbaac2b77f9  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  23 seconds ago  Exited (1) 24 seconds ago  0.0.0.0:8080->8443/tcp  httpd_B
[ ~]$

“podman logs” コマンドで停止したほうのコンテナのログを確認してみると、何やら 8080番ポートが使えず httpd が動作できないため、終了してしまったようです。

[ ~]$ podman logs httpd_B
 :
(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:8080
no listening sockets available, shutting down
AH00015: Unable to open logs
[ ~]$

これは結論から言えば、先に起動したほうの httpd コンテナが、Pod 内で共有されている仮想ネットワークの 8080番ポートなどを使用していたため、後に起動したほうの httpd コンテナが 8080番ポートを使用できずに発生してしまったものです。
このことからも Pod 内のコンテナ同士は Pod のネットワークリソースを共有していることが読み取れますが、確認を続けましょう。

とりあえず、先に起動したほうの httpd コンテナに、確認用コンテンツを作成します。
更に、httpd の待ち受けポートを 8080、8443 から 9191、9554 に変更します。

[ ~]$ podman exec -it httpd_A /bin/bash
bash-4.2$
bash-4.2$ echo -e "AAAAA This is test page. AAAAA" > /opt/rh/httpd24/root/var/www/html/test_content.html
bash-4.2$
bash-4.2$ grep -rn "Listen" /etc/httpd/*/*.conf
/etc/httpd/conf.d/ssl.conf:5:Listen 0.0.0.0:8443 https
/etc/httpd/conf/httpd.conf:34:# Listen: Allows you to bind Apache to specific IP addresses and/or
/etc/httpd/conf/httpd.conf:38:# Change this to Listen on specific IP addresses as shown below to
/etc/httpd/conf/httpd.conf:41:#Listen 12.34.56.78:80
/etc/httpd/conf/httpd.conf:42:Listen 0.0.0.0:8080
bash-4.2$
bash-4.2$ sed -i s/8080/9191/g /etc/httpd/conf/httpd.conf
bash-4.2$
bash-4.2$ sed -i s/8443/9554/g /etc/httpd/conf.d/ssl.conf
bash-4.2$
bash-4.2$ exit
exit
[ ~]$

先に作成した httpd コンテナの設定反映と、後に作成した httpd コンテナの起動のため、
podman pod restart” コマンドで Pod 全体を再起動します。
これで Pod 内のコンテナも全て再起動され、今度はどちらのコンテナも起動してくれるはずです。

[ ~]$ podman pod restart pod-test
490793555f6f2c77de0092951ddcedce3dc71073ef028ee4a19c9da0d84caa57
[ ~]$
[ ~]$ podman ps -a
CONTAINER ID  IMAGE                                    COMMAND               CREATED         STATUS            PORTS                   NAMES
eca8fcbe3115  k8s.gcr.io/pause:3.5                                           14 minutes ago  Up 9 minutes ago  0.0.0.0:8080->8443/tcp  490793555f6f-infra
8fc8615aa5a3  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  14 minutes ago  Up 9 minutes ago  0.0.0.0:8080->8443/tcp  httpd_A
5cbaac2b77f9  quay.io/centos7/httpd-24-centos7:latest  /usr/bin/run-http...  14 minutes ago  Up 9 minutes ago  0.0.0.0:8080->8443/tcp  httpd_B
[ ~]$

今度は後に起動したほうの httpd コンテナにコンテンツを作成します。
確認の際に見分けがつくように、どちらのコンテナのコンテンツなのか判別しやすい形にしておきましょう。

[ ~]$ podman exec -it httpd_B /bin/bash
bash-4.2$
bash-4.2$ echo -e "BBBBB This is test page. BBBBB" > /opt/rh/httpd24/root/var/www/html/test_content.html
bash-4.2$

さて、では後に起動したほうのコンテナ内から、localhost として Pod 上の両方のコンテナのコンテンツにアクセスできることを確認してみましょう。
先に作成したほうの httpd コンテナの Listen ポートは 9191、9554 に変更しているので、もし Pod 内のネットワークが共有されているのであれば、そのいずれかとこのコンテナ自身の Listen ポート 8080、8443 のいずれかに接続してどちらもコンテンツが表示できるはずです。

bash-4.2$ curl -k https://localhost:8443/test_content.html
BBBBB This is test page. BBBBB
bash-4.2$ curl -k https://pod-test:8443/test_content.html
BBBBB This is test page. BBBBB
bash-4.2$ curl -k https://pod-test:9554/test_content.html
AAAAA This is test page. AAAAA
bash-4.2$ curl -k https://localhost:9554/test_content.html
AAAAA This is test page. AAAAA
bash-4.2$

このとおり、Pod を使うと Pod 上の別のコンテナにも localhost としてアクセスできることが確認できました。
なお上の手順で見れるとおり、Pod 内の仮想ネットワークには、コンテナの時と同じく Pod 内部でのみ使用できる、Pod の name と同じ名前の DNS がデフォルトで作成されています。

このように、Pod 内でリソースを共有できることが、Pod の一つの大きな特徴です。

■最後に

今回は主に Pod について確認してみました。
これもまた、使うこと自体はさして難しくないかな、と実感できたかと思います。

しかし、Pod の話だけを聞いてもイマイチ活用方法はピンとこないかも知れません。
この Pod はどちらかというとコンテナ運用の自動化などを行なう kubernetes などで重要になってくる考え方で、kubernetes のドキュメントによれば、「1つの Pod 内に 1つのコンテナが稼働しているのが一般的なユースケース」などとされています。

一見よくわからないなと思っても、今後コンテナの自動運用を使おうと考えている場合はもちろん、Podman においても密接に連携すべきコンテナがあれば有効に活用できるはずなので、きっと覚えておいて損はないはずです。

(他の回)
わからないなりに理解したい Podman ① ~ 何をするもの?
わからないなりに理解したい Podman ② ~ コンテナを書き換える
わからないなりに理解したい Podman ③ ~ 可搬性とは?
わからないなりに理解したい Podman ④ ~ 可搬性とは?その2
わからないなりに理解したい Podman ⑤ ~ レジストリと TAG
(今回) わからないなりに理解したい Podman ⑥ ~ Pod って何だ?
わからないなりに理解したい Podman ⑦ ~ Pod の可搬性

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

2人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です