镜像本质上是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基本运行环境开发的软件,它包含运算某个软件所需要的内容和环境,包括代码、运行时库、环境变量和配置文件等。
所有的应用,直接打包docker镜像就可以直接跑起来
如何得到镜像:
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持文件系统的修改作为一次提交一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Docker镜像的基础。镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体应用。
特性:一次同时加载多个问价那系统,但从外表看起来,只能看到一个文件系统,联合加载会吧各层文件系统叠加起来,这样最终的文件系统包括所有底层的文件和目录
我们pull镜像时看到的一层一层的就是这个!!!
Docker镜像加载原理
查看一个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镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!!
这一层就是我们常说的容器层,容器之下的都叫镜像层!
举例: 当我们pull下来一个tomcat镜像时,我们通过镜像启动了tomcat 容器 那么我们其实操作的并不是tomcat这个镜像本身 在我们将tomcat镜像启动为一个容器的时候,会在镜像层的上方新增一个容器层, 其实在文件分层的概念上来说 tomcat镜像本身是镜像层,是只读的 我们的操作都在镜像层上的容器层进行
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的理念回顾
将应用和环境打包成一个镜像
我们的项目都会保存一些数据img,所以我们的数据是不会存到容器内的 ,因为一旦容器被删除那么数据也就删除了
需求:数据可以做持久化!!
例如MYSQL ,容器删了 那就相当于是删库跑路了 所以我们的需求就是将mysql的数据保存到本地
容器之间可以有一个数据共享的技术!Docker 容器中产生的数据,同步到本地!
总结:容器中数据的持久化和同步操作!容器之间也是可以数据共享的
方式一:直接使用命令来进行挂载 -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]#
# 此时我们发现在容器停止后 还是可以进行数据的挂载的
思考: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容器被删除了 我们的数据库数据也不会丢失
#### 匿名挂载
-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镜像的构建文件!命令脚本
# 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个容器 通过我们自己写的镜像启动 因为都是-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是用来构建docker镜像的文件!命令参数脚本
构建的步骤:
# 我们查看一下官方的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"]
# 我们发现官方的镜像都是纯净的包 都是基础包 很多基础的功能都没有 通常会搭建自己的镜像
官方既然能够制作镜像 ,那么我们也可以构建镜像!!!!
dokcerFile是面向开发的,作进行共享,就需要编写dockerfile文件,这个文件非常的简单
Dcoker 已经逐渐成为了企业交付的标准! 很重要!
指令 | 作用 | 描述 |
---|---|---|
FROM | 基础镜像 | 一切从这里开始构建 |
MAINTAINER | 作者信息 | 国际通用格式:姓名+邮箱 |
RUN | 镜像构建的时候需要运行的命令 | |
ADD | 添加内容 | 举例:添加tomcat |
WORKDIR | 工作目录 | 当前镜像的工作目录 |
VOLUME | 容器卷挂载的目录 | |
EXPOSE | 指定暴露的端口 | 这里暴露端口就不需要-p了 |
CMD | 指定这个容器启动时要运行的命令 | |
ENTRYPOINT | 指定这个容器启动时要运行的命令 | 只有最后的才会生效,可以追加命令 |
ONBUILD | 触发指令 | 当构建一个被继承的DockerFile时,就会运行ONBUILD指令 |
COPY | 拷贝 | 类似于ADD将文件拷贝到镜像中 |
ENV | 构建的时候设置设置环境变量 |
# 创建一个自己的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 这里就不演示了