Linux运维进阶-Python,Docker,ShellDocker容器

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

2019-09-15  本文已影响0人  My熊猫眼

前面介绍了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格式;

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

上一篇下一篇

猜你喜欢

热点阅读