docker的数据卷
容器和宿主机之间,或者容器和容器之间的数据共享(目录)。
创建容器的时候,通过指定目录,实现容器和宿主机之间,或者容器和容器之间的数据共享。
容器的生命周期是有限的,容器一旦销毁,内部的数据也会一并消失,所有我们创建了数据卷的方式,将容器内的数据持久化保存到宿主机。
宿主机和容器的数据卷

- -v:volume,挂载卷,数据卷。
- -v前面是宿主机目录,后面是容器目录。
- 挂载后,以宿主机目录为优先,容器的生命周期是有限的,保存到宿主机的数据可以在下一次创建容器时继续使用。

- ro:容器目录权限是只读;数据卷的默认权限是rw。
容器和容器的数据卷
容器和容器之间共享数据

- -v:指定目录,如果后面没有:,这个目录就是容器内的数据目录,不会和宿主机挂载
- volumes-from:另外一个容器,使用其他容器提高的数据目录。这个目录仅限于容器内数据共享,一旦容器销毁,内部数据目录也会一并销毁。
练习
创建容器,指定挂载卷容器内的nginx的日志目录和宿主机挂载,nginx的映射端口为随机端口。然后访问容器,可以在宿主机显示日志的内容。

创建容器的三要素:创建容器的时候,一定要做宿主机和容器之间的端口映射(容器对外提高访问),一定要对容器做资源限制,一定要做数据卷。
dockerfile
自定义镜像
基于dockerfile创建,联合文件系统,UnionFs是创建docker镜像的基础,镜像可以通过分层来进行集成,基于基础的镜像可以制作各自应用的镜像。
特点:一次性加载多个文件系统,但是创建好容器之后,对于用来说只有一个文件系统。
镜像底层架构

docker镜像的定制化操作实际上就是定制每一层所要添加的配置和文件等等
把所有的需要的操作写入一个脚本当中,然后一键运行,就是dockerfile。
dockerfile组成和命令
dockerfile作为一个脚本,由四部分组成:
- 基础镜像:程序的运行环境
- 维护者信息(可选项,相当于注释)可以不加
- 镜像的操作命令(自定义应用)
- 容器启动时的命令(容器没有可执行的命令,就会退出,进入stop状态,必须要给容器一个可执行的持久化的命令)
dockerfile的命令格式
- FROM:指定程序的基础镜像
- MAINTAINER / LABEL:维护者信息(可以不加)
镜像的操作命令
- RUN:在基础镜像运行命令,结果提交到新镜像。每执行一次run,就相当于是镜像的一层,run的命令太多,镜像的分层就越多,镜像就越大。
- ADD:将宿主机的文件复制到镜像的内部,可以URL和解压。
- COPY:将宿主机的文件复制到镜像内部,只能是宿主机的本地文件,不支持下载。
- ENV:指定镜像内的容器运行之后的环境变量
- WORKDIR:容器的工作目录,也是进入容器之后的默认目录。
- USER:指定容器运行时的用户名或者UID
- VOLUME:创建容器内的挂载点,可被外部使用,既可以和宿主机挂载,也可和容器使用。
- EXPOSE:声明容器对外的网络端口
- ARG:用来传递变量,把宿主机的参数传递到容器内部的参数。
容器启动的命令
- CMD:指定容器运行时的默认命令
- ENTRYPOINT:指定容器运行时的默认命令
CMD和ENTRYPOINT的区别
- CMD可以给ENTRYPOINT传参。
- entrypoint会覆盖cmd的命令。
- 当创建容器时,外部定义了参数,如果是cmd,会被外部的传参覆盖,只会执行外部传参的命令,但是entrypoint的命令是不会被外部传参的命令覆盖的。
- 如果有多个CMD和ENTRYPOINT只会执行最后一个。
如我们创建一个dockerfile,使用CMD和ENTRYPOINT制作镜像,运行容器后可以发现执行了两次命令:
1、ENTRYPOINT执行了ls -a /etc的命令
2、CMD传参,又执行了一次ls -lh /usr的命令
说明如果有多个CMD和ENTRYPOINT只会执行最后一个,同时CMD可以给ENTRYPOINT传参。

开启镜像的制作
- -t:创建完只会给镜像指定名称和标签
- .:直接从当前目录的dockerfile文件创建镜像



run命令
run命令在一个dockerfile当中不能太多,每执行一次run,就相当于是镜像的一层,run的命令太多,镜像的分层就越多,镜像就越大。
RUN apt -y insatll nginx && apt -y install httpd
RUN apt -y insatll nginx ; apt -y install httpd
- &&:在run命令中,表示连接多个命令,确保前一个命令执行成功,才会运行第二个命令。
- ;:表示连接多个命令,不管前面的命令是否成功,都会执行后面的命令
- ||:只有前面的失败了,后面的命令才会执行。
如我们创建一个dockerfile,以镜像ubuntu:22.04为基础创建镜像,执行apt命令,暴露82端口,并且启动Nginx服务并使其在前台运行,而不是作为后台守护进程。


add和copy命令
1、add和copy在复制文件时,表现是一致的,尤其是复制本地文件(和dockerfile在一个目录下的文件)自动复制到指定路径。
2、解压和下载只能用add
add的优点:没有格式的限制,直接跟上路径会自动解压到目标路径。
add缺点:在不解压的前提下,无法复制tar的压缩文件。
总结:只是复制使用copy;如果是压缩使用add。
复制:复制宿主机的nginx.conf到容器/etc/nginx/目录下

解压:解压宿主机的nginx安装包到容器/opt/目录下

下载:下载阿里源到容器的/opt/目录下
工作目录、环境变量和容器卷
如创建一个自定义镜像,工作目录是/opt,自定义环境变量和容器卷目录。

练习
定制化的创建一个nginx的基于源码包的镜像,用ubuntu实现nginx:1.22的编译版本,暴露端口为84,设置nginx的默认访问目录为/var/www/html/ 宿主机和访问目录实现挂载,限制cpu只能使用10%,以及1g的内存。
首先创建一个自定义镜像dockerfile脚本Dockerfile,在脚本Dockerfile同一个目录下准备好nginx包

在脚本Dockerfile同一个目录下准备好nginx的主配置文件nginx.conf

准备好宿主机上挂载目录,配置好nginx的访问页面index.html


docker build -t nginx11 . #直接拉取镜像命名nginx11
创建容器nginx22,宿主机/opt/nginx和容器/var/www/html/访问目录实现挂载,端口映射是随机端口,限制cpu只能使用10%,以及1g的内存。

这时候我们宿主机32770端口和容器84端口成功映射,我们访问宿主机的32770端口便访问了容器的84端口(nginx程序)。