四、Docker镜像讲解

四、Docker镜像讲解

一、镜像是什么

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

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

如何得到镜像:

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

二、Docker镜像加载原理

UnionFS(联合文件系统)

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

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

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

Docker镜像加载原理

四、Docker镜像讲解_第1张图片

三、分层的理解

查看一个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 包,就会在基础镜像上创建第二个镜像层;如果继续添加一个安全补丁,就会去常见第三层镜像

四、Docker镜像讲解_第2张图片

特点

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

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

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

四、Docker镜像讲解_第3张图片

四、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 容器中产生的数据,同步到本地!

四、Docker镜像讲解_第4张图片

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

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.5.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.5.6 数据卷容器

多个容器共享数据

四、Docker镜像讲解_第5张图片

# 启动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

2.6.1 DcockerFile的介绍

DockerFile是用来构建docker镜像的文件!命令参数脚本

构建的步骤:

  1. 编写y一个dockerfile 文件
  2. docker build 构建称为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云镜像)
# 我们查看一下官方的centos7的dockerfile
FROM scratch   # 最底层的镜像 百分之九十的镜像的最底层都是它
ADD centos-7-x86_64-docker.tar.xz /

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20200504" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-05-04 00:00:00+01:00"

CMD ["/bin/bash"]

# 我们发现官方的镜像都是纯净的包 都是基础包  很多基础的功能都没有 通常会搭建自己的镜像

官方既然能够制作镜像 ,那么我们也可以构建镜像!!!!

2.6.2 DockerFile基础知识

  1. 每个保留关键字(指令) 都必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交

dokcerFile是面向开发的,作进行共享,就需要编写dockerfile文件,这个文件非常的简单

Dcoker 已经逐渐成为了企业交付的标准! 很重要!

  • 三部曲
    • DockerFile: 通过DockerFile构建文件,定义了一切步骤,源代码
    • DockerImages: 通过DockerFile构建生成的镜像,最终发布和运行的产品,原来是jar、war
    • Docker容器:容器就是镜像运行起来提供服务的!

2.6.3 DockerFile的指令

指令 作用 描述
FROM 基础镜像 一切从这里开始构建
MAINTAINER 作者信息 国际通用格式:姓名+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 添加内容 举例:添加tomcat
WORKDIR 工作目录 当前镜像的工作目录
VOLUME 容器卷挂载的目录
EXPOSE 指定暴露的端口 这里暴露端口就不需要-p了
CMD 指定这个容器启动时要运行的命令
ENTRYPOINT 指定这个容器启动时要运行的命令 只有最后的才会生效,可以追加命令
ONBUILD 触发指令 当构建一个被继承的DockerFile时,就会运行ONBUILD指令
COPY 拷贝 类似于ADD将文件拷贝到镜像中
ENV 构建的时候设置设置环境变量

2.6.4 实战测试

# 创建一个自己的centos镜像

# 1. 编写DockerFile文件
cd /home   #进入宿主机的 /home命令
vim mydockerfile

FROM centos
MAINTAINER hzbs<[email protected]>

ENV MYPATH /user/local
WORKDIR $MYPATH

RUN yum -y install vim 
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
:wq  #退出

# 2. 通过这个文件构建镜像
[root@iZhp3do4qhzu84445osa3sZ home]# docker build -f mydockerfile -t mysentos:1.0.1 .
Sending build context to Docker daemon 193.6 MB
Step 1/10 : FROM centos
 ---> 831691599b88
Step 2/10 : MAINTAINER hzbs<[email protected]>
 ---> Using cache
 ---> fd62c5644424
Step 3/10 : ENV MYPATH /user/local
 ---> Using cache
 ---> 3716e7c4b09c
Step 4/10 : WORKDIR $MYPATH
 ---> Using cache
 ---> 8e27e15e7037
Step 5/10 : RUN yum -y install vim
 ---> Using cache
 ---> 009e774fff42
Step 6/10 : RUN yum -y install net-tools
 ---> Running in a1e240f12b89

Last metadata expiration check: 0:01:03 ago on Mon Jun 22 12:49:10 2020.
Dependencies resolved.
================================================================================
 Package         Architecture Version                        Repository    Size
================================================================================
Installing:
 net-tools       x86_64       2.0-0.51.20160912git.el8       BaseOS       323 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 323 k
Installed size: 1.0 M
Downloading Packages:
net-tools-2.0-0.51.20160912git.el8.x86_64.rpm   1.0 MB/s | 323 kB     00:00    
--------------------------------------------------------------------------------
Total                                           276 kB/s | 323 kB     00:01     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 
  Running scriptlet: net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 
  Verifying        : net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 

Installed:
  net-tools-2.0-0.51.20160912git.el8.x86_64                                     

Complete!
 ---> 2c6378ce1735
Removing intermediate container a1e240f12b89
Step 7/10 : EXPOSE 80
 ---> Running in 7d5c8998cdc2
 ---> 0c6dcd4220c8
Removing intermediate container 7d5c8998cdc2
Step 8/10 : CMD echo $MYPATH
 ---> Running in 728747ba5f03
 ---> 31286280fab2
Removing intermediate container 728747ba5f03
Step 9/10 : CMD echo "---end---"
 ---> Running in 9ae3930786b7
 ---> d28528ea662a
Removing intermediate container 9ae3930786b7
Step 10/10 : CMD /bin/bash
 ---> Running in 0e6fa2110dce
 ---> fd927ec7d5fb
Removing intermediate container 0e6fa2110dce
Successfully built fd927ec7d5fb

# 3. 查看我们刚才制作的镜像
[root@iZhp3do4qhzu84445osa3sZ home]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
mysentos                        1.0.1               fd927ec7d5fb        3 minutes ago       295 MB

# 4. 进入镜像查看 ifconfig 是否生效   官方centos 不剩下  因为没有 yum install net-tools
# 而我们在制作镜像时 下载了这个包
[root@iZhp3do4qhzu84445osa3sZ home]# docker run -it --name mycentos fd927ec7d5fb /bin/bash
[root@ddaa9a1e3fdd local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.5  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:5  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:05  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 586 (586.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.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
# 可以看到我们自己制作的centos镜像时有这个功能的  证明 RUN yum -y install net-tools 这个指令是执行了的
[root@ddaa9a1e3fdd local]# pwd
/user/local
# 工作目录也是我们在制作镜像时设置的 /user/local  也就是我希望别人进入到这个镜像进入的是工作目录  而官方的centos目录是根目录/

# 在这里可以试试vim  这里就不演示了


七、Dcoker 网络 (后面更新)

你可能感兴趣的:(docker,docker,java,大数据,linux,python)