7. podman -- 保存容器中修改的内容


 

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 选项,前面的链接里面有叙述,此处放出截图,不在叙述。

 

 

posted @ 2021-10-31 23:42  牛顿撕鸡  阅读(2397)  评论(0编辑  收藏  举报