docker进阶学习
一、可视化面板
(1)什么是 portainer
Portainer是Docker的图形化管理WEB工具,由GO语言编写的,提供状态显示、应用模板快速部署、对于Docker([容器]、镜像、网络、数据卷)的基本操作、日志显示、容器控制台等功能。
(2)安装、启动命令
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
(3)访问测试
#浏览器访问启动成功的地址 注:第一次访问加载较慢
http://ip:8088
(4)设置密码–创建用户–登录
登陆之后的页面是:
本机docker运行情况统计
点击进入详情,里面包含容器、镜像、挂载目录等模块。
二、docker镜像分层
Docker 镜像由一些松耦合(关系不怎么紧密)的只读镜像层组成,Docker Daemon 负责堆叠这些镜像层,并将它们关联为一个统一的整体,即对外表现出的是一个独立的对象。
介绍
Docker 镜像采用分层结构来构建和管理,这是其轻量、高效和可复用性的关键。镜像的分层结构使得 Docker 镜像在构建、部署和更新过程中非常灵活,同时节省存储空间和下载时间。下面是 Docker 镜像分层的详细介绍:
- 只读分层:
Docker 镜像由多个只读的文件系统层组成,每个分层包含了一个或多个文件或目录的更改。这些分层按照从底部到顶部的顺序叠加在一起,形成了一个完整的镜像。底部的分层通常是一个基础操作系统的根文件系统,而顶部的分层包含了应用程序代码和配置等信息。由于每个分层是只读的,所以镜像在创建后不会被更改。 - 联合文件系统:
Docker 使用联合文件系统(UnionFS)技术将多个只读分层组合成一个单一的虚拟文件系统。联合文件系统使得各个分层看起来像是一个整体,使得镜像中的每个分层的内容在文件系统层次结构中可见,但实际上并不复制这些内容。这样的设计节省了存储空间,并且可以在不同的镜像之间共享公共层,从而加快镜像的构建和下载速度。 - 分层继承:
Docker 镜像支持分层继承,这意味着可以基于现有的镜像构建新的镜像。当新的镜像构建时,它只需在现有镜像的基础上添加新的分层,而不需要重新复制现有的分层。这种分层继承的特性使得镜像构建变得高效和快速,并允许镜像的复用。 - 可读写容器层:
当基于镜像创建一个容器时,Docker 会在镜像的顶部添加一个可读写的容器层。这个容器层允许容器在运行时对文件系统进行写操作,例如应用程序的日志输出、数据库文件等。容器层是临时的,只在容器运行时存在,当容器停止时,对容器层的修改也会被丢弃,保持镜像的不可变性。 - 镜像的复用和共享:
Docker 镜像分层的结构使得镜像可以复用和共享。多个镜像可以共享相同的基础层,从而节省存储空间,并减少镜像拉取和构建的时间。这对于持续集成、持续部署和分布式系统的部署非常有益。 - 总结来说,Docker 镜像的分层结构是一种高效、灵活和可复用的设不同的环境中可以轻松部署和运行,同时节省了存储空间和提高了构建和下载速度。这种设计也促进了 Docker 生态系统的发展和镜像的共享,使得 Docker 成为一种广泛使用的容器化技术。
通过 d o c k e r p u l l 命令拉取指定的镜像时,每个 P u l l c o m p l e t e 结尾的行就代表下载完毕了一个镜像层。 \textcolor{GreenYellow}{通过 docker pull 命令拉取指定的镜像时,每个 Pull complete 结尾的行就代表下载完毕了一个镜像层。} 通过dockerpull命令拉取指定的镜像时,每个Pullcomplete结尾的行就代表下载完毕了一个镜像层。
[root@docker ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Already exists
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
docker.io/library/nginx:latest
镜像层构成
Docker 镜像是由一系列只读的文件系统层构成的,这些层会按特定顺序叠加在一起,构成一个完整的镜像。镜像层的设计使得 Docker 具有轻量、高效和可复用的特性。下面是 Docker 镜像层构成的详细介绍:
-
基础镜像层:
Docker 镜像的第一层是基础镜像层,它通常包含一个最小化的操作系统,如Alpine Linux、Ubuntu、CentOS等。这个基础镜像提供了运行应用程序所需的最基本的文件和工具。基础镜像通常是公共或私有的,供其他镜像构建和扩展使用。 -
应用程序依赖层:
在基础镜像之上,Docker 可以添加应用程序的依赖项和运行时环境,这些依赖项可能包括软件包、库文件等。这些层用于支持应用程序的执行和运行所需的软件和工具。 -
应用程序代码层:
在依赖层之上,Docker 可以添加应用程序的实际代码和资源文件。这些层包含了应用程序的源代码、配置文件、静态资源等。这使得 Docker 镜像能够完整地包含应用程序的所有代码。 -
只读层:
镜像的每个层都是只读的,这意味着在构建后,镜像层的内容不会再改变。这种设计有助于镜像的高效性和可复用性。如果需要修改镜像,Docker 将在现有层之上创建新的镜像层,保持原有层的完整性。 -
共享相同层:
当多个镜像共享相同的基础层时,它们可以节省存储空间和下载时间。因为这些镜像只需在自己的特定层上添加差异层,而不是复制整个基础镜像。这使得镜像的存储和传输变得更加高效。 -
镜像的唯一标识:
每个镜像都有一个唯一的标识符,称为镜像 ID,它是根据镜像内容生成的哈希值。镜像 ID 是根据所有镜像层的内容计算得出的,即使一个镜像只有一个小的改动,它的镜像 ID 也会发生变化。这种特性有助于确保镜像的唯一性和数据的完整性。
每个镜像层由两部分构成:镜像文件系统与镜像 json 文件。这两部分具有相同的 ImageID。镜像文件系统就是对镜像占有的磁盘空间进行管理的文件系统,拥有该镜像所有镜像层的数据内容。而镜像 json 文件则是用于描述镜像的相关属性的集合,通过 docker inspect [镜像]就可以直观看到。
三、commit镜像
- docker commit 命令用于根据 Docker容器 的更改创建一个新的 Dokcer镜像。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。
命令格式
docker commit -m="[提交的描述信息]" -a="[作者]" [容器ID] [新的镜像名称]:[新的镜像标签]
参数 | 描述 |
---|---|
-a, --author string | 作者 |
-c, --change list | 应用 dockerfile 指令来创建图像。 |
-m, --message | string |
-p, --pause | 提交期间暂停容器(默认为true)。 |
示例
- 例如我们对新拉取的镜像进行了修改 我们可以将修改后的惊险commit到docker images中 后面可以直接拉取我们commit的镜像
- 以tomcat为例:
# 1、拉取tomcat镜像
docker pull tomcat
# 2、启动镜像
docker run -d -p 3355:8080 --name tomcat01 tomcat
#此时打开http://ip:3355页面显示404
# 3、进入tomcat
docker exec -it tomcat01 /bin.bash
#4、将webapps.dist中的文件复制到webapps下面
cp -r webapps.dist/* webapps
#5、此时打开浏览器在访问http://ip:3355页面 显示tomcat正常 现在这个版本的tomcat镜像就是我们要的完整的镜像 现在需要把他commit到我们的docker images中
docker commit -m="提交tomcat" -a="red" eb370257efb7 tomcat02:1.0
#6、此时查看docker images 就能看到我们提交的名称为 tomcat02 的镜像 版本为1.0
#7、删除已经运行的tomcat 网页已经进入不到我们的tomcat中
docker rm -f eb370257efb7
#8、重新运行刚刚提交的tomcat02
docker run -d -p 3355:8080 --name tomcat03 tomcat02:1.0
#9、此时不需要做任何操作 直接访问浏览器 直接看到tomcat界面
- 此处可以更好地理解分层的概念
我们把拉取到的tomcat镜像理解为一层 在tomcat基础上我们加了一层 这一层就是我们对内部的webapps.dist进行操作的一层
最后我们把两层一起打包 commit到docker images中 用于后续直接拉取
四、容器数据卷
(一)容器数据卷的介绍
- Docker可以将开发的应用和运行的环境一起打包形成容器运行,Docker容器产生的数据,如果不通过Commit生成一个新的镜像,使得这些数据成为镜像的一部分保存下来,那当容器删除时,数据自然也就没有了(相当于别人删除跑路),为了能够保存数据在Docker中我们使用数据卷。
- 卷就是目录和文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过union file system提供一些用于持续存储或共享数据的特性。(将docker容器内的数据保存进宿主机的磁盘中)
- 卷的设计目的就是数据持久化(类似于redis中的rdb和aof文件),完全独立于容器的生命周期,因此docker不会在容器删除时删除其挂载的容器卷。
(二) 数据卷的特点
- 数据卷可在容器之间共享或重用数据
- 数据卷的更改会直接生效
- 数据卷的更改不会包含到镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
例如mysql的数据要挂载到linux文件系统中
(三) 使用数据卷
方式一 :使用命令方式挂载 -v
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=root --name mysql mysql
- -d 后台运行
- -p 暴露端口
- -v 数据挂载
- -e mysql配置密码
- –name 别名
进入容器内部
docker exec -it mysql /bin/bash
进入数据文件夹
cd /var/lib/mysql
ls 查看内部文件
此时为:
使用datagrip远程连接数mysql 并且新建一个数据库 再次ls查看内部文件
此时已经多了一个数据库:
访问linux本机挂载的文件
cd /home/mysql/data
ls查看内部文件
此时发现新增数据库已经同步过来了
(四) 具名和匿名挂载
匿名挂载
匿名挂载就是指定容器内路径,dockers run 每挂载一个目录就会宿主主机自动创建一个随机字符串的目录。目录/var/lib/docker/volumes/随机字符串。
匿名挂载示例
运行容器
docker run -d -p 8000:80 --name nginxtest -v /etc/nginx nginx
#查看所有的volume
docker volume ls
#得到结果:
DRIVER VOLUME NAME
local 7b23fa71b5b47001962eddaf376c4d6bad4df365b63c458fb9bc6866fec98d94
local 14b9a15e9dc3f7419b0ece9076e0cbf8e9120ee57dc16a709b2335ef78082f6b
local 076b36a05625f9ae35ffdedebd6690e58ef46a279b64463bd45d649f6361ef3f
local ab952e8073354f96d00f34abc71aa81467f98b3406e6a9f90e170d94a2d5a843
local cfb419957c6654c7193a75bca445f1bb153f151377418c9e66a032bc2834fac7
local da2232656e9974568db21fc0568f9ba8764da397b9b164bf8b7f8b69aa05195c
local mq-plugins
具名挂载(大多数使用的形式)
docker run -d -p 3344:80 --name nginx02 -v juming-ngin:/etc/nginx nginx
- 具名挂载 -v 卷名:容器内路径
docker volume ls 查看
此时已经可以找到卷名
使用命令: docker volume inspect juming-ngin 查看挂载文件的具体位置
我们进入/var/lib/docker/volumes/juming-ngin/_data文件夹 ls查看文件夹内部 会发现nginx配置文件已经挂载进来了
(四) 挂载的方式
- 指定路径挂载:-v 容器外路径:容器内路径
- 匿名挂载 :-v 容器内路径
- 具名挂载 : -v 卷名:容器内路径
拓展
# -v 卷名:容器内路径:(后面会加上ro或者rw)
#ro : 只读 readonly
#ew :可读可写 read write
docker run -d -p 3344:80 --name nginx02 -v juming-ngin:/etc/nginx:ro nginx
docker run -d -p 3344:80 --name nginx02 -v juming-ngin:/etc/nginx:rw nginx