podman自己构建镜像

一、背景:

   podman镜像可以通过Docker hub或者阿里云仓库中获取,这些镜像由官方或者社区人员提供的,对于podman用户来说并不能满足我们的需求,但是从无开始构建成本大。常用的数据库、中间件、应用软件等都有现成的podman 官方镜像或社区创建的镜像,我们只需要稍微配置就可以直接使用。

  使用现成的镜像的好处除了省去自己做镜像的工作量除外,更重要的是可以利用前任的经验。特别是使用那些官方的镜像,因为容器工程师知道如何更好地在容器中运行软件。

  当然,某些情况下我们也不得不自己构建镜像,比如自己开发的应用程序,需要在镜像中加入特定的功能。

二、构建镜像的三种方法:

1.podman commit命令:

  此命令可以基于容器创建镜像,创建过程可以分为三步,先创建容器,在容器中安装我们所需要的内容,再使用podman commit将容器打包为镜像即可。

 示例:在centos的base镜像中安装vim-common并保存为新镜像。

(1)先基于centos7运行容器,容器名为centos-test,并用it生成终端进入容器。

podman run --name centos-test -it docker.io/library/cetos7:7(7为版本信息)

(2)在容器中安装vim-common软件包

e52d /]#yum -y install vim-common

rpm -q vim-common//查看

(3)退出容器后,使用podman commit将centos-test容器打包为镜像,新镜像名为centostest:7

podman ps -a //退出容器后查看所有容器

podman commit centos-test centostest:7

podman images | grep centos  //查看新生成的镜像信息

     这样,一个新的镜像就构建完成了,cetostest:7镜像是在centos:7镜像的基础上创建的,通过查看镜像属性发现cetostest:7要比centos:7镜像大一些。

   这是一种手工创建镜像的方法,容易出错,效率低且可重复性弱,更重要的是,使用者并不知道镜像是如何创建出来的,里面是否有恶意程序,即无法对进行进行审计,存在安全隐患。

   构建镜像的过程(即镜像生成容器,生成所需的指令的过程)

   注:镜像层只有只读的权限,容器层有可写的权限。

  centos7对应的基础镜像(base),如何添加维护者信息,将容器变为镜像?(A、B、C即为临时容器)

  原理:此时先将centos7的镜像运行为容器A,在A容器中添加维护者信息,再停掉A容器,将A打包成镜像层继而累加存入镜像中,然后删除A容器,(即合成一个更大的镜像层)。暴露端口:暴露完端口后再停掉容器,打包生成新的镜像,删除C容器。

2.基于本地模版导入:

 用户可以直接从一个操作系统模板文件导入一个镜像,主要使用podman import命令,要直接导入一个镜像,可以使用Open VZ模版的下载地址为http://openvz:org/Download/template/precreated。

如:下载ubuntu:12.04的模版压缩包,之后使用以下命令即可:

如:下载了ubuntuL12.04的模版压缩包,之后使用以下命令导入即可:(Xshell:搭载yum源时首先进行挂载,mount /dev/cdrom /mnt,首先安装一个软件,yum -y install lrzsz,然后拖文件,rz -E,)

cat ubuntu-12.04-x86-minimal.tar.gz | podman import - ubuntu:12.04:v1 (v1为版本)

3.podmanfile构建文件(增加了镜像的安全性能):

(1)基本概念:

  podmanfile镜像是一个特殊的文件系统,除了提供容器运行所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

镜像的定制实际上就是定制每一层所添加的配置、文件,如果我们可以把每一层修改、安装、构建、操作的命令都写成一个脚本,用这个脚本来构建、定制镜像,那么之前提到的无法重复的问题、镜像构建透明性的问题、体积问题就都会解决,这个脚本就是podmanfile。

podmanfile是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容就是描述该层如何构建。有了podmanfile,当我们需要在podmanfile上添加或修改指令,重新生成镜像即可,省去了敲命令的麻烦。

(2)文件内格式:

podmanfile分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动指令。一开始必须要指明所基于的镜像名称,接下来会说维护者信息,后面则是镜像操作指令。例如ADD指令,每执行一条ADD指令,镜像添加新的一层,并提交;最后是CMD指令来指明运行容器时的操作指令。

示例:构建一个httpd镜像

vim Podmanfile

1)第一行必须指定基础镜像信息

FROM docker.io/library/centos:7

2)维护者信息

MAINTAINER test@example.com

3)镜像操作指令

RUN yum -y install httpd

EXPOSE 80

4)容器启动执行指令

CMD [“/bin/bash”]

  把构建容器所需要的指令都存放在Podmanfile文件中,这个文件的名字是固定的,不能够更改,再使用Podman build命令构建容器,使用-t定义新的镜像名,-f指定Podmanfile。

命令格式:podman build -f Podmanfile -t http:test

podman history  localhost/http:test //查看新镜像的构建过程

呈现出透明化,整个构建过程可见。

三、Podmanfile构建镜像的全过程:

1.下载centos7镜像

2.添加镜像构建者信息

3.基于centos7镜像启动容器,安装httpd软件,安装完成后将容器打包为镜像。

4.基于上一步生成的镜像启动容器后,将80端口打开,打开后将容器打包为镜像。

5.基于上一步生成的镜像启动容器,添加容器启动后需要执行的指令,再打包为镜像。

6.常见的podman指令:

(1)FROM指令必须为Podmanfile文件开篇的第一个非注释行,用于指定构建镜像所使用的基础镜像,后续的指令运行都要依靠此基础镜像所提供的环境。使用时,若没有指定仓库,docker build会先从本机查找是否有此基础的镜像,若没有,会默认去Docker Hub Registry上拉取。

(2)MAINTAINER指令用于让Podmanfile的作者提供个人信息,Podmanfile并不限制此指令的位置,但建议在FROM指令之后。在最新的版本中,此指令已经被LABEL替代。

格式:MAINTAINER test@example.com

(3)LABEL指令用于让用户为镜像指定各种元数据。

(4)COPY指令用于复制宿主机上的文件到目标镜像中。

格式:COPY <src> <dest>

<src>:要复制的源文件或目录,支持通配符

<dest>:目标路径,即正创建的镜像的文件系统路径,建议使用绝对路径,否测,COPY指令会以WORKRID为起始路径,

路径中包含空白字符,建议用”[]”。

(5)ADD指令,跟COPY指令类似,区别在于它还具有解压功能。即支持tar和URL路径。当拷贝的源文件是tarw文件时,会自动展开为一个目录并拷贝到新的镜像中,然而通过URL获取到的tar文件不会自动展开。

(6)WORKRID用于切换工作目录,(外面用的cd)可以指多个,每个WORKERID影响它下面的指令。WORKRID也可以调用由ENV指令定义的变量。

(7)VOLUME指令用于在镜像中创建一个挂载点目录,其有两种类型:绑定挂载卷和podman管理的卷,即只能指定容器内的路径,不能指定宿主机的路径。

格式:VOLUME <mountpoint>   VOLUME [“<mountpoint>”]

(8)EXPORT指令用于指定容器中待暴露的端口号。

如http——>80端口;https——>443端口。有时需要将容器中的80端口和宿主机的8080端口映射,此时需要-p和-P参数。区别为:-P——>随机生成一参数;-p——>根据需求指定固定端口。

(9)ENV指令用于镜像定义所需的环境变量,并可以被ENV指令后面的其他指令所调用。格式为:ENV <key> <vaule>,使用podman run启动容器时加-e的参数,可以覆盖ENV后面定义的变量,但变量的确是被定义了,也不会影响Dockerfile中已经引用过此变量的文件名。

如:ENV a=123

RUN touch $a

podman run -e ‘a=111’,此时111覆盖掉原来的123。

(10)RUN指令运行于podman build过程中运行的程序,可以是任意命令。RUN指令后所执行的命令必须在FROM指令后的基础镜像中存在才行。

格式:RUN <command> //command通常为一个shell命令,系统默认会把后面的命令作为shell子进程来运行,以”/bin/sh-c”来运行它。

RUN[“executable”,”param1”,”param2”]           

(11)CMD指令用于用户指定启动容器默认要运行的命令,即PID为1 的进程命令,且运行结束后容器也会终止。如果不指定,默认的是bash。CMD指令指定的默认程序会被podman run会被podman run命令行指定的参数覆盖。Podmanfile中可以存在多个CMD指令,但仅最后一个生效。因为一个podman容器只能运行一个PID为1的进程。类似于RUN指令,也可以运行任意命令或程序,但是两者的运行时间点不同。

RUN和CMD的区别:

RUN:构建镜像的时候运行的指令;CMD:基于新镜像启动时运行的指令。

格式:CMD command param1 param2

   CMD [“executable”,”param1”,”param2”]

这两种同RUN指令,第一种用法对于CMD指令基本没有意义,因为它运行的程序PID不为1,即直接运行。

   CMD[“param1”,”param2”]

这种需要结合ENTRYPOINT指令结合使用,CMD指令后面的命令作为ENTRYPOINT指令的默认参数。若podman run命令行结尾有参数指定,那CMD后面的参数不生效(即ENTRYPOINT指令优先级高于CMD指令)。

(12)ENTRYPOINT指令类似CMD指令的功能,用于为容器指定默认的运行程序,Podmanfile中可以存在多个ENTRYPOINT指令,但仅最后一个生效,与CMD的区别在于,由ENTRYPOINT指令启动的程序不会被podman run命令行指定的参数所覆盖,而CMD会被覆盖掉。而且这些命令行参数会被当做参数传递给ENTRYPOINT指令指定的程序。

(13)USER用于指定podman build过程中任何RUN、CMD等指令的用户名或者UID。默认情况下容器运行用户为root。

格式:USER <user> [:<group>]  USER <UID> [:<GID>]

  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值