如果运行中的容器修改如果生成了新的数据或者修改了现有的一个已经存在的文件内容,那么新产生的数据将会被复制到读写层进行持久化保存,这个读写层也就是容器的工作目录,此即“写时复制(COW)copy on write”机制
#查看指定PID的容器信息
日志:
[root@gbase8c_private haproxy-1.8.31]# docker inspect bd4ec06804db
.......
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a-init/diff:/var/lib/docker/overlay2/d214d50660ae41a278d91e2c6c29fd4a7cc8184a98d5a6806c083e69dcc6e3fa/diff:/var/lib/docker/overlay2/7519ab25a179a968ecea9c106ff942cb7773ccdf45a28481fffb0459e18820ce/diff:/var/lib/docker/overlay2/d3bb81d4b06b5a73c5ced34a63078c386bdf78e7284673222ab2a620d5f0961f/diff:/var/lib/docker/overlay2/d9c3436b42f5d4b6d20e657640f1367ccbdba9521bc24d2f4e28dfaaf1d35537/diff:/var/lib/docker/overlay2/eb71623e9d9461ab5f07a015ce1882ad64366fd660e2431819cc248211d49b02/diff:/var/lib/docker/overlay2/0a665e15bd865f0001c1627b299c1704ac24c5411c4f10253946aae3087d54a6/diff:/var/lib/docker/overlay2/dac7c052b6df0bc270aa518861aff146477172886deb3dc593eaef00cd0de4cb/diff:/var/lib/docker/overlay2/d82086cfc2f1bc7fddb53f836e70daa237746cbd4a53dc5d8f70e59d8650c846/diff:/var/lib/docker/overlay2/a86b253e60b8498a4c59a48951e43f5c77a5e5e8266e405f8a7e8e1b20a63dc9/diff:/var/lib/docker/overlay2/ce3de19266860f7e3493ba9b16649347e9bd92ba648261843bd14fb1dd9e1e54/diff:/var/lib/docker/overlay2/f1bf8e7f890b1a1071493b75983686629b4e50c2bb38a7b77b1c044660a762f2/diff:/var/lib/docker/overlay2/43af4ff05b28f124d174b05c8f91a519e026386552867953fd4cc7c228497827/diff",
"MergedDir": "/var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/merged",
"UpperDir": "/var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/diff",
"WorkDir": "/var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/work"
},
.......
[root@gbase8c_private haproxy-1.8.31]# docker exec -it bd4ec06804db bash
[root@bd4ec06804db /]# dd if=/dev/zero of=file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0658615 s, 1.6 GB/s
[root@bd4ec06804db /]# md5sum file
2f282b84e7e608d5852449ed940bfc51 file
[root@bd4ec06804db /]# ls
apps dev file lib lost+found mnt proc run srv tmp var
bin etc home lib64 media opt root sbin sys usr
[root@bd4ec06804db /]# cp file /opt/file.log
[root@gbase8c_private haproxy-1.8.31]# tree /var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/diff
/var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/diff
├── apps
│ └── apache-tomcat-8.5.96
│ ├── conf
│ │ └── Catalina
│ │ └── localhost
│ ├── logs
│ │ ├── catalina.2023-12-10.log
│ │ ├── catalina.2023-12-12.log
│ │ ├── catalina.out
│ │ ├── host-manager.2023-12-10.log
│ │ ├── host-manager.2023-12-12.log
│ │ ├── localhost.2023-12-10.log
│ │ ├── localhost.2023-12-12.log
│ │ ├── localhost_access_log.2023-12-10.txt
│ │ ├── localhost_access_log.2023-12-12.txt
│ │ ├── manager.2023-12-10.log
│ │ └── manager.2023-12-12.log
│ └── work
│ └── Catalina
│ └── localhost
│ ├── docs
│ ├── examples
│ ├── host-manager
│ ├── manager
│ ├── myapp
│ └── ROOT
│ └── org
│ └── apache
│ └── jsp
│ ├── index_jsp.class
│ └── index_jsp.java
├── file ######当前容器中产生的数据
├── opt ######当前容器中产生的数据
│ └── file.log ######当前容器中产生的数据
├── root
├── tmp
│ └── hsperfdata_www
│ └── 29
└── var
└── log
└── lastlog
24 directories, 17 files
#验证md5值一致
[root@gbase8c_private haproxy-1.8.31]# md5sum /var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/diff/opt/file.log
2f282b84e7e608d5852449ed940bfc51 /var/lib/docker/overlay2/dddd5100022dc9dd378bbf2335238c397d1af17a5aea082bb92fbef9c812c93a/diff/opt/file.log
数据卷实际上就是宿主机上的目录或者是文件,可以被直接mount到容器当中使用。
实际生成环境中,需要针对不同类型的服务、不同类型的数据存储要求做相应的规划,最终保证服务的可扩展性、稳定性及安全性。
mkdir /usr/local/testapp/
echo "Test App Page" > /usr/local/testapp/index.html
cat /usr/local/testapp/index.html
[root@gbase8c_private testapp]# cat /usr/local/testapp/index.html
Test App Page
使用-v参数,将宿主机目录映射到容器内部,web2的ro标示在容器内对该目录只读,默认是可读写的
docker run -d --name web1 -v /usr/local/testapp/:/apps/tomcat/webapps/testapp -p8888:8080 tomcat-web:app1
docker run -d --name web2 -v /usr/local/testapp/:/apps/tomcat/webapps/testapp:ro -p8889:8080 tomcat-web:app2
日志:
[root@gbase8c_private testapp]# docker run -d --name web1 -v /usr/local/testapp/:/apps/tomcat/webapps/testapp -p8888:8080 tomcat-web:app1
5406ca7307ee47cf6a29d47822b33d1c9964cf64563b8e7beb839932cfe7a259
[root@gbase8c_private testapp]# docker run -d --name web2 -v /usr/local/testapp/:/apps/tomcat/webapps/testapp:ro -p8889:8080 tomcat-web:app2
903990f7d923082bc124158319c2226a8859c4b7d34b6af0ca8622b0d2fb4fd6
[root@gbase8c_private testapp]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
903990f7d923 tomcat-web:app2 "/apps/tomcat/bin/ru…" 50 seconds ago Up 49 seconds 8009/tcp, 0.0.0.0:8889->8080/tcp web2
5406ca7307ee tomcat-web:app1 "/apps/tomcat/bin/ru…" 56 seconds ago Up 55 seconds 8009/tcp, 0.0.0.0:8888->8080/tcp web1
[root@gbase8c_private testapp]# docker inspect -f "{{.State.Pid}}" 5406ca7307ee
30824
[root@gbase8c_private testapp]# nsenter -t 30824 -m -u -i -n -p
[root@5406ca7307ee /]# cat /apps/tomcat/webapps/testapp/index.html
Test App Page
[root@5406ca7307ee /]# echo "docker" >> /apps/tomcat/webapps/testapp/index.html
[root@5406ca7307ee /]# cat /apps/tomcat/webapps/testapp/index.html
Test App Page
docker
[root@5406ca7307ee /]# logout
[root@gbase8c_private testapp]# docker inspect -f "{{.State.Pid}}" 903990f7d923
30996
[root@gbase8c_private testapp]# nsenter -t 30996 -m -u -i -n -p
[root@903990f7d923 /]# cat /apps/tomcat/webapps/testapp/index.html
Test App Page
docker
[root@903990f7d923 /]# echo "docker" >> /apps/tomcat/webapps/testapp/index.html
-bash: /apps/tomcat/webapps/testapp/index.html: Read-only file system
#只读
#宿主机验证
[root@gbase8c_private testapp]# cat /usr/local/testapp/index.html
Test App Page
docker
http://192.168.56.199:8888/testapp/
日志:
echo "111" >> /usr/local/testapp/index.html
web界面访问验证
创建容器的时候指定参数-v,可以删除/var/lib/docker/containers/的容器数据目录,但是不会删除数据卷的内容。
删除所有容器之后,容器的数据目录被删除但是数据卷还在,所以数据卷数据是可以持久保存的。
日志:
[root@gbase8c_private testapp]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
903990f7d923 tomcat-web:app2 "/apps/tomcat/bin/ru…" 11 minutes ago Up 11 minutes 8009/tcp, 0.0.0.0:8889->8080/tcp web2
5406ca7307ee tomcat-web:app1 "/apps/tomcat/bin/ru…" 11 minutes ago Up 11 minutes 8009/tcp, 0.0.0.0:8888->8080/tcp web1
[root@gbase8c_private testapp]# docker rm -f -v 5406ca7307ee
5406ca7307ee
[root@gbase8c_private testapp]# docker rm -f -v 903990f7d923
903990f7d923
[root@gbase8c_private testapp]# ll /var/lib/docker/containers/
总用量 0
[root@gbase8c_private testapp]# cat /usr/local/testapp/index.html
Test App Page
docker
111
文件挂载用于很少更改文件内容的场景,比如nginx的配置文件、tomcat的配置文件等。
vim /usr/local/testapp/catalina.sh
[root@gbase8c_private testapp]# cat catalina.sh | grep JAVA_OPTS
#自定义JAVA选项
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -XX:CMSInitiatingOccupancyFraction=65 -XX:+UseFastAccessorMethods -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewSize=2048M -XX:MaxNewSize=2048M -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
docker run -d --name web1 -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -p8811:8080 tomcat-web:app1
日志:
[root@gbase8c_private testapp]# docker inspect -f "{{.State.Pid}}" b62074be97a9
24222
[root@gbase8c_private testapp]# docker inspect -f {{.State.Pid}} b62074be97a9
24222
[root@gbase8c_private testapp]# nsenter -t 24222 -m -u -p -i -n
[root@b62074be97a9 /]# ps -ef | grep java
www 29 1 7 21:28 ? 00:00:06 /usr/local/jdk/jre/bin/java -Djava.util.logging.config.file=/apps/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xms4g -Xmx4g -Xss512k -Xmn1g -XX:CMSInitiatingOccupancyFraction=65 -XX:+UseFastAccessorMethods -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewSize=2048M -XX:MaxNewSize=2048M -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /apps/tomcat/bin/bootstrap.jar:/apps/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/apps/tomcat -Dcatalina.home=/apps/tomcat -Djava.io.tmpdir=/apps/tomcat/temp org.apache.catalina.startup.Bootstrap start
多个目录要位于不同的目录下
docker run -d --name web1 -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -v /usr/local/testapp:/apps/tomcat/webapps/testapp -p8811:8080 tomcat-web:app1
数据卷容器最大的功能是可以让数据在多个docker容器之间共享,即可以让B容器访问A容器的内润,而容器C也可以访问A容器的内容,即先要创建一个后台运行的容器作为Server,用于卷提供,这个卷可以为其他容器提供数据存储服务,其他使用此卷的容器作为clinet端。
先启动一个容器,并挂载宿主机的数据目录
docker run -d --name volume-docker -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -v /usr/local/testapp:/apps/tomcat/webapps/testapp -p8800:8080 tomcat-web:app1
docker run -d --name web1 -p8801:8080 --volumes-from volume-docker tomcat-web:app1
docker run -d --name web2 -p8802:8080 --volumes-from volume-docker tomcat-web:app2
读写权限依赖于源数据卷Server容器
docker stop volume-docker
docker run -d --name web3 -p8803:8080 --volumes-from volume-docker tomcat-web:app2
docker rm -fv volume-docker
docker run -d --name web4 -p8804:8080 --volumes-from volume-docker tomcat-web:app2
已经运行的容器不受影响
docker run -d --name volume-docker -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -v /usr/local/testapp:/apps/tomcat/webapps/testapp -p8800:8080 tomcat-web:app1
docker run -d --name web4 -p8804:8080 --volumes-from volume-docker tomcat-web:app2
[root@gbase8c_private testapp]# docker run -d --name volume-docker -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -v /usr/local/testapp:/apps/tomcat/webapps/testapp -p8800:8080 tomcat-web:app1
de700ac7ae15f1efb07e672750997f91a469b8b2e33cc166cf4ad38328e4a815
[root@gbase8c_private testapp]# docker run -d --name web1 -p8801:8080 --volumes-from volume-docker tomcat-web:app1
1490e4a6697d5978614ac6b8557ef39ace767270da5014043a81ee7cc44775c2
[root@gbase8c_private testapp]# docker run -d --name web2 -p8802:8080 --volumes-from volume-docker tomcat-web:app2
e925dd3ccc2c45e03940ee5fbc22c4f6cd5be27371bcb20cc005442ea132ce4e
[root@gbase8c_private testapp]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e925dd3ccc2c tomcat-web:app2 "/apps/tomcat/bin/ru…" 6 seconds ago Up 5 seconds 8009/tcp, 0.0.0.0:8802->8080/tcp web2
1490e4a6697d tomcat-web:app1 "/apps/tomcat/bin/ru…" 11 seconds ago Up 10 seconds 8009/tcp, 0.0.0.0:8801->8080/tcp web1
de700ac7ae15 tomcat-web:app1 "/apps/tomcat/bin/ru…" 15 seconds ago Up 14 seconds 8009/tcp, 0.0.0.0:8800->8080/tcp volume-docker
[root@gbase8c_private ~]# docker exec 1490e4a6697d bash
[root@gbase8c_private ~]# docker exec -it 1490e4a6697d bash
[root@1490e4a6697d /]# echo "#test" >> /apps/tomcat/webapps/testapp/index.html
[root@1490e4a6697d /]# echo "#test" >> /apps/tomcat/bin/catalina.sh
bash: /apps/tomcat/bin/catalina.sh: Read-only file system
[root@1490e4a6697d /]# exit
[root@gbase8c_private ~]# docker stop volume-docker
volume-docker
[root@gbase8c_private ~]# docker run -d --name web3 -p8803:8080 --volumes-from volume-docker tomcat-web:app2
5f0cb9bb4888fde6252d09c63d1eda34b9194a2fa68da04648b17334be96a207
[root@gbase8c_private ~]# docker rm -fv volume-docker
volume-docker
[root@gbase8c_private ~]# docker run -d --name web4 -p8804:8080 --volumes-from volume-docker tomcat-web:app2
docker: Error response from daemon: No such container: volume-docker.
See 'docker run --help'.
[root@gbase8c_private ~]# docker run -d --name volume-docker -v /usr/local/testapp/catalina.sh:/apps/tomcat/bin/catalina.sh:ro -v /usr/local/testapp:/apps/tomcat/webapps/testapp -p8800:8080 tomcat-web:app1
53c04a1406b994f96cd073465eee084e75153c45b65d9df73d4f2b9035282664
[root@gbase8c_private ~]# docker run -d --name web4 -p8804:8080 --volumes-from volume-docker tomcat-web:app2
cbe7367b77e3bc80b128e115fe7266601f0d819280594849fc17965034588edb