関連記事
- Podmanの学習記録#1
- Podmanの学習記録#2 <-- 今回はこれ
はじめに
Podmanの学習記録#1の続きです。
主に以下のような内容を行います。
- イメージ管理の方法
- Containerfileによるカスタムイメージの作成
- ボリュームマウントの方法
- コンテナのトラブルシューティングの基本
イメージの管理
イメージの検索
test@ubuntu-podman:~$ podman search hello-world
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/library/hello-world Hello World! (an example of minimal Dockeriz... 2097 [OK]
docker.io docker.io/rancher/hello-world 4
docker.io docker.io/okteto/hello-world 0
docker.io docker.io/golift/hello-world Hello World Go-App built by Go Lift Applicat... 0
docker.io docker.io/tacc/hello-world 0
docker.io docker.io/armswdev/c-hello-world Simple hello-world C program on Alpine Linux... 0
docker.io docker.io/tutum/hello-world Image to test docker deployments. Has Apache... 90 [OK]
docker.io docker.io/thomaspoignant/hello-world-rest-json This project is a REST hello-world API to bu... 2
docker.io docker.io/kitematic/hello-world-nginx A light-weight nginx container that demonstr... 152
docker.io docker.io/dockercloud/hello-world Hello World! 20 [OK]
docker.io docker.io/ansibleplaybookbundle/hello-world-apb An APB which deploys a sample Hello World! a... 1 [OK]
docker.io docker.io/ansibleplaybookbundle/hello-world-db-apb An APB which deploys a sample Hello World! a... 2 [OK]
docker.io docker.io/crccheck/hello-world Hello World web server in under 2.5 MB 17 [OK]
docker.io docker.io/strimzi/hello-world-consumer 0
docker.io docker.io/strimzi/hello-world-producer 0
docker.io docker.io/businessgeeks00/hello-world-nodejs 0
docker.io docker.io/koudaiii/hello-world 0
docker.io docker.io/freddiedevops/hello-world-spring-boot 0
docker.io docker.io/strimzi/hello-world-streams 0
docker.io docker.io/garystafford/hello-world Simple hello-world Spring Boot service for t... 0 [OK]
docker.io docker.io/ppc64le/hello-world Hello World! (an example of minimal Dockeriz... 2
docker.io docker.io/tsepotesting123/hello-world 0
docker.io docker.io/kevindockercompany/hello-world 0
docker.io docker.io/dandando/hello-world-dotnet 0
docker.io docker.io/vad1mo/hello-world-rest A simple REST Service that echoes back all t... 7 [OK]
test@ubuntu-podman:~$
イメージのプル
test@ubuntu-podman:~$ podman pull hello-world:latest
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob 719385e32844 done
Copying config 9c7a54a9a4 done
Writing manifest to image destination
Storing signatures
9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d
test@ubuntu-podman:~$
イメージの詳細
test@ubuntu-podman:~$ podman image inspect hello-world:latest
[
{
"Id": "9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d",
"Digest": "sha256:4f53e2564790c8e7856ec08e384732aa38dc43c52f02952483e3f003afbf23db",
"RepoTags": [
"docker.io/library/hello-world:latest",
"localhost/hello-world:latest"
],
"RepoDigests": [
"docker.io/library/hello-world@sha256:4f53e2564790c8e7856ec08e384732aa38dc43c52f02952483e3f003afbf23db",
"docker.io/library/hello-world@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3",
"localhost/hello-world@sha256:4f53e2564790c8e7856ec08e384732aa38dc43c52f02952483e3f003afbf23db",
"localhost/hello-world@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3"
],
"Parent": "",
"Comment": "",
"Created": "2023-05-04T17:37:03.872958712Z",
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/hello"
]
},
"Version": "20.10.23",
"Author": "",
"Architecture": "amd64",
"Os": "linux",
"Size": 19929,
"VirtualSize": 19929,
"GraphDriver": {
"Name": "overlay",
"Data": {
"UpperDir": "/home/test/.local/share/containers/storage/overlay/01bb4fce3eb1b56b05adf99504dafd31907a5aadac736e36b27595c8b92f07f1/diff",
"WorkDir": "/home/test/.local/share/containers/storage/overlay/01bb4fce3eb1b56b05adf99504dafd31907a5aadac736e36b27595c8b92f07f1/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:01bb4fce3eb1b56b05adf99504dafd31907a5aadac736e36b27595c8b92f07f1"
]
},
"Labels": null,
"Annotations": {},
"ManifestType": "application/vnd.docker.distribution.manifest.v2+json",
"User": "",
"History": [
{
"created": "2023-05-04T17:37:03.801840823Z",
"created_by": "/bin/sh -c #(nop) COPY file:201f8f1849e89d53be9f6aa76937f5e209d745abfd15a8552fcf2ba45ab267f9 in / "
},
{
"created": "2023-05-04T17:37:03.872958712Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/hello\"]",
"empty_layer": true
}
],
"NamesHistory": [
"localhost/hello-world:latest",
"docker.io/library/hello-world:latest"
]
}
]
test@ubuntu-podman:~$
イメージのtagづけ
test@ubuntu-podman:~$ podman tag hello-world:latest localhost/hello-world:latest
test@ubuntu-podman:~$ podman images | grep hello
docker.io/library/hello-world latest 9c7a54a9a43c 4 months ago 19.9 kB
localhost/hello-world latest 9c7a54a9a43c 4 months ago 19.9 kB
test@ubuntu-podman:~$
イメージの削除
test@ubuntu-podman:~$ podman rmi hello-world:latest
Untagged: docker.io/library/hello-world:latest
test@ubuntu-podman:~$ podman rmi localhost/hello-world:latest
Untagged: localhost/hello-world:latest
Deleted: 9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d
test@ubuntu-podman:~$
他のイメージから参照されていないイメージは以下で削除できる。
podman image prune
Containerfileによるカスタムイメージの作成
イメージのビルド
# ベースイメージ
FROM python:3.11
# ラベル情報
LABEL jp.co.example.environment="dev"
LABEL jp.co.example.version="0.0.1"
# 環境変数
ENV HTTP_PORT=8000
# ポートバインド
EXPOSE $HTTP_PORT
# 作業ディレクトリを指定
WORKDIR /opt/fastapi/src
# ホストからファイルをコピー
COPY app.py .
# Pythonモジュールインストール
RUN pip install fastapi uvicorn[standard]
# Entrypoint(コンテナ起動時に必ず実行するコマンド)
ENTRYPOINT ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
fastapi-sample-app
というイメージ名でtag名をtest
としてイメージをビルドする。
podman build -t fastapi-sample-app .
イメージを確認する。
test@ubuntu-podman:~/work$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/fastapi-sample-app latest 4340cdc505db 56 seconds ago 1.1 GB
docker.io/library/nginx latest f5a6b296b8a2 2 weeks ago 191 MB
docker.io/library/python 3.11 b94d01b49295 4 weeks ago 1.03 GB
test@ubuntu-podman:~/work$
FastAPIをコンテナで起動する
podman run -d --rm --name fastapi-app \
-p 8000:8000 \
localhost/fastapi-sample-app:latest
起動したコンテナのデフォルトのディレクトリを確認すると、Containerfile
で指定したWORKDIR
になっていることが分かる。
test@ubuntu-podman:~/work$ podman exec fastapi-app pwd
/opt/fastapi/src
test@ubuntu-podman:~/work$
アクセス確認。{"message":"Hello World"}
が表示されたらOK。
test@ubuntu-podman:~/work$ curl localhost:8000
{"message":"Hello World"}
test@ubuntu-podman:~/work$
コンテナをストップ。(--rm
オプションを付けているのでストップと同時にコンテナも削除される。)
test@ubuntu-podman:~/work$ podman stop fastapi-app
fastapi-app
test@ubuntu-podman:~/work$
ボリュームマウント
コンテナ内で作成されたファイルなどは、コンテナの削除と同時に消えてしまう。しかし、データベースに登録したデータなどがコンテナのダウンの度に消えるのは嬉しくない。
そこで、コンテナではデータを永続化するための仕組みが用意されている。ホストのディレクトリやファイルをコンテナ内にマウントすることで、永続化を実現する。
コンテナボリュームを作成する方法
以下のコマンドでコンテナボリュームを作成できる。
test@ubuntu-podman:~$ podman volume create hello
hello
test@ubuntu-podman:~$
ボリュームの詳細情報を確認する。
test@ubuntu-podman:~/work$ podman volume inspect hello
[
{
"Name": "hello",
"Driver": "local",
"Mountpoint": "/home/test/.local/share/containers/storage/volumes/hello/_data",
"CreatedAt": "2023-09-26T02:19:16.972967692Z",
"Labels": {},
"Scope": "local",
"Options": {}
}
]
test@ubuntu-podman:~/work$
ボリュームマウントは-v
オプションで指定する。
test@ubuntu-podman:~$ podman run -d --name nginx-vol-test -v hello:/world nginx ls -al /world
b99234876a3a214fd8dd985eb71f7350f2c2d8cb6f6ab0bcf62ad051c881a40a
test@ubuntu-podman:~$ podman logs nginx-vol-test
total 8
drwxr-xr-x 2 root root 4096 Sep 26 02:19 .
dr-xr-xr-x 1 root root 4096 Sep 26 02:28 ..
test@ubuntu-podman:~$ podman rm -af
b99234876a3a214fd8dd985eb71f7350f2c2d8cb6f6ab0bcf62ad051c881a40a
test@ubuntu-podman:~$
hello
ボリュームにファイルをインポートしてみる。
test@ubuntu-podman:~$ echo "Hello World" > test.txt
test@ubuntu-podman:~$ tar zcvf test.tar.gz test.txt
test.txt
test@ubuntu-podman:~$ podman volume import hello test.tar.gz
再度ボリュームマウントして、test.txt
がコンテナ内にもあることを確認する。
test@ubuntu-podman:~$ podman run -d --name nginx-vol-test -v hello:/world nginx ls -al /world
f846c661c57e2c03987fc53cdca505a308bdd5ca1b05c4f5a9356deec5cbed07
test@ubuntu-podman:~$ podman logs nginx-vol-test
total 12
drwxr-xr-x 2 root root 4096 Sep 26 02:31 .
dr-xr-xr-x 1 root root 4096 Sep 26 02:34 ..
-rw-rw-r-- 1 1000 1000 12 Sep 26 02:30 test.txt
test@ubuntu-podman:~$ podman rm -af
f846c661c57e2c03987fc53cdca505a308bdd5ca1b05c4f5a9356deec5cbed07
test@ubuntu-podman:~$
最後にボリュームを削除する。
test@ubuntu-podman:~$ podman volume rm hello
hello
test@ubuntu-podman:~$
ディレクトリのマウント
テスト用のディレクトリとファイルを作成する。
mkdir html
echo "Hello World" > html/index.html
-v
オプションで以下のように指定することで、ホストのディレクトリをコンテナにマウントできる。
podman run -d --rm --name nginx-vol-test \
-p 8080:80 \
-v `pwd`/html:/usr/share/nginx/html \
nginx
アクセス確認をすると、作成した inde.html
が反映されている。
test@ubuntu-podman:~$ curl localhost:8080
Hello World
test@ubuntu-podman:~$ podman rm -af
061c6513a0cff2a4a88f336f778ea374f6d99692769fc5a0da4238d42fa22ba5
test@ubuntu-podman:~$
コンテナのトラブルシューティングの基本
コンテナ構築時に上手く起動できないときに確認すべき基本的なポイントを紹介する。
個人的によく遭遇するのは以下のような事象。
- ボリュームマント時のパーミッションの問題(
podman unshare
) - ポートマッピングの不整合(コンテ内で利用してるポート番号が確認するなど)
- すでにホストで同じポートが利用されている場合
コンテナのログを確認するには以下を実行する。まずはログを確認するのが基本でしょう。
podman logs <コンテナ名>
まとめ
今回は以下を学びました。
- イメージ管理の方法
- Containerfileによるカスタムイメージの作成
- ボリュームマウントの方法
- コンテナのトラブルシューティングの基本