一、dockerfile
自定义镜像---------通过docker创建镜像。
1.1、创建镜像的方式:
1、dockerfile最基的方式,最常用的方式。
2、docker pull 拉取的是最基础的镜像,只有基础功能,没有定制化的功能。
3、基于基础镜像,创建好容器之后,在容器内部进行自定义定制化的操作,然后导出成镜像,下一次继续使用。
1.2、基于docker创建:
联合文件系统:UnionFS
这个是docker镜像的基础,镜像通过分层来进行集成,基于基础可以制作各种具体的应用镜像。
特性:一次性同时加载多个文件系统,但是从外至少能看一个文件系统。文件系统叠加。
1、镜像加载的原理:
一层一层文件系统组成的
rootfs:根文系统,包含了一个完整的文件系统(操作系统)包括了所有的文件和目录,以及相关的权限和用户等信息。
运行容器时,整个的根文件系统就会整个被使用,作为应用的运行的环境。
bootfs:引导文件系统,启动根系统时加载时需要加载的核心文件。
2、先启动bootfs,再引导开启rootfs
二、docker定制化镜像:
- docker定制化镜像:定制每一层需要添加的配置和文件,把每一层的修改,安装,构建和操作都写入到一个脚本。
- 用脚本来进行创建镜像。
- 这个脚本就是dockerfile
2.1、dockerfile分为四个部分:
1、基础镜像信息 底层
2、维护者信息 (可有可无)
3、镜像的操作指令和相关配置
4、容器启动时执行的命令
可以支持#开头作为注释
2.2、dockerfile的命令:
- FROM:永远是整个脚本的第一个语法,指定定制镜像的基础操作系统。
- MAINTAINER:维护者信息,(可以写可不写),新版本LABELE来代替了。
- RUN:在基础镜像上执行的命令,然后把运行结果整合到新镜像当中。RUN就是镜像的分层,RUN越多,分成就越多,镜像越大,为了控制镜像的大小,多个run尽可能写在一个RUN里面。
- ENTRYPOINT:指定容器在启动时执行的命令或者参数
- CMD:指定容器在启动时执行的命令或者参数
- EXPOSE:指定容器对外暴露的端口号
- ENV:用来设置基础操作系统的环境变量,以便RUN命令使用或者新镜像使用,就是给系统添加环境变量。
- ADD:支持URL从网络下载文件,也可以对压缩文件进行解压
- COPY:只能复制本地文件(宿主机文件)到镜像的目标位置为止
- VOLUME:创建一个容器内的挂载点,不是和宿主机进行挂载。-v test
- USER:设置运行镜像时用户
- WORKDIR:执行容器的工作目录,相当于切换到这个目录,在这个目录做下指定的操作
- ONBUILD:指定一个镜像作为另一个镜像构建的基础时需要运行的命令。
- ARG:ARG用来传参数,用户传递的参数,ENV是容器内部的变量。
2.3、FROM的语法,以及cmd和ENTRYPOINT的区别:
docker run -it --name test1 centos:7 /bin/bash
1、多个ENTRYPOINT命令执行情况
[root@docker3 ~]# cd /opt/
[root@docker3 opt]# mkdir test1/
[root@docker3 opt]# cd test1
[root@docker3 test1]# vim Dockerfile
#FROM的语法,以及cmd和ENTRYPOINT的区别:
FROM centos:7
ENTRYPOINT ["ls","/etc"]
ENTRYPOINT ["ls","/usr"]
[root@docker3 test1]# docker build -t centos:test .
[+] Building 0.1s (5/5) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 207B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.0s
=> [1/1] FROM docker.io/library/centos:7 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:002dc8e21afaf9c44463df20fe78fd6a6a91098e5511d16 0.0s
=> => naming to docker.io/library/centos:test 0.0s
[root@docker3 test1]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest a72860cb95fd 7 weeks ago 188MB
nginx 1.22 0f8498f13f3a 16 months ago 142MB
centos 7 eeb6ee3f44bd 2 years ago 204MB
centos test 002dc8e21afa 2 years ago 204MB
nginx 1.18 c2c45d506085 3 years ago 133MB
[root@docker3 test1]# docker run -it --name test1 centos:test
bin etc games include lib lib64 libexec local sbin share src tmp
##等于下面
[root@docker3 test1]# ls /usr
bin etc games include lib lib64 libexec local sbin share src tmp
##结果:
##执行最后ENTRYPOINT最后一条命令
2、多个CMD命令执行情况
[root@docker3 test1]# vim Dockerfile
#FROM的语法,以及cmd和ENTRYPOINT的区别:
FROM centos:7
CMD ["ls","/etc"]
CMD ["ls","/usr"]
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test1 centos:test
bin etc games include lib lib64 libexec local sbin share src tmp
##结果:
##执行最后CMD最后一条命令
3、ENTRYPOINT和CMD命令混合执行情况
[root@docker3 test1]# docker rm -f test1
test1
[root@docker3 test1]# ls
Dockerfile
[root@docker3 test1]# vim Dockerfile
FROM centos:7
ENTRYPOINT ["ls","/etc"]
CMD ["ls","/usr"]
[root@docker3 test1]# docker build -t centos:test .
[+] Building 0.0s (5/5) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 200B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.0s
=> CACHED [1/1] FROM docker.io/library/centos:7 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:910253575de07fda566125d6d22802d5a26579b2a04780e 0.0s
=> => naming to docker.io/library/centos:test 0.0s
[root@docker3 test1]# docker run -it --name test1 centos:test
ls: cannot access ls: No such file or directory
/etc:
BUILDTIME gshadow openldap sasl2
DIR_COLORS gshadow- opt securetty
DIR_COLORS.256color gss os-release security
DIR_COLORS.lightbgcolor host.conf pam.d selinux
GREP_COLORS hostname passwd services
GeoIP.conf hosts passwd- shadow
X11 hosts.allow pkcs11 shadow-
adjtime.rpmsave hosts.deny pki shells
aliases init.d pm skel
alternatives inputrc popt.d ssl
bash_completion.d issue prelink.conf.d subgid
bashrc issue.net printcap subuid
binfmt.d krb5.conf profile sysconfig
centos-release krb5.conf.d profile.d sysctl.d
centos-release-upstream ld.so.cache protocols system-release
chkconfig.d ld.so.conf python system-release-cpe
csh.cshrc ld.so.conf.d rc.d systemd
csh.login libaudit.conf rc.local terminfo
dbus-1 libuser.conf rc0.d tmpfiles.d
default locale.conf rc1.d udev
depmod.d localtime rc2.d vconsole.conf
dracut.conf login.defs rc3.d virc
dracut.conf.d logrotate.d rc4.d xdg
environment machine-id rc5.d xinetd.d
exports modprobe.d rc6.d yum
filesystems modules-load.d redhat-release yum.conf
gcrypt motd resolv.conf yum.repos.d
gnupg mtab rpc
group nsswitch.conf rpm
group- nsswitch.conf.bak rsyslog.d
/usr:
bin etc games include lib lib64 libexec local sbin share src tmp
##结果:
##CMD命令是以传参的方式传给ENTRYPOINT ls ls /USR
##同时cmd命令不会覆盖entrypoint的命令
ENTRYPOINT和cmd的区别:
ENTRYPOINT有多个的情况,只会运行最后一个
CMD有多个的情况下,也是运行最后一个
CMD和ENTRYPOINT同时存在,命令都会执行,ENTRYPOINT会覆盖CMD的命令。并且CMD会把命令作为参数传给ENTRYPOINT。
4、ENTRYPOINT和CMD命令混合执行情况
[root@docker3 test1]# vim Dockerfile
FROM centos:7
ENTRYPOINT ["ls","/etc"]
CMD ["-lh","/usr"]
[root@docker3 test1]# docker rm -f test1
test1
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test1 centos:test
/etc:
total 888K
/usr:
面试
作为容器启动时执行命令的语句,一般情况下二者是通用的,但是在传参的情况下,需要加上CMD,如果没有特殊操作(传参),写一个CMD或者ENTRYPOINT即可,二者不要同时存在。
5、CMD命令执行情况
[root@docker3 test1]# vim Dockerfile
FROM centos:7
#ENTRYPOINT ["ls","/etc"]
CMD ["ls","/usr"]
[root@docker3 test1]# docker rm -f test1
[root@docker3 test1]# vim Dockerfile
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test1 centos:test
bin etc games include lib lib64 libexec local sbin share src tmp
6、CMD命令,外部传参执行情况
[root@docker3 test1]# docker run -it --name test2 centos:test ls /etc
7、ENTRYPOINT命令执行情况
[root@docker3 test1]# vim Dockerfile
FROM centos:7
ENTRYPOINT ["ls","/etc"]
#CMD ["ls","/usr"]
[root@docker3 test1]# docker rm -f test1
test1
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test1 centos:test
[root@docker3 test1]# docker run -it --name test1 centos:test
8、ENTRYPOINT命令,外部传参执行情况
[root@docker3 test1]# docker run -it --name test5 centos:test ls /usr
ls: cannot access ls: No such file or directory
/etc:
/usr:
[root@docker3 test1]# docker run -it --name test6 centos:test -lh /usr
/etc:
总结:
CMD作为启动命令,运行容器时传了额外的参数,cmd会被覆盖不会被执行。
ENTRYPOINT不会被覆盖,容器运行指定的命令相当于给ENTRYPOINT传参。
2.4、RUN命令:
RUN在基础镜像运行然后把结果传给新镜像。
RUN的结构要合理,不要太多,否则镜像太大。
1、多行运行RUN
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN ls /opt
RUN ls /usr
RUN ls /etc
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test1 centos:test
1、单行RUN多个命令优化,##&& 前一个指令成功,才会执行下一个。
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN ls /opt && ls /usr && ls /etc
[root@docker3 test1]# docker build -t centos:test .
##&& 前一个指令成功,才会执行下一个。
##;前一个命令不管成不成功,后一个都会执行
##|| 前一个命令失败才会执行,后面才会执行
##\ 把一个命令分成多个行,提高可读性
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN ls /opt && Ls /usr && ls /etc
[root@docker3 test1]# docker build -t centos:test .
2、##;前一个命令不管成不成功,后一个都会执行
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN ls /opt ; ls /usr ; ls /etc
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN Ls /opt ; ls /usr ; ls /etc
[root@docker3 test1]# docker build -t centos:test .
3、##|| 前一个命令失败才会执行,后面才会执行
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN ls /opt ; ls /usr ; ls /etc
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# vim Dockerfile
FROM centos:7
RUN Ls /opt ; ls /usr ; ls /etc
[root@docker3 test1]# docker build -t centos:test .
4、##\ 把一个命令分成多个行,提高可读性,换行,提高代码可读性
总结:
多个命令写入RUN
减少镜像内存,加快容器运行速度
2.5、COPY和ADD
ADD是解压, .tar .tar.gz .zip 根据URL进行下载,复制(官方解释:同样是复制,推荐使用copy)
copy:只能复制,复制本地文件到容器内。
ADD不能复制压缩文件,使用copy。
1、ADD 解压及copy复制
[root@docker3 test1]# vim Dockerfile
FROM centos:7 ##基于centos镜像创建一个容器承载体
ADD wordpress-6.4.2-zh_CN.tar.gz /opt ##解压脚本同目录下的wordpress-6.4.2-zh_CN.tar.gz到容器的/opt目录下
COPY 123 /opt/test ##复制重命名脚本目录下的123到容器的/opt/test
[root@docker3 test1]# docker build -t centos:test .
## .代表在当前目录操作
[root@docker3 test1]# docker run -it --name test2 centos:test ##前台运行容器,进入容器查看
[root@f6fef66dbe6d /]# cd /opt/
[root@f6fef66dbe6d opt]# ls
test wordpress
[root@f6fef66dbe6d opt]#cat 123
123
2、ADD 下载、复制及copy复制
[root@docker3 test1]# vim Dockerfile
[root@docker3 test1]# docker build -t centos:test .
FROM centos:7 ##基于centos镜像创建一个容器承载体
ADD http://mirrors.aliyun.com/repo/Centos-7.repo /opt/Centos-7.repo ##下载镜像并复制到/opt下
COPY 123 /opt/test ##复制重命名脚本目录下的123到容器的/opt/test
[root@docker3 test1]# docker run -itd --name test2 centos:test
fd7ce4e91e9fe4759e5894b3a6431e62a98ff871b3483b7ffe5cdd55ee6a43d7
[root@docker3 test1]# docker exec -it test2 bash
[root@fd7ce4e91e9f /]# cd /opt/
[root@fd7ce4e91e9f opt]# ls
Centos-7.repo test
[root@fd7ce4e91e9f opt]# cat test
123
2.6、工作目录和环境变量以及容器卷(挂载卷)
1、工作目录:切换到容器内的指定目录
WORKDIR
ENV:添加一个PATH
[root@docker3 test1]# vim Dockerfile
FROM centos:7 ##基于centos镜像创建一个容器承载体
WORKDIR /opt ##指定容器的工作目录为opt==原来的/目录
ENV PATH /opt/test:$PATH
COPY /opt/234 aa/345 ##此时的opt是在/opt/test1/目录下的目录。
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -it --name test3 centos:test
[root@docker3 test1]# docker exec -it test3 bash
[root@55d2cfc45dcf opt]# ls
aa
[root@55d2cfc45dcf opt]# cd aa
[root@55d2cfc45dcf aa]# ls
345
[root@55d2cfc45dcf aa]# cat 345
9989
[root@55d2cfc45dcf opt]# echo $PATH
/opt/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
2、在脚本中设置容器的挂载点
[root@docker3 test1]# vim Dockerfile
FROM centos:7
WORKDIR /opt
ENV PATH /opt/test:$PATH
COPY /opt/234 bb/345
VOLUME ["/opt/test"] ##容器挂载点
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -itd --name test1 centos:test /bin/bash
9a248e75e210dc1a30a5bbf88393450888811f01f5d3912b47b67dfc5883ea68
[root@docker3 test1]# docker run -it --name test2 --volumes-from test1 centos:test
[root@45dcc50e0f33 opt]# ls
bb test
[root@45dcc50e0f33 opt]# cd bb
[root@45dcc50e0f33 bb]# ls
345
[root@45dcc50e0f33 bb]# cd ..
[root@45dcc50e0f33 opt]# cd test/
[root@45dcc50e0f33 test]# ls
2.7、EXPOSE指定端口
1、##实战,yum安装定制一个nginx
[root@docker3 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"]
CMD ["nginx","-g","daemon off;"]
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -itd --name nginx1 centos:test
c1687c0298ea82aeeced3d6fcca84f9a860543265b4f89e51d814abf541be503
[root@docker3 test1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker3 test1]# docker run -itd --name nginx2 centos:test /bin/bash ##保持容器运行不停止
03112c0ad206814eaeb91f993e233b4a2ade5bcede1c752a1fdf72f1686fe679
[root@docker3 test1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03112c0ad206 centos:test "/bin/bash" 2 seconds ago Up 1 second 80/tcp nginx2
[root@docker3 test1]# docker exec -it nginx2 bash
[root@03112c0ad206 nginx]# cd /usr/share/nginx/html/
[root@03112c0ad206 html]# ls
404.html 50x.html en-US icons img index.html nginx-logo.png poweredby.png
[root@docker3 test]# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx1
172.17.0.2
[root@docker3 test]# curl 172.17.0.2
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
[root@docker3 test]# docker exec -it nginx1 bash
[root@b228f0431382 nginx]# cd /usr/share/nginx/html
[root@b228f0431382 html]# ll
[root@b228f0431382 html]# ll
total 12
-rw-r--r--. 1 root root 3650 Nov 10 2022 404.html
-rw-r--r--. 1 root root 3693 Nov 10 2022 50x.html
lrwxrwxrwx. 1 root root 20 Aug 15 06:06 en-US -> ../../doc/HTML/en-US
drwxr-xr-x. 2 root root 27 Aug 15 08:43 icons
lrwxrwxrwx. 1 root root 18 Aug 15 06:06 img -> ../../doc/HTML/img
lrwxrwxrwx. 1 root root 25 Aug 15 06:06 index.html -> ../../doc/HTML/index.html
-rw-r--r--. 1 root root 368 Nov 10 2022 nginx-logo.png
lrwxrwxrwx. 1 root root 14 Aug 15 06:06 poweredby.png -> nginx-logo.png
[root@b228f0431382 html]# cat index.html
cat: index.html: No such file or directory
[root@b228f0431382 html]# rm -rf index.html
[root@b228f0431382 html]# echo 123 > index.html
[root@b228f0431382 html]#
[root@docker3 test]# curl 172.17.0.2
123
2、挂载卷
[root@docker3 test1]# docker run -itd --name nginx5 -v /opt/html:/usr/share/nginx/html centos:test
[root@docker3 test]# docker exec -it nginx5 bash
[root@16cd20a93b21 nginx]# cd /usr/share/nginx/html/
[root@16cd20a93b21 html]# ls
[root@docker3 test]# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx5
172.17.0.4
[root@docker3 test]# curl 172.17.0.4
123
3、挂载容器共享卷
[root@docker3 test1]# docker run -itd --name nginx6 --volumes-from nginx5 centos:test
796f39f9146ca804acf33df9e87d242dc907277bcf1717156ad72d8cf0545479
[root@docker3 test1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
796f39f9146c centos:test "nginx -g 'daemon of…" 7 seconds ago Up 6 seconds 80/tcp nginx6
[root@docker3 test]# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx6
172.17.0.5
[root@docker3 test]# curl 172.17.0.5
123
4、在脚本目录下,写入nginx配置文件,一起复制到容器里面
[root@docker3 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
COPY nginx.conf /opt/nginx/
WORKDIR /var/log/nginx/
VOLUME ["/usr/share/nginx/html"]
ENTRYPOINT ["nginx","-g","daemon off;"]
[root@docker3 test1]# vim nginx.conf
345
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -itd --name nginx1 centos:test
[root@docker3 test]# docker exec -it nginx1 bash
[root@059f29234051 nginx]# cd /opt/nginx/
[root@059f29234051 nginx]# ls
nginx.conf
[root@docker3 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
COPY nginx.conf /opt/nginx/
WORKDIR /var/log/nginx/
VOLUME ["/usr/share/nginx/html"]
ENTRYPOINT ["nginx","-g","daemon off;"]
[root@docker3 test1]# vim nginx.conf
345
[root@docker3 test1]# docker build -t centos:test .
[root@docker3 test1]# docker run -itd --name nginx1 centos:test
[root@docker3 test]# docker exec -it nginx1 bash
[root@059f29234051 nginx]# cd /opt/nginx/
[root@059f29234051 nginx]# ls
nginx.conf