1.通过dockerfile 制作centos系统镜像然后再制作 nginx编译镜像
//开始制作centos系统镜像
//创建并进入目录~/homework/dockerfile/centos,编写dockfile
root@aseal:~/homework/dockfile/centos# cat Dockerfile
FROM centos:7
RUN yum -y install wget && rm -f /etc/yum.repos.d/* && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo
&& wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo
&& yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools bzip2 lsof zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel
&& yum clean all
&& rm -f /etc/localtime
&& ln -s ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
//制作镜像
root@aseal:~/homework/dockfile/centos# docker build -t centos7-base:v1 .
(输出省略)
root@aseal:~/homework/dockfile/centos# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-base v1 c584e14edcb3 2 minutes ago 399MB
//centos系统镜像制作完成
//开始制作nginx镜像
//创建并进入目录~/homework/dockerfile/nginx
//下载nginx编译文件
root@aseal:~/homework/dockfile/nginx# wget http://nginx.org/download/nginx-1.16.1.tar.gz
//编写dockerfile
root@aseal:~/homework/dockfile/nginx# cat Dockerfile
FROM centos7-base:v1
ADD nginx-1.16.1.tar.gz /usr/local/src
RUN cd /usr/local/src/nginx-1.16.1
&& ./configure --prefix=/apps/nginx
&& make && make install
&& rm -rf /usr/local/src/nginx*
&& useradd -r nginx
&& ln -s /apps/nginx/sbin/nginx /usr/sbin/nginx
EXPOSE 80 443
CMD ["nginx","-g","daemon off;"]
//制作镜像并运行
root@aseal:~/homework/dockfile/nginx# docker build -t nginx-centos7:v1 .
root@aseal:~/homework/dockfile/nginx# docker run -d -p 80:80 nginx-centos7:v1
//验证镜像制作正确
root@aseal:~/homework/dockfile/nginx# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a5b96e6c5f1 nginx-centos7:v1 "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, 443/tcp suspicious_vaughan
root@aseal:~/homework/dockfile/nginx# curl 127.0.0.1
...
<h1>Welcome to nginx!</h1>
...
//nginx镜像制作完成
2.写出10个常用的dockerfile 脚本参数及使用说明
(1)FROM
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
指定基础镜像,后续操作会在基础镜像上进行定制。此指令必需放在dockerfile文件第一个非注释行
(2)LABEL
LABEL <key>=<value> <key>=<value> ...
可以指定镜像元数据,如镜像作者等
(3)RUN
RUN <cmd> && <cmd> ...
用来在构建镜像阶段执行基础镜像所支持的Shell命令。RUN命令可以写多个,每一个RUN指令都会建立一个镜像层
(4)ENV
ENV <key>=<value> <key>=<value> ...
可以定义环境变量和值,会被后续指令(如ADD,COPY,RUN等)引用,并在容器运行时保持
(5)COPY
COPY <src> <dest>
复制本地宿主机的文件到容器中。源文件的权限和变更时间等元数据会被保留
(6)CMD
CMD ["executable","param1","param2"]
指定在容器启动阶段执行的命令。
如果有多条CMD,只有最后一条会被执行;如果开始容器时用了docker run xxx运行指定命令,会覆盖CMD指定的命令;如果有ENTRYPOINT命令,会将CMD指定的内容作为ENTRYPOINT命令的参数
(7)ENTRYPOINT
ENTRYPOINT ["executable","param1","param2"]
指定容器运行后执行的命令及参数。
如果有多个ENTRYPOINT,只有最后一个会被执行;如果有ENTRYPOINT命令,则CMD或者docker run xxx后的内容会被作为ENTRYPOINT命令的参数(docker run xxx会覆盖CMD指定的内容)
(8)VOLUME
VOLUME <path>
创建一个挂载点,一般会将/var/lib/containers/storage/volumes/<id>/_data挂载至VOLUME命令指定的容器目录。
容器删除后该宿主机目录仍会保留,从而可以实现容器数据的持久保存
(9)WORKDIR
WORKDIR </path>
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录,并指定容器运行后进入容器内的默认目录
(10)EXPOSE
EXPOSE <port>[/ <protocol>]
指定默认的暴露端口,启动容器时通过docker run -P将指定的端口进行暴露
3.请写出dockerfile的分层原理
这个问题似乎应该表述为“docker的分层原理”?
什么是docker的镜像分层:
Docker 利用了 Union FS(联合文件系统) 的技术,将镜像设计为分层存储的架构。镜像实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变(只读),后一层上的任何改变只发生在自己这一层
当使用镜像时,我们只会看到一个整体而不知道镜像到底有几层。当容器启动时,一个新的可写层(容器层)被加载到镜像的顶层。对容器的任何修改都只会发生在容器层中而不会影响之前的镜像层
分层的好处:
(1)使得镜像的复用、定制变的更为容易。可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像
(2)共享资源,节省资源。有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了
当使用dockerfile制作镜像时:
dockerfile中的每一个指令都会生成一个新的镜像层,为了减少分层和镜像大小,应尽可能将多条指令合并为一条指令
回答参考了老师的笔记以及https://www.sudo.ren/article/15