Docker镜像究竟是什么!!!

Docker镜像讲解

一、镜像是什么

镜像本质上是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基本运行环境开发的软件,它包含运算某个软件所需要的内容和环境,包括代码、运行时库、环境变量和配置文件等。

所有的应用,直接打包docker镜像就可以直接跑起来

如何得到镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作镜像 —>DockerFile

二、Docker镜像加载原理

UnionFS(联合文件系统)

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持文件系统的修改作为一次提交一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Docker镜像的基础。镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体应用。

特性:一次同时加载多个问价那系统,但从外表看起来,只能看到一个文件系统,联合加载会吧各层文件系统叠加起来,这样最终的文件系统包括所有底层的文件和目录

我们pull镜像时看到的一层一层的就是这个!!!

Docker镜像加载原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z1sGUU6m-1592743841273)(/Users/wangxuehui/Library/Application Support/typora-user-images/image-20200621042616596.png)]

三、分层的理解

查看一个ES的Images的分层

docker inspect [容器ID/容器名称]  我这里查看的是我的ES 镜像
 "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:77b174a6a187b610e4699546bd973a8d1e77663796e3724318a2a4b24cb07ea0",
                "sha256:7712f32688d1bef330aa3b4fac2683cec1d7339335ce403483b329423debffb6",
                "sha256:1a090720e70c88e61053c89d3ff01932943b198644f4a7e86426e576b721d2e3",
                "sha256:0535424758bd9ab49a3d03af52a9fa5447b807198fadc35e9f80123a0929402e",
                "sha256:4d2f8f4a58623431cca0ee321bbee273b87070f9e381b3147e4293e83dc146d7",
                "sha256:77c5267605c2c7cf2426242d5df50af78931e66403e9d0d06f2b9fd7adc3adc9",
                "sha256:537370aeea86be07f79bbcd25464a1df23f347bb5313e0ff7ca15d6aad70e074"
            ]
        }
# 我们可以清楚的看到 ES 的镜像其实是分很多层的

理解

所有的Docker 镜像都是起始于一个基础的镜像,当进行修改或者增加新的内容的时候,就会创建新的镜像成。 举一个简单的例子,加入CentOS 创建了一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python 包,就会在基础镜像上创建第二个镜像层;如果继续添加一个安全补丁,就会去常见第三层镜像

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-spSeqgj3-1592743841285)(/Users/wangxuehui/Library/Application Support/typora-user-images/image-20200621121957557.png)]

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!!

这一层就是我们常说的容器层,容器之下的都叫镜像层!

举例: 当我们pull下来一个tomcat镜像时,我们通过镜像启动了tomcat 容器 那么我们其实操作的并不是tomcat这个镜像本身 在我们将tomcat镜像启动为一个容器的时候,会在镜像层的上方新增一个容器层, 其实在文件分层的概念上来说 tomcat镜像本身是镜像层,是只读的 我们的操作都在镜像层上的容器层进行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vSEQbNA-1592743841294)(/Users/wangxuehui/Library/Application Support/typora-user-images/image-20200621123303367.png)]

四、commit镜像

docker commit					#提交一个容器称为新的木本
docker commit -m="提交的描述信息" -a="作者" 容器ID  目标镜像名:[TAG]
#举例   启动一个tomcat
[root@iZhp3do4qhzu84445osa3sZ ~]# docker run -it  -p:17501:8080 2eb5a120304e
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/openjdk-11
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
## 省略tomcat的启动日志
## 查看刚才启动的tomcat 第一个
[root@iZhp3do4qhzu84445osa3sZ ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                            NAMES
95cfb21f2c7c        2eb5a120304e          "catalina.sh run"        41 seconds ago      Up 38 seconds       8080/tcp                                         condescending_wilson
d27977b9712c        portainer/portainer   "/portainer"             8 hours ago         Up 8 hours          0.0.0.0:8088->9000/tcp                           condescending_cori
272b65fe3867        elasticsearch:7.6.2   "/usr/local/bin/do..."   9 hours ago         Up 9 hours          0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es01
afbd9cc1bd41        docker.io/tomcat      "catalina.sh run"        9 hours ago         Up 9 hours          0.0.0.0:17500->8080/tcp                          tomcat01
48abd2f7180a        docker.io/nginx       "/docker-entrypoin..."   10 hours ago        Up 10 hours         0.0.0.0:17200->80/tcp                            nginx01

# 新建一个窗口,已交互的方式进入tomcat容器
## docker exec -it 95cfb21f2c7c /bin/bash
[root@iZhp3do4qhzu84445osa3sZ ~]# docker exec -it 95cfb21f2c7c /bin/bash
root@95cfb21f2c7c:/usr/local/tomcat# 
## 和上次遇到的问题一样 我们需要将webapps.dist中的文件拷贝到webapps中
root@95cfb21f2c7c:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work        
root@95cfb21f2c7c:/usr/local/tomcat# cp webapps.dist/** -r webapps
root@95cfb21f2c7c:/usr/local/tomcat# cd webapps
root@95cfb21f2c7c:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
root@95cfb21f2c7c:/usr/local/tomcat/webapps# 
# exit 
# curl localhost:17501 测试

# 提交镜像  #原本的tomcat是阉割版本的 我们要复制文件到webapps  那么我们复制完文件之后 制作一个自己的镜像就可以了  后面我们就可以使用自己镜像了
# 1. docker ps
[root@iZhp3do4qhzu84445osa3sZ ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                            NAMES
d27977b9712c        portainer/portainer   "/portainer"             9 hours ago         Up 9 hours          0.0.0.0:8088->9000/tcp                           condescending_cori
272b65fe3867        elasticsearch:7.6.2   "/usr/local/bin/do..."   9 hours ago         Up 9 hours          0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es01
afbd9cc1bd41        docker.io/tomcat      "catalina.sh run"        10 hours ago        Up 10 hours         0.0.0.0:17500->8080/tcp                          tomcat01
48abd2f7180a        docker.io/nginx       "/docker-entrypoin..."   11 hours ago        Up 10 hours         0.0.0.0:17200->80/tcp                            nginx01

# 2. 提交镜像
[root@iZhp3do4qhzu84445osa3sZ ~]# docker commit -m="黑知白首的Tomcat镜像" -a="hzbs" afbd9cc1bd41 hzbstomcat:0.0.1
sha256:b3feb81b41264f3760ce9b4fdbe4bdb036326beabceec5891eb3b3ec19dff563

# 3. 查看提交的镜像
[root@iZhp3do4qhzu84445osa3sZ ~]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
hzbstomcat                      0.0.1               b3feb81b4126        14 seconds ago      652 MB

学习方式说明: 理解概念,但一定给要实践,最后实践和理论相结合一次搞定这个知识

如果想保存当前镜像中自己新增的内容,就可以通过commit的方式提交 后面自己使用

到了这里才算是入门了Docker!!!!

后面的内容才是精髓

五、容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像

2.5.1 什么是容器数据卷

我们的项目都会保存一些数据img,所以我们的数据是不会存到容器内的 ,因为一旦容器被删除那么数据也就删除了

需求:数据可以做持久化!!

例如MYSQL ,容器删了 那就相当于是删库跑路了 所以我们的需求就是将mysql的数据保存到本地

容器之间可以有一个数据共享的技术!Docker 容器中产生的数据,同步到本地!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jeeBylbr-1592743841298)(/Users/wangxuehui/Library/Application Support/typora-user-images/image-20200621143531737.png)]

总结:容器中数据的持久化和同步操作!容器之间也是可以数据共享的

2.5.2 使用数据卷

方式一:直接使用命令来进行挂载 -v

docker run -v  # 在启动容器时进行数据挂载
# 完整的启动命令 
docker run -v [宿主机目录]:[容器目录] -p [宿主机端口]:[容器端口] -d --name yourname [镜像名称/镜像ID]
# 启动一个centos镜像 并且进入
[root@iZhp3do4qhzu84445osa3sZ home]# docker run -it -v /home/ceshi:/home 831691599b88 /bin/bash
# 此时 容器内的/home 目录已经和 宿主机的/home/ceshi目录同步
# 测试是否同步  测试:
# 容器内部的/home目录是空的       								
																								[root@d3b957a011a4 home]# ls   
																								[root@d3b957a011a4 home]# 
																
# 此时我们看一下宿主机的/home/ceshi目录也是空的		
																								[root@iZhp3do4qhzu84445osa3sZ /]# cd /home/ceshi/
                                								[root@iZhp3do4qhzu84445osa3sZ ceshi]# ls
                                								[root@iZhp3do4qhzu84445osa3sZ ceshi]# 
# 在容器的/home目录下创建一个test.java文件
[root@d3b957a011a4 home]# touch test.java
[root@d3b957a011a4 home]# ls
test.java
[root@d3b957a011a4 home]# 

# 再次查看宿主机的/home/ceshi 目录下是否有test.java这个文件
[root@iZhp3do4qhzu84445osa3sZ ceshi]# ls
test.java
[root@iZhp3do4qhzu84445osa3sZ ceshi]#   
# 我们清楚的发现在宿主机的/home/ceshi目录下多了一个test.java文件 这时就可以证明数据实现了同步

# docker inspect d3b957a011a4   查看一下容器的信息
"Mounts": [
            {
                "Type": "bind",   				# 绑定的类型
                "Source": "/home/ceshi", 	# 宿主机的文件路径
                "Destination": "/home",		# 容器内的文件路径
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
# 我们也可以发现 数据卷已经进行了挂载 这时就可以证明数据实现了同步(类似于VUE的双向绑定)

问题:当我们的容器停止了之后那数据数据会不会同步呢?

# 1. 退出容器
[root@d3b957a011a4 home]# exit
exit
[root@iZhp3do4qhzu84445osa3sZ home]# 
# 2. 在宿主机的/home/ceshi/目录下新建test2.java   注意: 此时容器已经停止了
[root@iZhp3do4qhzu84445osa3sZ home]# cd /home/ceshi/
[root@iZhp3do4qhzu84445osa3sZ ceshi]# ls
test.java
[root@iZhp3do4qhzu84445osa3sZ ceshi]# touch test2.java
[root@iZhp3do4qhzu84445osa3sZ ceshi]# ls
test2.java  test.java
[root@iZhp3do4qhzu84445osa3sZ ceshi]# 

# docker exec -it d3b957a011a4 /bin/bash 进入容器
[root@iZhp3do4qhzu84445osa3sZ ceshi]# docker exec -it d3b957a011a4 /bin/bash
[root@d3b957a011a4 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@d3b957a011a4 /]# cd /home/
[root@d3b957a011a4 home]# ls
test.java  test2.java
[root@d3b957a011a4 home]# 

# 此时我们发现在容器停止后 还是可以进行数据的挂载的

2.5.3 安装mysql挂载

思考:Mysql的数据持久化问题 /data

# 1. 获取镜像
docker pull mysql
# 2. 启动mysql时 将数据挂载到宿主机上 安装mysql时要配置密码的
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=[your password] --name mysql01 docker.io/mysql
# 参数讲解
-d										#后台运行
-p										#端口映射
-v										#挂载卷   -v[宿主机DIR]:[容器的DIR]
-e										#配置密码
--name								#起别名



# 这里我踩到的坑:使用Navicat12 去连接时报错错误信息如下
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded
# 原因是mysql8.0之后做了一个密码加密方式的改变 这时我们需要进入容器
docker exec -it [容器名称] /bin/bash   
mysql -uroot -p
# 输入你上面设置的密码 进入到mysql操作界面
root@91a6188295ba:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.20 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 然后改变密码的加密方式
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your password';
Query OK, 0 rows affected (0.00 sec)
# 这时我们在使用Navicat进行连接就可以了


# 查看宿主机的地址/home/mysql中是否有文件
[root@iZhp3do4qhzu84445osa3sZ ~]# cd /home/
[root@iZhp3do4qhzu84445osa3sZ home]# ls
admin.password  ceshi  mysql  nexus  nexus-data  www
[root@iZhp3do4qhzu84445osa3sZ home]# cd mysql/
[root@iZhp3do4qhzu84445osa3sZ mysql]# ls
conf  data
[root@iZhp3do4qhzu84445osa3sZ mysql]# cd data/
[root@iZhp3do4qhzu84445osa3sZ data]# ls
auto.cnf       binlog.index     client-key.pem     ibdata1      #innodb_temp        private_key.pem  sys
binlog.000001  ca-key.pem       #ib_16384_0.dblwr  ib_logfile0  mysql               public_key.pem   undo_001
binlog.000002  ca.pem           #ib_16384_1.dblwr  ib_logfile1  mysql.ibd           server-cert.pem  undo_002
binlog.000003  client-cert.pem  ib_buffer_pool     ibtmp1       performance_schema  server-key.pem
[root@iZhp3do4qhzu84445osa3sZ data]# 

# 使用Navica创建一个test数据库 再次查看
[root@iZhp3do4qhzu84445osa3sZ data]# ls
auto.cnf       binlog.index     client-key.pem     ibdata1      #innodb_temp        private_key.pem  sys
binlog.000001  ca-key.pem       #ib_16384_0.dblwr  ib_logfile0  mysql               public_key.pem   test
binlog.000002  ca.pem           #ib_16384_1.dblwr  ib_logfile1  mysql.ibd           server-cert.pem  undo_001
binlog.000003  client-cert.pem  ib_buffer_pool     ibtmp1       performance_schema  server-key.pem   undo_002
[root@iZhp3do4qhzu84445osa3sZ data]# 

#会发现再次ls 多出来一个test的数据库,这是就可以说明 mysql01 容器的数据 和宿主机的数据是共享的 数据卷起作用了

这时 我们就可以保证即时这个mysql01容器被删除了 我们的数据库数据也不会丢失

2.5.4 具名/匿名挂载

#### 匿名挂载 
-v 容器内路径!
docker rin -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的数据卷   在-v的时候我们只写了容器内的路径并没有写容器外的路径
[root@iZhp3do4qhzu84445osa3sZ data]# docker volume ls
DRIVER              VOLUME NAME
local               1cecc9f117feb5014d30b74b2cd2c7417c5de6aac7e635606346fad2883dbc30 
local               306f1a8a8b0a071d069ad4e435540438617ddb98182b993c010f92420ca1ac0d
local               4d484ee3a5ae92318609101b1d8a5f1ec3080e40a72d4810bc805fbc84756549
local               4e79c29279c22b0dac4f11410f4355882ae0b92e2e6e2665f6f03e44a41b6db2
local               73d356d3f0fbd17ef4674a6f8892353ac67eecf81622a540c3482e9160772c28
local               81a4b4fec1a3ac462e6e733880a95751cc504f6fa2d6ae3b88fa4411cbc66213
local               88160f87c138e6274af2057130614d33afeb07fac3f1536c4f6e3d130d854631
local               9006bd5676585d0e9e750b30d8dd250f95f31f66b5956b3b55f103ae676d4404
local               c5add424515e1d394996a1687db79d63023097875765f823741bde048ce3d84a
# DRIVER  本地
# VOLUME NAME 容器的ID(完整的ID)

####  具体名挂载 (多数使用,不建议匿名挂载)
[root@iZhp3do4qhzu84445osa3sZ ceshi]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx 2622e6cca7eb
f6f4d910103da106baa1d7347dabfd07d77f7805c629f40b15444045c4e66944

#再次查看所有的数据卷 
[root@iZhp3do4qhzu84445osa3sZ ceshi]# docker volume ls
DRIVER              VOLUME NAME
local               1cecc9f117feb5014d30b74b2cd2c7417c5de6aac7e635606346fad2883dbc30
local               306f1a8a8b0a071d069ad4e435540438617ddb98182b993c010f92420ca1ac0d
local               4d484ee3a5ae92318609101b1d8a5f1ec3080e40a72d4810bc805fbc84756549
local               4e79c29279c22b0dac4f11410f4355882ae0b92e2e6e2665f6f03e44a41b6db2
local               73d356d3f0fbd17ef4674a6f8892353ac67eecf81622a540c3482e9160772c28
local               81a4b4fec1a3ac462e6e733880a95751cc504f6fa2d6ae3b88fa4411cbc66213
local               88160f87c138e6274af2057130614d33afeb07fac3f1536c4f6e3d130d854631
local               9006bd5676585d0e9e750b30d8dd250f95f31f66b5956b3b55f103ae676d4404
local               c5add424515e1d394996a1687db79d63023097875765f823741bde048ce3d84a
local               juming-nginx
# 我们可以发现他是有名称的
# 查看卷的信息  docker volume inspect juming-nginx
[root@iZhp3do4qhzu84445osa3sZ ceshi]# docker volume inspect juming-nginx
[
    {
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",   #我们挂载到宿主机的目录
        "Name": "juming-nginx",
        "Options": {},
        "Scope": "local"
    }
]
# 查看juming-nginx挂载到宿主机上的地址
[root@iZhp3do4qhzu84445osa3sZ ceshi]# cd /var/lib/docker/volumes/juming-nginx/_data
[root@iZhp3do4qhzu84445osa3sZ _data]# ls
conf.d  fastcgi_params  koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params  uwsgi_params  win-utf

所有docker容器内的卷 在没有指定目录的情况加都存在 /var/lib/docker/volumes/juming-nginx/_data

/var/lib/docker/volumes/juming-nginx/_data
/var/lib/docker/volumes/卷名/_data

扩展:

#ro   readonly		只读  只能在宿主机来操作,容器内幕是无法操作的
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro 2622e6cca7eb
#rw		readwrite		读写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw 2622e6cca7eb

DockerFile 就是迎来构建docker镜像的构建文件!命令脚本

2.6.5 初识DockerFile

# 1. 创建一个自定义的docker镜像存放目录
[root@iZhp3do4qhzu84445osa3sZ ~]# cd /home/
[root@iZhp3do4qhzu84445osa3sZ home]# ls
admin.password  ceshi  mysql  nexus  nexus-data  www
[root@iZhp3do4qhzu84445osa3sZ home]# mkdir docker-test-volume
[root@iZhp3do4qhzu84445osa3sZ home]# ls
admin.password  ceshi  docker-test-volume  mysql  nexus  nexus-data  www

# 进入docker-test-volume目录创一个dockerfile01的文件
vim dockerfile01

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash
:wq #保存退出

#查看我们编写的dockerfile
[root@iZhp3do4qhzu84445osa3sZ docker-test-volume]# cat dockerfile01 
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

# 创建镜像
# docker build -f dockerfile01 -t hzbs/centos .
[root@iZhp3do4qhzu84445osa3sZ docker-test-volume]# docker build -f dockerfile01 -t hzbs/centos .
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM centos
 ---> 831691599b88  # 一个基础的镜像
Step 2/4 : VOLUME volume01 volume02   #挂载
 ---> Running in dad9b0d159b0
 ---> 317cd5e7c102
Removing intermediate container dad9b0d159b0
Step 3/4 : CMD echo "----end----"  #打印了我们的命令
 ---> Running in 48ff5dcfd40a
 ---> 26193b4bdb92
Removing intermediate container 48ff5dcfd40a
Step 4/4 : CMD /bin/bash
 ---> Running in 5e44f6aec261
 ---> 4baac1de9c3b  #进入到我们的bin/bash
Removing intermediate container 5e44f6aec261
Successfully built 4baac1de9c3b
# 查看镜像
[root@iZhp3do4qhzu84445osa3sZ docker-test-volume]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
hzbs/centos                     latest              4baac1de9c3b        3 minutes ago       215 MB
docker.io/rabbitmq              latest              7e50c60f7e3e        4 days ago          156 MB
docker.io/centos                latest              831691599b88        4 days ago          215 MB
docker.io/redis                 latest              235592615444        11 days ago         104 MB
docker.io/nginx                 latest              2622e6cca7eb        11 days ago         132 MB
docker.io/mysql                 latest              be0dbf01a0f3        12 days ago         541 MB
docker.io/sonatype/nexus3       latest              e56a3b1f769b        12 days ago         630 MB
docker.io/portainer/portainer   latest              cd645f5a4769        2 weeks ago         79.1 MB
docker.io/elasticsearch         7.6.2               f29a1ee41030        2 months ago        791 MB
# 可以看到我们刚才生成的镜像在第一行

# 启动一下自己写的容器
[root@iZhp3do4qhzu84445osa3sZ docker-test-volume]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
hzbs/centos                     latest              4baac1de9c3b        6 minutes ago       215 MB
docker.io/rabbitmq              latest              7e50c60f7e3e        4 days ago          156 MB
docker.io/centos                latest              831691599b88        4 days ago          215 MB
docker.io/redis                 latest              235592615444        11 days ago         104 MB
docker.io/nginx                 latest              2622e6cca7eb        11 days ago         132 MB
docker.io/mysql                 latest              be0dbf01a0f3        12 days ago         541 MB
docker.io/sonatype/nexus3       latest              e56a3b1f769b        12 days ago         630 MB
docker.io/portainer/portainer   latest              cd645f5a4769        2 weeks ago         79.1 MB
docker.io/elasticsearch         7.6.2               f29a1ee41030        2 months ago        791 MB
[root@iZhp3do4qhzu84445osa3sZ docker-test-volume]# docker run -it 4baac1de9c3b /bin/bash
[root@2b8800ad70b0 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02
# 我们发现我们刚才自己写的两个目录在容器中生成了
# volume01 volume02 这两个目录就是我们生成镜像的时候自动挂载的,数据卷的目录
# 这两个卷一定和外部有一个同步的目录,这里打开另一个窗口在宿主机上查看该镜像的详细信息

[root@iZhp3do4qhzu84445osa3sZ ~]# docker inspect 15642f091df9

# 根据之前的逻辑我们要在Mounts中查看我们的数据卷
"Mounts": [
            {
                "Type": "volume",
                "Name": "8269ee28ede4ea417acd1fb94ed8153dd60abdf66b5ff560b94da3cd89b5ef06",
                "Source": "/var/lib/docker/volumes/8269ee28ede4ea417acd1fb94ed8153dd60abdf66b5ff560b94da3cd89b5ef06/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "df38c89e750a6d14256b1fadc6900c2b57ccecd8eb9fd95501f1affab6c1f946",
                "Source": "/var/lib/docker/volumes/df38c89e750a6d14256b1fadc6900c2b57ccecd8eb9fd95501f1affab6c1f946/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
# 这里的Source 就是宿主机上数据全挂载的目录
# 进入volume01 目录 新建一个hello-world.java 文件
[root@15642f091df9 volume01]# touch hello-world.java
[root@15642f091df9 volume01]# ls
hello-world.java

# 我们在宿主机上的目录查看一下刚才创建的hello-world.java是否挂载呆宿主机上
[root@iZhp3do4qhzu84445osa3sZ _data]# cd /var/lib/docker/volumes/8269ee28ede4ea417acd1fb94ed8153dd60abdf66b5ff560b94da3cd89b5ef06/_data
[root@iZhp3do4qhzu84445osa3sZ _data]# ls
hello-world.java

# 我们可以看到 我们刚才在容器内部touch的一个java文件已经挂载到了宿主机上

# 这样的方式在未来使用的十分多,因为我们会经常的构建自己的项目镜像
# 假设构件时没有挂在卷 那么这是我们就需要-v 来手动挂载到宿主机上

2.6.6 数据卷容器

多个容器共享数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5O7G9FwA-1592743841302)(/Users/wangxuehui/Library/Application Support/typora-user-images/image-20200621195048179.png)]

# 启动2个容器 通过我们自己写的镜像启动  因为都是-it 所以需要2个窗口 因为我mac系统command+q是默认快捷键所以 打击可以使用 ctrl +Q+p  再来一个宿主机窗口 
docker run -it --name centos01 4baac1de9c3b /bin/bash
docker run -it --name centos02 --volumes-from centos01 4baac1de9c3b /bin/bash
docker run -it --name centos03 --volumes-from centos01 4baac1de9c3b /bin/bash
# centos01 中的volume01 中创建一个文件
[root@35730f23b852 volume01]# touch docker01.java
[root@35730f23b852 volume01]# ls
docker01.java

# 查看centos02中的volume01是否存在文件
[root@498c5470e36b /]# cd volume01/
[root@498c5470e36b volume01]# ls
docker01.java

# 查看centos03中的volume01是否存在文件
[root@f422d36d5d98 /]# cd volume01/
[root@f422d36d5d98 volume01]# ls
docker01.java

# 我们发现在 centos02   centos03 中都存在docker01.java 说明centos01作为父容器 被centos02  centos03 挂载
#	这时 centos01 centos02 centos03 这三个容器的数据是同步的 当删除其中的一个容器时 剩余的两个容器的数据不发生	改变 即是是父容器被删除   那么这个作用就是起到了一个数据备份的作用

思考:当我们删除其中一个容器时 数据不会被删除 但是当我们在其中的一个容器中吧数据卷删除后其他的容器的数据卷还会有内容么

答:不会有内容,所以这是我们可以做容器映射到宿主机的操作 并且是readonly的,不回去操作容器内部的数据 而是通过宿主机去操作容器的文件

这里可以实现的功能就是mysql集群和redis集群的数据一致性问题

这里我们可以启动两个mysql容器 让他们的数据卷都挂载到宿主机的数据卷 这样可以实现mysql的数据一致性问题 间接的实现mysql集群的功能

六、DockerFile

七、Dcoker 网络

GitHub: 所有笔记

猜你喜欢

转载自blog.csdn.net/qq_39381775/article/details/106890940