docker commit镜像以及数据卷技术
commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git类似
docker commit -m='提交的描述信息' -a='作者' 容器id 目标镜像名:[tag]
实战测试
# 启动一个默认的tomcat
# 发现这个tomcat没有webapps应用,镜像原因,官方的镜像默认webapps下面是没有文件的
# 自己将webapps.dist中的文件拷贝到webapps中
# 拷贝指令:root@a81a26e1b2d3:/usr/local/tomcat# cp -r webapps.dist//* webapps
# 将我们操作过的镜像通过commit提交为一个镜像。我们后面可以直接使用该镜像。
[root@instance-suip20a5 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a81a26e1b2d3 tomcat "catalina.sh run" 8 minutes ago Up 8 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp amazing_black
70591f01912e portainer/portainer "/portainer" 7 hours ago Up 7 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp angry_khorana
[root@instance-suip20a5 ~]# docker commit -a='wk' -m='add webapps app' a81a26e1b2d3 tomcat02:10
sha256:7039d062e4664b825ad395496bb7043efe42bb0c27d3d96b583e7a24f4704167
[root@instance-suip20a5 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 10 7039d062e466 17 seconds ago 684MB
tomcat latest fb5657adc892 6 months ago 680MB
redis latest 7614ae9453d1 6 months ago 113MB
centos latest 5d0da3dc9764 9 months ago 231MB
portainer/portainer latest 580c0e4e98b0 15 months ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 2 years ago 791MB
总结:如果需要保存当前容器的状态,就可以通过commit提交,获得一个镜像。类似于快照。
容器数据卷
什么是容器数据卷
服务产生相关数,如果数据都在容器中,我们删除容器,数据就会丢失。需求:数据可以持久化
容器之间可以有一个数据共享的技术。Docker容器中产生的数据,同步到本地!
这就是卷技术,也就是目录的挂载,将我们容器内的目录挂载到Linux上面,从而可以让数据存在本地,删除容器不会影响数据。
总结一句话:容器的持久化和同步操作,容器间也是可以数据共享的。
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
[root@instance-suip20a5 ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@cd5f3e13719a /]# cd /home
[root@cd5f3e13719a home]# ls
[root@cd5f3e13719a home]# exit
exit
[root@instance-suip20a5 ~]# cd /home
[root@instance-suip20a5 home]# ls
ceshi
[root@instance-suip20a5 home]# docker ps
测试数据的同步
# 在centos容器的home目录下创建一个test.java文件
[root@de3a61b8542d /]# cd /home
[root@de3a61b8542d home]# ls
[root@de3a61b8542d home]# touch test.java
[root@de3a61b8542d home]# ls
test.java
# 查看主机home/ceshi目录下也有相对应的文件
[root@instance-suip20a5 home]# ls
ceshi
[root@instance-suip20a5 home]# cd ceshi/
[root@instance-suip20a5 ceshi]# ls
test.java
测试修改主机文件是否会同步到容器内
# 1、停掉centos容器
[root@de3a61b8542d home]# exit
exit
# 2、修改主机home/ceshi目录下test.java文件
[root@instance-suip20a5 ceshi]# ls
test.java
[root@instance-suip20a5 ceshi]# vim test.java
# 3、启动centos容器,查看文件内容是否同步
[root@instance-suip20a5 home]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@464f7172747b /]# cd /home
[root@464f7172747b home]# ls
test.java
[root@464f7172747b home]# cat test.java
hello,linux update
总结:好处就是通过这种挂载方式以后只需要修改主机本地文件即可,容器内会自动同步。
实战数据同步:安装MySQL
# 1、获取镜像
[root@instance-suip20a5 ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Pull complete
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 运行容器,需要做数据挂载 #安装启动mysql,需要配置密码。
# dockerhub官方测试命令:$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动mysql
[root@instance-suip20a5 ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
e3247eb4908146be98d537db769f9e9ab06318d3ffa2151c8e3a8ed41b15bf6d
[root@instance-suip20a5 ~]#
具名挂载和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /ect/nginx nginx
[root@instance-suip20a5 ~]# docker run -d -P --name nginx01 -v /ect/nginx nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
6afa806de6afb13c69691ee4d21f532c29372bc934b78505098738dafd4a9c23
# 查看所有卷的情况
[root@instance-suip20a5 ~]# docker volume ls
DRIVER VOLUME NAME
local 0d8b6e58296dced29be873be709063f4fb54aa16be87ceb1697d9124ee6e7eec
local 82884d4b95863771ebe3af485ed51e9480b5db11584077a985064ad1527d11ab
[root@instance-suip20a5 ~]#
# 这里发现卷是一串不规则字符串,这就是匿名挂载,我们只写了容器内路径,没有写容器外路径。
# 具名挂载
[root@instance-suip20a5 ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
86a0be51270214d21b943bec8025b27c99508d241a98454b99a97fef3f8e0917
[root@instance-suip20a5 ~]# docker volume ls
DRIVER VOLUME NAME
local 0d8b6e58296dced29be873be709063f4fb54aa16be87ceb1697d9124ee6e7eec
local 82884d4b95863771ebe3af485ed51e9480b5db11584077a985064ad1527d11ab
local juming-nginx
[root@instance-suip20a5 ~]#
# 通过 -v 卷名:容器内路径
#查看一下这个具名挂载卷
[root@instance-suip20a5 ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-07-10T11:56:08+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
[root@instance-suip20a5 ~]#
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes
我们通过具名挂载可以方便找到我们的卷,大多数情况下都是使用具名挂载。
如何分别具名挂载和匿名挂载:
# 如何确定是具名挂载和匿名挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #具名挂载
拓展:
# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
# 一旦设置了这个权限,容器对我们挂载出来的内容就有权限限制
docker run -d -P --name nginx02 juming-nginx:/etx/nginx:ro nginx
docker run -d -P --name nginx02 juming-nginx:/etx/nginx:rw nginx
# ro 设置了ro权限就说明这个路径只能通过宿主机来操作,容器没有写入权限。
初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件。
通过这个脚本可以生成镜像,镜像是一层一层的,脚本的一个个命令,每个命令都是一层。
# 创建一个dockerfile,名字可以任意命令
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "----end-----"
CMD /bin/bash
# 这里每个命令就是一层
[root@instance-suip20a5 home]# mkdir docker-test-volume
[root@instance-suip20a5 home]# ls
ceshi docker-test-volume mysql
[root@instance-suip20a5 home]# pwd
/home
[root@instance-suip20a5 home]# cd docker-test-volume/
[root@instance-suip20a5 docker-test-volume]# pwd
/home/docker-test-volume
[root@instance-suip20a5 docker-test-volume]# vim dockerfile
[root@instance-suip20a5 docker-test-volume]# ls
dockerfile
[root@instance-suip20a5 docker-test-volume]# docker build -f dockerfile -t wkcentos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
^H^H^H^Hlatest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01, "volume02"]
failed to process "[\"volume01,": unexpected end of statement while looking for matching double-quote
[root@instance-suip20a5 docker-test-volume]#
[root@instance-suip20a5 docker-test-volume]# ls
dockerfile
[root@instance-suip20a5 docker-test-volume]# vi dockerfile
[root@instance-suip20a5 docker-test-volume]# docker build -f dockerfile -t wk/centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01", "volume02"]
---> Running in d2826f73d11a
Removing intermediate container d2826f73d11a
---> bc1ba59bee3c
Step 3/4 : CMD echo "----end-----"
---> Running in 48d706202103
Removing intermediate container 48d706202103
---> b63312b7ba09
Step 4/4 : CMD /bin/bash
---> Running in 67c9b32c7cea
Removing intermediate container 67c9b32c7cea
---> 75479a3a5461
Successfully built 75479a3a5461
Successfully tagged wk/centos:1.0
[root@instance-suip20a5 docker-test-volume]# ls
dockerfile
[root@instance-suip20a5 docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wk/centos 1.0 75479a3a5461 34 seconds ago 231MB
nginx latest 605c77e624dd 6 months ago 141MB
centos latest 5d0da3dc9764 9 months ago 231MB
[root@instance-suip20a5 docker-test-volume]#
启动自己的容器:
数据卷容器
多个mysql同步数据
# 启动三个容器,通过自己刚才创建的镜像
[root@instance-suip20a5 docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wk/centos 1.0 75479a3a5461 2 hours ago 231MB
nginx latest 605c77e624dd 6 months ago 141MB
centos latest 5d0da3dc9764 9 months ago 231MB
[root@instance-suip20a5 docker-test-volume]# docker run -it --name docker01 75479a3a5461
[root@132e581f0fe6 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@132e581f0fe6 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jul 10 08:41 dev
drwxr-xr-x 1 root root 4096 Jul 10 08:41 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 185 root root 0 Jul 10 08:41 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jul 10 08:41 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Jul 10 08:41 volume01
drwxr-xr-x 2 root root 4096 Jul 10 08:41 volume02
# 容器间的数据共享指令 --volumes-from 目标容器名
[root@instance-suip20a5 ~]# docker run -it --name docker02 --volumes-from docker01 75479a3a5461
# 删除docker01之后,docker02、docker03依然还是可以保存这个文件,docker容器之间的数据共享是拷贝型数据。
结论:容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。但是一旦持久化到了本地,这个时候本地的数据不会删除。