出现的意义:
- 数据持久化,因为容器删除后,保存在容器中的数据会丢失
- 方便容器与宿主机数据交互
docker数据类型:
- **数据卷 ** :相当于mount一块磁盘
- 数据容器:将数据保存在容器上,用于容器间共享数据,这种容器一般不跑应用,只是挂载卷
-
具名挂载
-v 卷名:容器路径 [root@master ~]# docker run -d -P -v test_volume:/etc/nginx --name="nginx_name" nginx:latest f7640ae90c7ec4a2514bc0bf4fb41c156c21d9e5b3ab43aabcba7ed279a9b3df [root@master ~]# docker volume ls DRIVER VOLUME NAME local 7a767141bcb3e25b07c67aaad61ffacab081d1b80937fc7b02c3184cd4706b0b local 7727d1a368eec5721da70bf1af6121065b646a7be02d97b007e9c8b508148029 local test_volume [root@master ~]# docker volume inspect test_volume|grep Mountpoint "Mountpoint": "/var/lib/docker/volumes/test_volume/_data", -
匿名挂载
-v 容器路径 [root@master ~]# docker run -d -P -v /etc/nginx --name="nginx_01" nginx:latest c986f508b492e8327a0916c54f824f2f46490f50674fd0ef6c2303d369a304ad
没有指定宿主机目录的,一般默认宿主机路径为/var/lib/docker/volumes/卷名/_data
-
指定宿主机路径挂载
-v 宿主机路径:容器路径
#挂载时可添加容器对卷的权限控制,默认为rw,可指定ro,ro表示仅能在宿主机更改文件内容,在docker内只读 -v 宿主机路径:容器路径:ro测试一:挂载centos镜像
[root@master ~]# docker run -it -v /root/yiyu/centos_tmp:/tmp centos:latest /bin/bash
[root@master centos_tmp]# docker ps
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c475662fa21b centos:latest "/bin/bash" 4 minutes ago Up 4 minutes silly_hamilton
#检查是否挂载成功
[root@master centos_tmp]# docker inspect c475662fa21b|grep -i mounts -A 10
"Mounts": [
{
"Type": "bind",
"Source": "/root/yiyu/centos_tmp",
"Destination": "/tmp",
"Mode": "",
"RW": true, #默认挂载权限为rw
"Propagation": "rprivate"
}
],
"Config": {
[root@master centos_tmp]#
分别在容器外创建文件、容器内创建文件验证:
停止容器,检查文件是否存在:
测试二:搭建mysql卷环境[root@master centos_tmp]# docker pull mysql:5.7
[root@master ~]# docker run -it -d --name="mysql_docker" -v /root/yiyu/mysql/conf:/etc/mysql/conf -v /root/yiyu/mysql/libs:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
c738c38ffdf5b5d731cedec603215886b74ad83...03a0bf6cb2249986c5d9
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c738c38ffdf5 mysql:5.7 "docker-entrypoint.s…" 37 seconds ago Up 36 seconds 3306/tcp, 33060/tcp mysql_docker
#查看挂载状态
[root@master ~]# docker inspect c738c38ffdf5|grep -i mounts -A 20
"Mounts": [
{
"Type": "bind",
"Source": "/root/yiyu/mysql/conf",
"Destination": "/etc/mysql/conf",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/root/yiyu/mysql/libs",
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "c738c38ffdf5",
"Domainname": "",
#查看本地路径
[root@master ~]# ll /root/yiyu/mysql/
total 4
drwxr-xr-x. 2 root root 6 Nov 22 22:08 conf
drwxr-xr-x. 5 polkitd root 4096 Nov 22 22:10 libs
[root@master ~]# ll /root/yiyu/mysql/conf/
total 0
[root@master ~]# ll /root/yiyu/mysql/libs/
total 188484
-rw-r-----. 1 polkitd input 56 Nov 22 22:08 auto.cnf
-rw-------. 1 polkitd input 1676 Nov 22 22:08 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 Nov 22 22:08 ca.pem
-rw-r--r--. 1 polkitd input 1112 Nov 22 22:08 client-cert.pem
-rw-------. 1 polkitd input 1676 Nov 22 22:08 client-key.pem
...
#查看容器内路径
[root@master centos_tmp]# docker exec -it c738c38ffdf5 /bin/bash
root@c738c38ffdf5:/# ls /etc/mysql/conf
root@c738c38ffdf5:/# ls -l /var/lib/mysql
total 188484
-rw-r-----. 1 mysql mysql 56 Nov 22 14:08 auto.cnf
-rw-------. 1 mysql mysql 1676 Nov 22 14:08 ca-key.pem
-rw-r--r--. 1 mysql mysql 1112 Nov 22 14:08 ca.pem
-rw-r--r--. 1 mysql mysql 1112 Nov 22 14:08 client-cert.pem
-rw-------. 1 mysql mysql 1676 Nov 22 14:08 client-key.pem
...
#容器内创建文件,容器外验证
root@c738c38ffdf5:/# echo "test_sh" > /etc/mysql/conf/test_sh_yiyu.sh
root@c738c38ffdf5:/# exit
[root@master centos_tmp]# ls /root/yiyu/mysql/conf/ -l
total 4
-rw-r--r--. 1 root root 8 Nov 22 22:18 test_sh_yiyu.sh
#删除容器,验证文件是否还在
[root@master centos_tmp]# docker rm -f c738c38ffdf5
c738c38ffdf5
[root@master centos_tmp]# docker ps
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@master centos_tmp]# ll /root/yiyu/mysql/
total 4
drwxr-xr-x. 2 root root 29 Nov 22 22:18 conf
drwxr-xr-x. 5 polkitd root 4096 Nov 22 22:10 libs
[root@master centos_tmp]# ll /root/yiyu/mysql/conf/
total 4
-rw-r--r--. 1 root root 8 Nov 22 22:18 test_sh_yiyu.sh
[root@master centos_tmp]# ll /root/yiyu/mysql/libs/
total 188484
-rw-r-----. 1 polkitd input 56 Nov 22 22:08 auto.cnf
-rw-------. 1 polkitd input 1676 Nov 22 22:08 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 Nov 22 22:08 ca.pem
-rw-r--r--. 1 polkitd input 1112 Nov 22 22:08 client-cert.pem
-rw-------. 1 polkitd input 1676 Nov 22 22:08 client-key.pem
...
#至此,容器创建时通过-v挂载的目录,容器运行后新增到挂载目录的文件,在容器删除时不会消失
测试三:通过dockerFile挂载数据卷
#创建docker_file文件目录
[root@master docker_file]# mkdir -p ~/yiyu/docker_file/
[root@master docker_file]# cd ~/yiyu/docker_file/
#挂载3个卷的docker file
[root@master docker_file]# tee ~/yiyu/docker_file/test_docker_file <<- 'EOF'
> FROM centos:latest
> VOLUME ["volume1","volume2","volume3"]
> CMD echo "ok"
> CMD /bin/bash
> EOF
FROM centos:latest
VOLUME ["volume1","volume2","volume3"]
CMD echo "ok"
CMD /bin/bash
#编译镜像
[root@master docker_file]# docker build -f ~/yiyu/docker_file/test_docker_file -t yiyu/centos:1.0 ./
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos:latest
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume1","volume2","volume3"]
---> Using cache
---> e1c7151792b2
Step 3/4 : CMD echo "ok"
---> Using cache
---> 313c3d61e1f6
Step 4/4 : CMD /bin/bash
---> Using cache
---> a4d1fa934530
Successfully built a4d1fa934530
Successfully tagged yiyu/centos:1.0
#查看镜像
[root@master docker_file]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
yiyu/centos 1.0 a4d1fa934530 about a minute ago 231MB
tomcat_local 1.0 c0855d5befbd 26 hours ago 685MB
tomcat 9.0 76206e3ba4b1 4 days ago 680MB
#启动容器检查挂载是否成功
[root@master docker_file]# docker run -it --name="yiyu_centos" yiyu/centos:1.0 /bin/bash
[root@3fdfae345dcc /]# ls -ld vo*
drwxr-xr-x. 2 root root 6 Nov 23 14:21 volume1
drwxr-xr-x. 2 root root 6 Nov 23 14:21 volume2
drwxr-xr-x. 2 root root 6 Nov 23 14:21 volume3
[root@3fdfae345dcc /]# touch volume1/test_by
#退出容器检查文件是否创建成功
[root@3fdfae345dcc /]# exit
exit
[root@master docker_file]# docker inspect yiyu_centos
"Type": "volume",
"Name": "fafa186d6965db85cec19eba9473e19f1b713569ed15f89873130eeb75d86a4a",
"Source": "/var/lib/docker/volumes/fafa186d6965db85cec19eba9473e19f1b713569ed15f89873130eeb75d86a4a/_data",
"Destination": "volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
#查得volume1对应得宿主机路径为/var/lib/docker/volumes/fafa186d6965db85cec19eba9473e19f1b713569ed15f89873130eeb75d86a4a/_data
[root@master docker_file]# ls -l /var/lib/docker/volumes/fafa186d6965db85cec19eba9473e19f1b713569ed15f89873130eeb75d86a4a/_data
total 0
-rw-r--r--. 1 root root 0 Nov 23 22:22 test_by
数据容器
--volumes-from #先启动一个容器A,再通过--volumes-from 指定复制容器A的卷来启动容器B、C,则容器A、B、C卷内容共享,任意容器宕机后不会导致其他容器卷内容消失 #用上面生成的yiyu_centos启动3个容器验证,已知yiyu_centos挂载了3个卷:volume1~volume3 #创建第一个 [root@master ~]# docker run -it --name="docker01" yiyu/centos:1.0 /bin/bash [root@5a186457299a /]# ls -dl volume* drwxr-xr-x. 2 root root 6 Nov 24 11:58 volume1 drwxr-xr-x. 2 root root 6 Nov 24 11:58 volume2 drwxr-xr-x. 2 root root 6 Nov 24 11:58 volume3 #再开一个窗口创建第二个 [root@master ~]# docker run -it --name="docker02" --volumes-from docker01 yiyu/centos:1.0 /bin/bash [root@800867154ec9 /]# ls -ld volume* drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume1 drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume2 drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume3 #再开一个创建创建第三个 [root@master ~]# docker run -it --name="docker03" --volumes-from docker02 yiyu/centos:1.0 /bin/bash [root@d6c45a5f7461 /]# ls -ld volume* drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume1 drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume2 drwxr-xr-x. 2 root root 6 Nov 24 12:00 volume3 #创建好了,在docker02里创建个文件,看docker03、docker01里是否有(见下图)
#删除docker01,验证docker02、docker03卷中文件是否还在(见下图) [root@master ~]# docker rm -f docker01 docker01 [root@master ~]# docker ps -a ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d6c45a5f7461 yiyu/centos:1.0 "/bin/bash" 5 minutes ago Up 5 minutes docker03 800867154ec9 yiyu/centos:1.0 "/bin/bash" 6 minutes ago Up 6 minutes docker02 [root@master ~]#volume管理
docker volume create 卷名 #使用默认的local drive创建一个volume docker rm -v 容器id #删除容器时删除卷 docker volume rm 卷名 #删除卷 docker volume ls #查看本机卷 docker volume ls -qf dangling=true #查询孤单卷 docker volume inspect 卷名 #查看指定卷信息 docker inspect 卷名 #查看指定卷信息 #当用rm删除容器后,会留下孤单卷 docker volume rm $(docker volume ls -qf dangling=true) #批量删除孤单卷DockerFile 构建步骤
- 编写dockerfile
- docker build
- docker run
- dockers push
- 每个指令(关键字)必须大写
- 从上到下,顺序执行
- 注释用#
- 每一个指令都创建一个镜像层并提交
FROM #基础镜像,基础镜像必须是小写,否则会 invalid reference format: repository name must be lowercase MAINTAINER #维护者信息 ADD #往镜像中添加 COPY #类似ADD,往镜像中拷贝东西 RUN #构建时运行的指令 CMD #启动时默认运行的指令,如果指定了其他执行命令或者用了ENTRYPOINT,CMD就不会执行 ENTRYPOINT #容器启动时运行的指令,追加 onBUILD #这个镜像被继承时,触发的动作 ENV #设置镜像的环境变量 WORKDIR #指定镜像的工作目录,进去容器默认的目录 EXPOSE #暴露端口 VOLUME #卷挂载,无法指定宿主机的对应目录,只能随机生成,VOLUME ["/data1","/data2"]
CMD和ENTRYPOINT的区别:
- 编写两个dockersfile
[root@master docker_file]# cat docker_cmd FROM centos MAINTAINER yiyu CMD ["ls","-a"] [root@master docker_file]# cat docker_entrypoint FROM centos MAINTAINER yiyu ENTRYPOINT ["ls","-a"] [root@master docker_file]#
2. 分别编译生成镜像
[root@master docker_file]# docker build -f docker_cmd -t centos_cmd:0.1 . [root@master docker_file]# docker build -f docker_entrypoint -t centos_entrypoint:0.1 . [root@master docker_file]#
3. 查看镜像列表
[root@master docker_file]# docker images|grep centos centos_entrypoint 0.1 5fa9ded07c07 6 seconds ago 231MB centos_cmd 0.1 e615afa00c74 10 seconds ago 231MB mycentos 1.0 3e8d28433743 2 days ago 371MB yiyu/centos 1.0 a4d1fa934530 3 days ago 231MB centos latest 5d0da3dc9764 2 months ago 231MB
- 运行容器,在docker run后添加-a对比
[root@master docker_file]# docker run -it centos_cmd:0.1 -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown. ERRO[0001] error waiting for container: context canceled [root@master docker_file]# docker run -it centos_entrypoint:0.1 -l total 0 drwxr-xr-x. 1 root root 6 Nov 27 07:16 . drwxr-xr-x. 1 root root 6 Nov 27 07:16 .. -rwxr-xr-x. 1 root root 0 Nov 27 07:16 .dockerenv lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Nov 27 07:16 dev drwxr-xr-x. 1 root root 66 Nov 27 07:16 etc drwxr-xr-x. 2 root root 6 Nov 3 2020 home ...
- 结论:从上可以看出,启动时添加的-a,会把CMD中的参数全部替换掉,转而把你输入的参数当成命令去执行,而会在ENTRYPOINT的参数后面是添加。即-l和ls -a -l的区别。
#编写前 [root@master ~]# docker images|grep centos yiyu/centos 1.0 a4d1fa934530 23 hours ago 231MB centos latest 5d0da3dc9764 2 months ago 231MB
1.编写dockerfile
[root@master docker_file]# cat ~/yiyu/docker_file/centos_docker_file MAINTAINER yiyu ENV default_path="/usr/local/bin" WORKDIR $default_path RUN yum install -y perf RUN yum install -y net-tools EXPOSE 8080 CMD echo "$default_path" CMD /bin/bash
- 构建dockerfile,看到最后的两个successfully就说明构建成功了
[root@master docker_file]# docker build -f centos_docker_file -t mycentos:1.0 ~/yiyu/docker_file/ Sending build context to Docker daemon 3.072kB Step 1/9 : FROM yiyu/centos:1.0 ... Successfully built 3e8d28433743 Successfully tagged mycentos:1.0 #查看镜像 [root@master docker_file]# docker images|grep centos mycentos 1.0 3e8d28433743 46 seconds ago 371MB yiyu/centos 1.0 a4d1fa934530 23 hours ago 231MB centos latest 5d0da3dc9764 2 months ago 231MB
- 分别启动 yiyu/centos:1.0 和 mycentos:1.0 对比,发现前者无perf和ifconfig命令,后者有
#启动制作前的 [root@master docker_file]# docker run -it --name="before_centos" yiyu/centos:1.0 /bin/bash [root@aaf5b20b026f /]# perf --help bash: perf: command not found [root@aaf5b20b026f /]# ifconfig bash: ifconfig: command not found [root@aaf5b20b026f /]# #启动制作后的 [root@master docker_file]# docker run -it --name="after_centos" mycentos:1.0 /bin/bash [root@49812951c620 bin]# perf --help usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS] ... [root@49812951c620 bin]# ifconfig eth0: flags=4163实例2:制作可动态发布的tomcat镜像mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 8 bytes 656 (656.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1. 准备一个tomcat包和jdk包
[root@master tomcat_pack]# ll
total 195380
-rw-r--r--. 1 root root 10305939 Nov 27 15:27 apache-tomcat-8.5.50.tar.gz
-rw-r--r--. 1 root root 189756259 Nov 27 15:44 jdk-8u161-linux-x64.tar.gz
-rw-r--r--. 1 root root 0 Nov 27 15:47 readMe.md
#创建目录
[root@master tomcat_pack]# mkdir -p ./tomcat_8.5.50/{test,logs}
2. 编写dockerfile
[root@master tomcat_pack]# cat docker_tomcat FROM centos MAINTAINER yiyu ADD ./jdk-8u161-linux-x64.tar.gz /usr/local/ ADD ./apache-tomcat-8.5.50.tar.gz /usr/local/ COPY ./readMe.md /usr/local/ RUN yum -y install which net-tools ENV MY_PATH="/usr/local" ENV WORKDIR=$MY_PATH ENV JAVA_HOME="/usr/local/jdk1.8.0_161" ENV CLASSPTH="$JAVA_HOME/lib" ENV CATALINA_HOME="/usr/local/apache-tomcat-8.5.50" ENV CATALINA_BASH="/usr/local/apache-tomcat-8.5.50" ENV PATH="$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin" EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.50/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.50/logs/catalina.out
- 构建dockerfile
[root@master tomcat_pack]# docker build -f docker_tomcat -t mytomcat:0.1 . Sending build context to Docker daemon 200.1MB Step 1/15 : FROM centos ---> 5d0da3dc9764 Step 2/15 : MAINTAINER yiyu ... ---> a9138168a7bb Successfully built a9138168a7bb Successfully tagged mytomcat:0.1 [root@master tomcat_pack]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat 0.1 a9138168a7bb 3 minutes ago 669MB centos_entrypoint 0.1 5fa9ded07c07 about an hour ago 231MB centos_cmd 0.1 e615afa00c74 about an hour ago 231MB
- 启动容器
[root@master tomcat_pack]# docker run -idt --name="tomcat_test" -p 9080:8080 -v /root/tomcat_pack/tomcat_8.5.50/logs:/usr/local/apache-tomcat-8.5.50/logs -v /root/tomcat_pack/tomcat_8.5.50/test:/usr/local/apache-tomcat-8.5.50/webapps/test mytomcat:0.1 51b6911b1f683cc7ccb07e8639702fd8fd01b328df9414ab13d463ac5b173275
- 访问验证
[root@master tomcat_pack]# curl -I localhost:9080 HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Transfer-Encoding: chunked Date: Sat, 27 Nov 2021 08:52:42 GMT
- 发布新内容
#因为在dockerfile中做了test目录的卷挂载(通过docker inspect 容器id可确认),所以直接修改test目录的内容,就会更新容器中test目录的内容
"Mounts": [
{
"Type": "bind",
"Source": "/root/tomcat_pack/tomcat_8.5.50/logs",
"Destination": "/usr/local/apache-tomcat-8.5.50/logs",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/root/tomcat_pack/tomcat_8.5.50/test",
"Destination": "/usr/local/apache-tomcat-8.5.50/webapps/test",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
#修改/root/tomcat_pack/tomcat_8.5.50/test下的内容
[root@master test]# cat index.html
hello java
[root@master test]#
- 验证访问
[root@master test]# curl localhost:9080/test/hello java
[root@master test]# #又因为做了日志路径挂载,所以也可以在宿主机的/usr/local/apache-tomcat-8.5.50/logs下查看日志,不用登入容器,即使节点宕机,日志也不会丢失。
或者用浏览器访问:
- 发布镜像到docker hub
[root@master tomcat_8.5.50]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat 0.1 a9138168a7bb 19 minutes ago 669MB centos_entrypoint 0.1 5fa9ded07c07 2 hours ago 231MB #push到官方hub需要已名字/镜像名:tag的形式,上面做的这个mytomcat:1.0需要重新打tag [root@master tomcat_8.5.50]# docker tag mytomcat:0.1 yiyu5527/mytomcat8.5.50:0.1 [root@master tomcat_8.5.50]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE yiyu5527/mytomcat8.5.50 0.1 a9138168a7bb 24 minutes ago 669MB mytomcat 0.1 a9138168a7bb 24 minutes ago 669MB #push(记得先执行docker login登录自己帐号,没有帐号需要先去docker hub注册) [root@master tomcat_8.5.50]# docker push yiyu5527/mytomcat8.5.50:0.1 The push refers to repository [docker.io/yiyu5527/mytomcat8.5.50] a5db832a5077: Pushed ec1302ae29f9: Pushed c10265c2b734: Pushed 03c12ebc4a35: Pushed 74ddd0ec08fa: Mounted from library/centos 0.1: digest: sha256:87acca3eb6329ac9721e820ae891502...f8fea38dda512dd90d2cb0810af size: 1373 上传成功
扩展:
docker history 镜像id #查看镜像的构建记录 docker login [仓库地址] #登录仓库,不带地址默认为docker hub,带地址则表示登录登录指定仓库,一般后者用的多 docker logout #登出 docker save #保存镜像到本地,比如备份成tar包 docker tag 镜像id #给镜像重新打tag docker push
最后附上docker的全流程图(侵删)



