
1. 導出、導入容器
1.1 export
podman export NAME > xxx.tar
export 命令可以將 NAME 來指定容器,導出到本地文件,可以作為一個快照,
Exports container's filesystem contents as a tar archive and saves it on the local machine.

如上,
podman export 將容器導出為 /tmp/t1.tar,
file 命令能看出,導出的文件為一個 tar 包
1.2 import
podman import
import 命令可以將容器快照的本地文件, 導入為一個鏡像,類似於恢復快照
Import a tarball and save it as a filesystem image
podman import 的結果是一個鏡像,而不是一個容器。
也就是說:
修改過的容器導出,得到一個 tar 包;tar 包導入,得到一個鏡像;鏡像運行,才是修改過的容器。
接上圖的例子:

如上:
(1)能看到,當前本地有兩個鏡像
podman import 前面步驟導出的 tar 包 /tmp/t1.tar,
導入完成后,podman images 能看到,本地多出一個鏡像,
(2)運行這個新鏡像,就能看到前面新創建的 1.txt
podman import --help 里面給出的 import 示例為:
podman import http://example.com/ctr.tar url-image
cat ctr.tar | podman import -
cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported
2. 更新(提交)鏡像
將修改過的容器,保存為一個鏡像,也就是對鏡像進行更新
podman commit
Create an image from a container's changes.
2.1 修改容器內容
如上,
運行鏡像 ubuntu,命名為 v1
然后再容器中進行了一些修改,(比如說,可以是修改了 httpd 的 index.html 文件等等)
退出容器
-
容器正常的 stop,start 對於已修改的內容沒有影響
-
容器的 rm,對於已修改的內容也就一並消失了
2.2 將修改過的容器,保存為鏡像
為了保存階段性修改過的內容,可以對鏡像進行更新
如上,
退出容器后,通過 commit 來提交容器,生成鏡像
--author | -a=author
Set the author for the committed image
v1
也就是前面作了修改的容器名稱,也可以使用 Image ID
xyz/unbutu:v2
生成的鏡像名和 tag
提交完成后,podman images 能看到,多了一條本地記錄 localhost/xyz/ubuntu v2
接下來,運行此鏡像,就能看到原先做的修改依舊存在
對於 docker 格式的鏡像(-f 參數),還可以有 -m 參數(message)來做一個注釋
3. 掛載
3.1 掛載
運行容器的時候,
可以通過 -v 參數,在容器中,掛載一個宿主機的目錄,
這樣的話,當容器啟停、刪除的時候,
因為這個目錄是容器外的內容,並不會隨着容器的刪除而被回收。
而容器再次運行的時候,又可以通過掛載,獲取新的內容。
--volume | -v
Create a bind mount.
可以使用 /Host-Dir:/Container-Dir
的格式,
表示將宿主機的目錄掛載到容器里面
如:
前面我們已經知道,
例子中的 httpd 鏡像創建的 index.html 文件位於 /usr/local/apache2/htdoc/index.html
下面將會把宿主機的 /opt/ 目錄掛載到 httpd 這個容器的 /usr/local/apache2/htdoc/
如上,
通過 -v /opt:/usr/local/apache2/htdoc
將宿主機的 /opt 目錄掛載到容器的 htdoc 目錄,
進入容器,
此時在宿主機的 /opt 目錄下新建文件,
在容器的 htdoc 目錄下就能同步看見 該文件。
(貌似訪問 http 服務的時候,還是原來的首頁,不過不管啦,目的暫時實現)
至此,
如果該容器,sotp,rm
再次 run 的時候,同樣掛載 /opt 目錄,就能看見所做的改動。如下:

因為啟動容器的時候有掛載動作,
因此,重新 exec 進入容器的時候,即便沒有 -v 選項,也能看見掛載的內容
3.2 selinux
- selinux 的相關操作需要 root 權限,普通用戶同步不了安全上下文
在上面的例子中,是在宿主機里的掛載目錄 /opt 編輯的 index.html
如果是在容器里面,掛載目錄里面來編輯的話,
會受到 SELinux 的影響,導致失敗,如:
-
方法一:宿主機 setenforce 0
-
方法二:掛載的時候添加一個掛載選項
--volume /Host-Dir:/Container-Dir[:Options]
https://blog.christophersmart.com/2021/01/31/podman-volumes-and-selinux/
If your host has SELinux enabled,
then container processes are confined to the domain:
system_u:system_r:container_t:s0
...
however the context that is required for container volumes is:
system_u:object_r:container_file_t:s0.
Fortunately, container volumes which podman creates at runtime will have the appropriate context set automatically.
也就是說,容器進程的安全上下文是 system_u:system_r:container_t:s0
那么掛載目錄的安全上下文需要是 system_u:object_r:container_file_t:s0 來保持匹配
z 選項表示 podman 在掛載的時候將 SELinux 安全上下進行同步,如:
如上,創建宿主機的掛載目錄 /opt/container_dir/
可以看到,其安全上下文為 user_t
podman run 的時候,掛載目錄時使用了 z 選項,
連接容器,進入 htdoc/
目錄,
成功在容器掛載目錄里面創建文件,
並能看到文件的安全上下文為 container_file_t
,
退出容器,
可以看見掛載目錄的安全上下文也相應的變為了 container_file_t
且能順利看見容器重創建 的文件 file1.txt
但上面這種方法會有一個問題:
容器 A,容器 B,容器 C,是個容器都能訪問掛載目錄,可能會有安全隱患。
如果只是限定容器 A 才能訪問掛載目錄的話,那么就需要使用到 Z 選項,前面的鏈接里面有敘述,此處放出截圖,不在敘述。