文章目录
Docker镜像原理-commit镜像
一、镜像讲解
①、镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
②、所有的应用,直接打包docker镜像,就可以直接跑起来!
(1)、如何得到镜像:
①、从远程的仓库下载
②、拷贝文件
③、自己做一个dockerfile
二、docker镜像加载原理
UnionFS(联合文件系统)
我们下载的时候看到的一层层就是这个!
UnionFS (联合文件系统):
Union文件系统( UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
(1)、特性︰
一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来
这样最终的文件系统会包含所有底层的文件和目录
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
(2)、bootis(boot file system):
bootis主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
(3)、rootfs (root file system):
在bootfs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, letc等标准目录和文件rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
三、docker镜像分层
(1)、理解:
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
(2)、例子:
假如基于Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
(3)、特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层!
四、commit镜像
(1)、docker commit提交容器成为一个新的副本
#命令和git的原理类似
docker commit -m=“提交描述的信息” -a=“作者” 容器ID 目标镜像名:TAG
实战测试:
#启动一个默认的tomcat
[root@localhost ~]# docker run -it -p 8080:8080 tomcat
#发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的!给它添加一份配置文件进去
root@c17e3c593edc:/usr/local/tomcat/webapps# ls
root@c17e3c593edc:/usr/local/tomcat/webapps# cd ..
root@c17e3c593edc:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@c17e3c593edc:/usr/local/tomcat# cd webapps
root@c17e3c593edc:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
#将我们修改了的镜像使用commit提交成为一个新的镜像,以后我们就可以使用这个新的镜像
[root@localhost ~]# docker commit -m="add webapps app" -a="grj" c17e3c593edc tomcat-1:1.0
sha256:a648200fa20fbd75dac8e44ec14271c73504e7608c51fad15dcfb55063c4a82b
[root@localhost ~]#
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat-1 1.0 a648200fa20f 5 seconds ago 684MB
nginx latest 605c77e624dd 3 months ago 141MB
tomcat latest fb5657adc892 4 months ago 680MB
redis latest 7614ae9453d1 4 months ago 113MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
centos latest 5d0da3dc9764 7 months ago 231MB
portainer/portainer latest 580c0e4e98b0 13 months ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 2 years ago 791MB
docker commit -m=“add webapps app” -a=“grj” c17e3c593edc tomcat-1:1.0
dockerimages
总结:
这个commit打包镜像将当前的操作环境保存下来 ,这个有点类似于虚拟机的镜像。
文章目录
容器数据卷
五、容器数据卷
(1)、概述:
将应用和环境打包成一个镜像,里面的数据文件存在容器当中,由docker挂载到容器,单不属于联合文件系统(Union File System),数据卷可以提供用于持续存储或共享数据的特性。
(2)、思考?
数据如果都在容器当中,如果我们删除容器,那么数据也会丢失!
如何将数据持久化?
容器之间的数据共享技术!docker容器里面产生的数据,同步到本地。
这就是卷技术,将容器内的数据挂载到Linux的文件目录上。
(3)、特点:
容器的持久化和同步操作,容器之间的数据也是可以共享的!
(4)、部署
- 实战1
#使用命令的方式挂载卷
docker run -it -v 主机目录和容器内的目录进行映射
[root@localhost ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@localhost ~]# cd /home/
[root@localhost home]# ls
ceshi nginx test.java
#“使用docker inspect 容器ID” 命令查看元数据进行验证
#如果能看到下面的这些部分则意味着数据卷挂载成功
[root@localhost ceshi]# docker inspect d1ff4bfe15ba
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
#使用一下刚刚挂载好的数据卷
[root@d1ff4bfe15ba /]# cd /home
[root@d1ff4bfe15ba home]# ls
[root@d1ff4bfe15ba home]# touch test.txt
[root@d1ff4bfe15ba home]# ls
test.txt
[root@localhost ceshi]# pwd
/home/ceshi
[root@localhost ceshi]# ls
test.txt
#这里可以看到我们在Linux虚拟机上写入了一个文件,
可以即时同步到docker镜像上面
[root@localhost ceshi]# vi test.txt
Hello,World!
[root@d1ff4bfe15ba home]# cat test.txt
Hello,World!
docker run -it -v /home/ceshi:/home centos /bin/bash
docker inspect d1ff4bfe15ba
以后我们所有的操作都可以在宿主机上面挂载的目录下完成,操作会自动同步到docker容器内部。
- 实战2:安装MySQL
思考:
安装MySQL后数据持久化的问题。
#下载MySQL镜像
[root@localhost ~]# docker pull mysql:5.7
#启动MySQL
-d:后台运行
-p:端口映射
-v:数据卷挂载
-e:环境的配置(例如修改密码)
--name:容器名字
[root@localhost ~]# 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
f0e606d5753cdff930a66ea67064330f64c66c163cdedaac826637d2c08a51fd
#使用SQLyug连接docker的mysql
#连接3310这个端口
#在本地创建一个数据库“test”,查看一下我们的映射路径
[root@localhost ~]# ls /home/mysql/data/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem test
#我们将容器删除,但是挂载到本地的数据卷仍未丢失,这个时候我们就已经实现了容器持久性的功能
[root@localhost ~]# docker rm -f mysql01
mysql01
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
572b2fd27dc9 portainer/portainer "/portainer" 4 days ago Up About an hour 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp quizzical_hypatia
[root@localhost ~]# ls /home/mysql/data/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem test
docker pull mysql:5.7
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
docker rm -f mysql01
docker ps
六、具名挂载和匿名挂载
#匿名挂载:不指定容器外的目录
-v 容器内的路径
docker -d -p --name nginx01 -v /etc/nginx nginx
#使用匿名挂载
[root@localhost ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
1458102dc9e10460c8712590516c50e44657887ffc960f5e0388ec5d8718e835
#查看所有的volume的情况
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 2a7ea4aa7b409318572914e56af3c93ce85a9974d407f4ce6a039db7f350fdde
local 850e72abcdce033c05a222682f636f9591089908bed6e076545ccdfacdd7cb02
#使用具名挂载Nginx:通过-v 卷名:容器内路径
[root@localhost ~]# docker run -d -P --name nginx02 -v juming_nginx:/etc/nginx nginx
82ac6c740c7807d3a87c02cbad9958e170e39d2a7aa6e267e8585847009f0cfb
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 2a7ea4aa7b409318572914e56af3c93ce85a9974d407f4ce6a039db7f350fdde
local 850e72abcdce033c05a222682f636f9591089908bed6e076545ccdfacdd7cb02
local juming_nginx
#查看卷的路径
[root@localhost ~]# docker volume inspect juming_nginx
[
{
"CreatedAt": "2022-04-24T17:18:54+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming_nginx/_data",
"Name": "juming_nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/*/_data
我们使用具名挂载都可以找到我们的一个卷,绝大多数的情况下我们使用的都是具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定目录路径挂载
-v容器内路径 #匿名挂载
-v卷名:容器内路径 #具名挂载
-v/宿主机路径:容器内路径 #指定路径挂载!
#通过-v容器内路径:
rorw改变读写权限
#只读:roreadonly
#可读可写:rwreadwrite
#一旦这个了设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -p --name nginx02 -v juming-nginx: /etc/nginx:ronginx
docker run -d -p --name nginx02 -v juming-nginx : /etc/nginx:rw nginx
# ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
docker run -d -P --name nginx01 -v /etc/nginx nginx
docker volume ls
docker volume inspect juming_nginx
docker run -d -p --name nginx02 -v juming-nginx: /etc/nginx:ronginx
docker run -d -p --name nginx02 -v juming-nginx : /etc/nginx:rw nginx
七、dockerfile
(1)、docker就是用来构建docker镜像的文件!
(2)、使用命令脚本生成一个镜像
#创建一个dockerfile文件
#写入文件的内容,脚本的一行命令对应的就是镜像的一层一层的操作
[root@localhost docker-test-volume]# cat docker-test1
FROM centos
VOLUME ["volume01","volume02"] //没有指定挂载目录【匿名挂载】
CMD echo "---end---"
CMD /bin/bash
#生成镜像
[root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/docker-test1 -t grj/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in b675053f69ad
Removing intermediate container b675053f69ad
---> 35dcc5c75613
Step 3/4 : CMD echo "---end---"
---> Running in e6556454ef08
Removing intermediate container e6556454ef08
---> fffe798b3763
Step 4/4 : CMD /bin/bash
---> Running in c6550f38e0ba
Removing intermediate container c6550f38e0ba
---> 0fe37490d4a0
Successfully built 0fe37490d4a0
Successfully tagged grj/centos:latest
[root@localhost docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
grj/centos latest 0fe37490d4a0 31 seconds ago 231MB
tomcat-1 1.0 a648200fa20f 38 hours ago 684MB
nginx latest 605c77e624dd 3 months ago 141MB
tomcat latest fb5657adc892 4 months ago 680MB
redis latest 7614ae9453d1 4 months ago 113MB
mysql 5.7 c20987f18b13 4 months ago 448MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
centos latest 5d0da3dc9764 7 months ago 231MB
portainer/portainer latest 580c0e4e98b0 13 months ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 2 years ago 791MB
#启动自己创建的一个容器
[root@localhost docker-test-volume]# docker run -it 0fe37490d4a0 /bin/bash
[root@f9551954f6cf /]#
#查看挂载的数据卷目录
[root@f9551954f6cf /]# ls -l
total 0
... ...
drwxr-xr-x. 2 root root 6 Apr 25 02:45 volume01
drwxr-xr-x. 2 root root 6 Apr 25 02:45 volume02
#查看卷挂载的路径
[root@localhost ~]# docker inspect 1098aa9684dc
... ...
"Mounts": [
{
"Type": "volume",
"Name": "f4bb2e1c512c1149f1bf0715191fdbb36d20148ec6c25fa12dc4fb42f767408e",
"Source": "/var/lib/docker/volumes/f4bb2e1c512c1149f1bf0715191fdbb36d20148ec6c25fa12dc4fb42f767408e/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "a02f6d6a3874279247515847fbdd3fb753901b9d53e7d132c7787819c0c543f6",
"Source": "/var/lib/docker/volumes/a02f6d6a3874279247515847fbdd3fb753901b9d53e7d132c7787819c0c543f6/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
#查看同步是否成功
[root@localhost ~]# cd /var/lib/docker/volumes/a02f6d6a3874279247515847fbdd3fb753901b9d53e7d132c7787819c0c543f6/_data
[root@localhost _data]# ls
container.txt
数据卷容器
一、多个容器同步数据
#启动容器多个容器并查找挂载目录
[root@localhost ~]# docker run -it --name centos01 grj/centos
[root@9f289f5ec06b /]# ls -lh
total 0
... ...
drwxr-xr-x. 2 root root 6 Apr 25 03:11 volume01
drwxr-xr-x. 2 root root 6 Apr 25 03:11 volume02
[root@localhost ~]# docker run -it --name centos02 --volumes-from centos01 grj/centos
[root@7532c7275fb0 /]# ls -l
total 0
... ...
drwxr-xr-x. 2 root root 6 Apr 25 03:11 volume01
drwxr-xr-x. 2 root root 6 Apr 25 03:11 volume02
#进入到容器01在挂载目录下新建一个文件
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7532c7275fb0 grj/centos "/bin/sh -c /bin/bash" About a minute ago Up About a minute centos02
9f289f5ec06b grj/centos "/bin/sh -c /bin/bash" 11 minutes ago Up 11 minutes centos01
572b2fd27dc9 portainer/portainer "/portainer" 4 days ago Up 43 minutes 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp quizzical_hypatia
[root@localhost ~]# docker attach 9f289f5ec06b
[root@9f289f5ec06b /]# cd volume01
[root@9f289f5ec06b volume01]# ls
[root@9f289f5ec06b volume01]# touch docker01
[root@9f289f5ec06b volume01]# ls
docker01
#在容器2上查看文件是否同步
[root@7532c7275fb0 /]# cd volume01
[root@7532c7275fb0 volume01]# ls
docker01
#启动第三个容器并将容器数据卷挂载到centos01
[root@localhost dockerfile]# docker run -it --name centos03 --volumes-from centos01 grj/centos
#在centos02挂载目录中新建文件
[root@b6dfd12a8e36 volume01]# touch test02.txt
[root@b6dfd12a8e36 volume01]# ls
test02.txt test1.txt
#在centos容器上面查看
[root@364862191d15 volume01]# ls
test02.txt test1.txt
二、多个MySQL实现数据共享
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 -name mysql02 --volumes-from mysql01 mysql:5.7
①、容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用位为止。
②、但是一单你持久化到了本地,这个时候,本地的数据是不会删除的。
三、DockerFile
(1)、用来构建docker镜像文件!
构建步骤:
1、编写一个docker文件、
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(dockerhub、阿里云镜像仓库)
访问官方镜像仓库
很多官方的镜像往往是没有很多命令和其它的功能,通常需要我们自己去添加
四、DockerFile构建过程
(1)、基础知识
①、每个保留关键字(命令),都必须是大写字母
②、执行重上到下顺序执行
③、# 表示注释
④、每个指令都会创建提交一个新的镜像层,并提交!
docker镜像逐渐成为了项目实战交付的标准。
(2)、DockerFile:
构建文件,定义了一切的步骤,源代码
(3)、Dockerimages:
通过DockerFile构建生成的镜像,最终发布和运行的产品,最终发布和运行的产品
(4)、Docker容器:容器就是镜像运行起来提供服务
五、Dockerfile镜像命令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤:tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR #镜像的目录
VOLUME #挂载的目录
EXPOST #暴露端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #可以追加命令
ONBUILD #当构建一个被继承,Dockerfile,这个时候就会运行ONBUILD 的指令,触发指令
COPY #类似ADD,将我们的文件拷贝到镜像中
ENV #设置环境变量