自定义镜像—————通过dockerfile创建的都是镜像。
1、dockerfile最基本、最常用的方式
2、docker pull 拉取的是最基础的镜像,只有基础功能,没有定制化的功能。
3、基于基础镜像,创建好了容器之后再容器内部进行定制化的操作,然后导出成镜像,下一次继续使用。
联合文件系统:UnionFS
这个是docker镜像的基础,镜像通过分成来进行集成。基于基础可以制作各种具体的应用镜像。
特性:一次性同时的加载多个文件系统,但是从外面看只能看到一个文件系统。文件系统叠加。
镜像加载的原理:
一层一层等等文件系统自称的
rootfs:根文件系统,包含了一个完整的文件系统(操作系统),包括了所有的文件和目录,以及相关的权限和用户等信息。
运行容器时,整个的根文件系统就会整个被使用,作为应用的运行的环境。
bootfs:引导文件系统 启动根系统时需要加载的核心文件。
dockerfile定制化镜像:定制每一层需要添加的配置和文件。把每一层的修改、安装、构建和操作都写入到一个脚本。
用脚本来进行创建镜像。
这个脚本就是dockerfile
1、基础镜像信息 底层
2、维护者信息(可有可无)
3、镜像的操作指令和相关配置
4、容器启动时执行的命令
可以支持#开头作为注释
FROM:永远是整个脚本第一个语法,指定定制镜像的基础操作系统。
MAINTAINER:维护者信息,可以不写 新版本用LABEL来替代
RUN:在基础镜像上执行的命令,然后把运行结果整合到新镜像当中。RUN就是一个镜像的分层,RUN越多,分成就越多,镜像就越大。为了控制镜像的大小,多个RUN尽可能的写在一个RUN里面。
ENTRYPOINT:指定容器在启动时执行的命令或者参数
CMD:指定容器在启动时执行的命令或者参数
EXPOSE:指定容器对外暴露的端口号
ENV:用来设置基础操作系统的环境变量,以变RUN命令可以使用,或者是新镜像使用,就是给系统添加环境变量。
ADD:支持URL从网络下载文件,也可以对压缩文件进行解压
COPY:只能复制本地文件(宿主机文件)到镜像的目标位置
VOLUME:创建一个容器内的挂载点,不是和宿主机进行挂载。
USER:设置运行镜像时用户
WORKDIR:指定容器的工作目录,相当于切换到这个命令,在这个目录下做指定的操作。
ONBUILD:指定一个镜像作为另一个镜像构建的基础时需要运行的命令。
ARG:ARG用来传参数,用户传递参数,ENV是容器内部的变量
#多个ENTRYPOINT的情况下 [root@docker1 test1]# vim Dockerfile FROM centos:7 ENTRYPOINT ["ls","/etc"] ENTRYPOINT ["ls","/usr"] [root@docker1 test1]# docker build -t centos:test . [root@docker1 test1]# docker run -it --name test1 centos:test bin games lib libexec sbin src etc include lib64 local share tmp
结论:ENTRYPOINT有多个的情况下,只会运行最后一个
#多个CMD的情况 [root@docker1 test1]# vim Dockerfile FROM centos:7 CMD ["ls","/etc"] CMD ["ls","/usr"] [root@docker1 test1]# docker build -t centos:test . [root@docker1 test1]# docker run -it --name test1 centos:test bin games lib libexec sbin src etc include lib64 local share tmp
结论:CMD有多个的情况下,只会运行最后一个
[root@docker1 test1]# vim Dockerfile FROM centos:7 ENTRYPOINT ["ls","/etc"] CMD ["ls","/usr"] [root@docker1 test1]# docker build -t centos:test1 . [root@docker1 test1]# docker run -it --name test2 centos:test1 ls: cannot access ls: No such file or directory /etc: BUILDTIME nsswitch.conf.bak DIR_COLORS openldap DIR_COLORS.256color opt DIR_COLORS.lightbgcolor os-release GREP_COLORS pam.d GeoIP.conf passwd X11 passwd- adjtime.rpmsave pkcs11 aliases pki alternatives pm bash_completion.d popt.d bashrc prelink.conf.d binfmt.d printcap centos-release profile centos-release-upstream profile.d chkconfig.d protocols csh.cshrc python csh.login rc.d dbus-1 rc.local default rc0.d depmod.d rc1.d dracut.conf rc2.d dracut.conf.d rc3.d environment rc4.d exports rc5.d filesystems rc6.d /usr: bin games lib libexec sbin src etc include lib64 local share tmp
在外面传入参数:
[root@docker1 test1]# docker run -it --name test1 centos:test1 ls /usr
结论:CMD和ENTRYPOINT同时存在,命令都会执行,ENTRYPOINT会覆盖CMD的命令。并且CMD会把命令作为参数传给ENTRYPOINT。
作为容器启动时执行命令的语句,一般情况下二者是通用的,但是在传参的情况下,需要加上CMD,如果没有特殊的操作(传参),写一个CMD或者ENTRYPOINT即可,二者不要同时存在。
CMD作为启动命令,运行容器时传了额外的参数,cmd会被覆盖不会被执行
ENTRYPOINT不会被覆盖,容器运行指定的命令相当于给ENTRYPOINT传参
RUN 在基础镜像运行然后把结果传给新镜像。
RUN的结构要合理,不要太多,否则镜像会很大。
[root@docker1 test1]# vim Dockerfile FROM centos:7 RUN ls /opt && ls /etc && ls /usr #&&:前一个指令成功,才会执行下一个 RUN ls /opt ; ls /etc ; ls /usr #;不管前面的命令是否成功,后一个都会执行 #||:前一个失败了,后面才会执行 #\:把一个命令分成多个行,提高可读性
ADD主要主要是解压, .tar .tar.gz .zip 根据URL进行文件下载,复制(官方解释:同样是复制,推荐使用COPY)
ADD不能复制压缩文件。
COPY:只能复制,复制本地文件到容器内。
[root@docker1 test1]# vim Dockerfile FROM centos:7 ADD wordpress-6.4.2-zh_CN.tar.gz /opt COPY test1.txt /opt/test/ [root@docker1 test1]# docker build -t centos:test1 . [root@docker1 test1]# docker run -it --name test1 centos:test1 [root@4a1821d7b685 /]# cd /opt/ [root@4a1821d7b685 opt]# ls test wordpress [root@4a1821d7b685 opt]# ls test/ test1.txt
[root@docker1 test1]# vim Dockerfile FROM centos:7 ADD http://mirrors.aliyun.com/repo/Centos-7.repo /opt/Centos-7.repo [root@docker1 test1]# docker build -t centos:test1 . [root@docker1 test1]# docker run -it --name test1 centos:test1 [root@55cd8240d715 /]# cd /opt/ [root@55cd8240d715 opt]# ls Centos-7.repo
工作目录和环境变量以及容器卷(挂载卷)
工作目录:切换到容器内的指定目录
[root@docker1 test1]# vim Dockerfile FROM centos:7 COPY test1.txt /opt/test/ WORKDIR /opt ENV PATH /opt/test:$PATH VOLUME ["/opt/test"] #默认容器内的挂载点,可以指定任意一个目录与这个目录进行挂载。其他容器就可以与这个目录进行挂载, [root@docker1 test1]# docker build -t centos:test1 . [root@docker1 test1]# docker run -itd --name test1 centos:test1 [root@383d90930c9f opt]# echo $PATH /opt/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin #新创一个容器与容器test1进行挂载 [root@docker1 test1]# docker run -it --name test2 --volumes-from test1 centos:7 [root@7300401aa9f9 /]# cd /opt/test/ [root@7300401aa9f9 test]# cat test1.txt 123
#实战,YUM安装定制一个nginx [root@docker1 test1]# vim Dockerfile FROM centos:7 RUN rm -rf /etc/yum.repos.d/* ADD http://mirrors.aliyun.com/repo/Centos-7.repo /etc/yum.repos.d/Centos-7.repo RUN yum -y install epel-release && \ yum -y install nginx EXPOSE 80 WORKDIR /var/log/nginx/ VOLUME ["/usr/share/nginx/html"] ENTRYPOINT ["nginx","-g","daemon off;"] [root@docker1 test1]# docker build -t nginx:test . [root@docker1 /]# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx1 172.17.0.2 [root@docker1 /]# curl 172.17.0.2 123
[root@docker1 opt]# cd html/ [root@docker1 html]# echo 123 > index.html [root@docker1 test1]# docker run -itd --name nginx2 -v /opt/html:/usr/share/nginx/html nginx:test [root@docker1 /]# curl 172.17.0.3 123 [root@docker1 test1]# docker run -itd --name nginx3 --volumes-from nginx2 nginx:test [root@docker1 /]# curl 172.17.0.4 123