专栏首页MyPanda的学习笔记基于centos的rootfs 创建自己的base image

基于centos的rootfs 创建自己的base image

前面介绍了dockerfile的常用命令,以及如何构建自己的centos rootfs, 这里用前面学习的内容,来创建 自己的base image .

该dockerfile包含如下的内容: a. 安装相应的RPM包,并用useradd创建用户, docker build的时候可以通过--build-arg=USERNAME=[USER_NAME] 来指定用户名称,如果在docker build的时候没有指定,USERNAME的默认值为 PandaEye; b. 设置EntryPoint指令值为/bin/bash;CMD指令的值welcome.sh作为ENTRYPOING指令的参数; c. 在该base image中还需要指定ONBUILD 指令,以便基于该base image的使用者知道该base image的一些信息。

下面演示创建该base image的过程:

1.

创建welcome.sh 文件:

[root@localhost ~]# cat welcome.sh
#!/bin/bash
echo -e "\033[1;32;40mUSAGE:\nYou can override the environment 'USERNAME' with your favorite name.\nAlso,you can override the instruction value of 'CMD' with any available commands in the system by format '-c COMMAND'.\033[0m"
export USERNAME
if [[ -z $USERNAME ]];then
        export USERNAME="Private_PandaEye"
fi
echo -e "\nWelcome to the Docker World,$USERNAME.\n"
[root@localhost ~]#

2.

创建dockerfile文件,文件内容如下:

[root@localhost ~]# cat dockerfile
#This is the 1st dockerfile for study dockerfile syntax.
FROM scratch
MAINTAINER  PandaEye
#Add the archive tar.gz file to the / of the docker images. The image generated after this instuctions.
ADD ./my_rootfs.tar.gz  /

#Install the package so that the "useradd" commands is available.
#Here, while we use the exec format for RUN instructions,environment variable can not be parsed,because no shell will be used.
#So we need use the sh or bash in exec format to make the environment variable can be parsed.
#"/bin/bash -c yum install $PKGNAME -y" inlcude 3 parts: command "/bin/bash", option "-c" , option value "yum install $PKGNAME -y"
#This 3 part can not be change. otherwise, it report error.
ARG PKGNAME="shadow-utils"
RUN ["/bin/bash","-c","yum install $PKGNAME -y"]

#Create the user,the default username is 'PandaEye', it can be override by:"docker build  --build-arg=USERNAME=WANTED_NAME".
ARG USERNAME=PandaEye
RUN useradd -c "$USERNAME's ID" -b /bin/bash -m -d /home/$USERNAME $USERNAME
WORKDIR /home/$USERNAME

#In the file : welcome.sh , it try to use the ENV parameter: USERNAME,if not defined, it will define in the welcome.sh
COPY ./welcome.sh  ./
#Below environment USERNAME value is ARG's USERNAME value. If no this line, the docker images has no environment USERNAME.
#The USERNAME environment parameter can be override by: "docker run --env USERNAME=value".
ENV USERNAME $USERNAME
#The CMD can be override while using: docker run IMAGNAME DEFINED_CMD , the DEFINED_CMD must have the similar format: -c CMD_VALUE
#Both CMD and ENTRYPOINT using the exec-format required for make CMD as parameter of ENTRYPOINT.
CMD ["-c","./welcome.sh"]
ENTRYPOINT ["/bin/bash"]

#ONBUILD instruction used to set the info for new image which based on this image.
ONBUILD ARG BASEIMG_RD="The base image build by auth: PandaEye. This is not official base image. "
ONBUILD RUN  ["/bin/bash","-c","echo $BASEIMG_RD"]
[root@localhost ~]#

3.

用docker build -t my_baseimage 来build image. 命令如下:

[root@localhost ~]# docker build -t my_baseimage  --build-arg=USERNAME="ZHANGFEI"   .
Sending build context to Docker daemon 725.3 MB
Step 1/14 : FROM scratch
 --->
Step 2/14 : MAINTAINER PandaEye
 ---> Running in fa6cd58beed7
......
Removing intermediate container 9386d4f58307
Step 14/14 : ONBUILD run /bin/bash -c echo $BASEIMG_RD
 ---> Running in c367b9387a11
 ---> e64162ad76f3
Removing intermediate container c367b9387a11
Successfully built e64162ad76f3
[root@localhost ~]#

4.

用docker run来测试容器: a), ARG参数USERNAME的默认值已经在docker build时候通过--build-arg=USERNAME=ZHANGFEI来替换,结果如下:

[root@localhost ~]# docker run my_baseimage
USAGE:
You can override the environment 'USERNAME' with your favorite name.
Also,you can override the instruction value of 'CMD' with any available commands in the system by format '-c COMMAND'.

Welcome to the Docker World,ZHANGFEI.

b), 在docker run的时候,通过 -e USERNAME参数来替换dockerfile中指定的ENV参数USERNAME的值,注意ARG的USERNAME无法作用于docker run时候引用的USERNAME,但是ENV的USERNAME是可以的:

[root@localhost ~]# docker run -e USERNAME=GuanYu my_baseimage
USAGE:
You can override the environment 'USERNAME' with your favorite name.
Also,you can override the instruction value of 'CMD' with any available commands in the system by format '-c COMMAND'.

Welcome to the Docker World,GuanYu.

c), 通过docker run时候替换CMD指令的值,从而进入容器的内部:

[root@localhost ~]# docker run -it my_baseimage -c /bin/bash
bash-4.2# ls
welcome.sh
bash-4.2# echo $USERNAME
ZHANGFEI
bash-4.2# exit
exit
[root@localhost ~]# docker run -it -e USERNAME=LIUBEI my_baseimage -c /bin/bash
bash-4.2# echo $USERNAME
LIUBEI
bash-4.2#

这里介绍该dockerfile中的几个值得注意的地方: A. 对于RUN,CMD,ENTRYPOIN等指令参数书写的时候,有exec 格式和shell格式;其中引用环境变量的时候,shell格式可以直接引用;而exec格式是不可以的,因为exec格式不会调用 shell, 但是对环境变量的解析是shell来完成的,所以要在exec格式中引用环境变量,要使用 ["/bin/bash","-c","PARAMETER"] 的格式; 这里重点在于对于PARAMETER的理解,“-c” 是 /bin/bash的参数,PARAMETER就是参数 “-c” 的值,所以是一个整体,不可以拆分成多个部分,比如: RUN ["/bin/bash","-c","yum install $PKGNAME -y"] 是正确的写法,而如果进一步拆分,比如RUN ["/bin/bash","-c","yum", "install $PKGNAME"," -y"] 就是错误的,因为 只有yum 作为了-c参数的值,其他是/bin/bash无法识别的参数,所以会报错; B. ARG参数 USERNAME和ENV参数USERNAME虽然同名,但是ARG参数USENAME在docker run时候是不可见的;只有ENV参数USERNAME才是docker run时候可以访问的; C. 当用CMD指令的参数值来作为 ENTRYPOING指令的默认参数的时候,那么需要注意以下两点: 1). ENTRYPOINT的值必须是 可以正确执行的,比如 /bin/bash, 不可以是 /bin/bash -c 2). ENTRYPOINT 和 CMD 都必须使用 exec格式;

本文原创,转载请注明出处

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python中函数位置参数与关键字参数

    Python中函数的参数依照不同的方式,可以有不同的分类,这里以“位置参数”与“关键字参数”两类进行讨论.

    qsjs
  • Here Documents 结合expect的使用--(1)

    使用expect 命令来解决自动交互问题是非常广泛的,expect有自己独特的语法,可以写expect脚本来解决复杂的交互问题;但是很多时候,我们会需要在she...

    qsjs
  • Here Documents 结合expect的使用--(2)

    我们已经知道expect可以帮我们自动完成“交互工作”,但是如果我们需要拿到 通过expect spawn的sub-process 所执行命令的结果,那么怎么做...

    qsjs
  • springboot实战之ORM整合(JPA篇)

    对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到...

    lyb-geek
  • IDG数字化商业转型报告:为什么你的转型总失败?

    人称T客
  • FPGA时序约束实战篇之多周期路径约束

      首先来看带有使能的数据,在本工程中的Tming Report中,也提示了同一个时钟域之间的几个路径建立时间不满足要求

    猫叔Rex
  • WORD中一次性删除所有图片

    一篇Word文档中,包括有大量的图片,如果不需要这些图片了,如何一次性批量删除整个Word文档中所有图片?如果一张一张地寻找图片并按下DEL键删除实在繁琐,这时...

    用户1191760
  • 【Rust日报】2020-08-23 Rust 内存容器备忘录

    Rust的官方文档对于非英语母语的开发者来说理解起来有点难,因此作者用更加通俗易懂的语言解释了Rust官方文档,目前已经完成内容进入审校阶段。

    MikeLoveRust
  • 【Rust日报】2020-03-05 在 Flutter 插件上运行原生 Rust!

    该项目是一个 flutter 的插件模板,它对所有可用的 iOS 和 Android 架构提供了交叉编译原生 Rust 代码的开箱即用支持,Dart 语言可以通...

    MikeLoveRust
  • Django关闭debug, 保持静态文件可访问

    以前写了一篇pm2快速部署Django项目, 遗留了一个问题, 网站虽然可以稳定访问了, 但Django程序依然是调试模式, 如果故意访问错误的url, Dj...

    zhaoolee

扫码关注云+社区

领取腾讯云代金券