Docker学习(来自狂神说Java)
1 - Docker概述
1)docker的由来:
一款产品: 开发–上线 两套环境!应用环境,应用配置!
开发 — 运维。 问题:我在我的电脑上可以允许!版本更新,导致服务不可用!对于运维来说考验十分大?
环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop…) !费事费力。
发布一个项目( jar + (Redis MySQL JDK ES) ),项目能不能带上环境安装打包!
之前在服务器配置一个应用的环境 Redis MySQL JDK ES Hadoop 配置超麻烦了,不能够跨平台。
开发环境Windows,最后发布到Linux!
传统:开发jar,运维来做!
现在:开发打包部署上线,一套流程做完!
安卓流程:java — apk —发布(应用商店)一 张三使用apk一安装即可用!
docker流程: java-jar(环境) — 打包项目帯上环境(镜像) — ( Docker仓库:商店)-----
Docker给以上的问题,提出了解决方案!
2)docker的思想来源于集装箱
JRE – 多个应用(端口冲突) – 原来都是交叉的!
隔离:Docker核心思想!打包装箱!每个箱子是互相隔离的。
Docker通过隔离机制,可以将服务器利用到极致!
本质:所有的技术都是因为出现了一些问题,我们需要去解决,才去学习!
3)docker的历史
2010年,几个的年轻人,就在美国成立了一家公司 dotcloud
做一些pass的云计算服务!LXC(Linux Container容器)有关的容器技术!
- Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
他们将自己的技术(容器化技术)命名就是 Docker。
Docker刚刚延生的时候,没有引起行业的注意!dotCloud,就活不下去!
- 开源
2013年,Docker开源!
越来越多的人发现docker的优点!火了。Docker每个月都会更新一个版本!
2014年4月9日,Docker1.0发布!
**docker为什么这么火?**十分的轻巧!
在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在window中装一个VMware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重!
虚拟机也属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!
- vm : linux centos 原生镜像(一个电脑!) 隔离、需要开启多个虚拟机! 几个G 几分钟
- docker: 隔离,镜像(最核心的环境 4m + jdk + mysql)十分的小巧,运行镜像就可以了!小巧! 几个M 秒级启动!
Docker基于Go语言开发的!开源项目!
docker官网:https://www.docker.com/
文档:https://docs.docker.com/ Docker的文档是超级详细的!
仓库:https://hub.docker.com/
4)docker容器化与虚拟化技术的对比
①虚拟机技术的缺点:
- 资源占用十分多
- 冗余步骤多
- 启动速度慢
②容器化技术的优点:互相隔离,互不影响,轻便,拥有独立的文件系统,安全
比较Docker容器和虚拟机技术的不同:
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
5)docker能做什么
①应用更快速的交付和部署
传统:一对帮助文档,安装程序。
Docker:打包镜像发布测试一键运行。
②更便捷的升级和扩缩容
使用了 Docker之后,我们部署应用就和搭积木一样
项目打包为一个镜像,扩展服务器A!服务器B
③更简单的系统运维
④在容器化之后,我们的开发,测试环境都是高度一致的
⑤更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
2 - Docker安装
1)docker的基本组成
镜像(image)
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像==>run==>容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container)
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的.
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的 Linux系统。
仓库(repository)
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库。(很类似git)
Docker Hub是国外的。
阿里云…都有容器服务器(配置镜像加速!)
2)环境准备
Linux系统内核需要3.0以上
3)安装
帮助文档:https://docs.docker.com/engine/install/
下载地址:https://docs.docker.com/engine/install/centos/
以下使用命令安装,在Linux环境执行相应命令即可
1.卸载旧版本
#1.卸载旧版本 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2.需要的安装包
yum install -y yum-utils
3.设置镜像的仓库
yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的非常慢 #推荐使用国内的 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4.安装docker相关的 docker-ce 社区版 而ee是企业版
#更新yum软件包索引 yum makecache fast #4.安装docker相关的 docker-ce 社区版 而ee是企业版 yum install docker-ce docker-ce-cli containerd.io
5.启动docker
systemctl start docker
6.使用 docker version检验是否安装成功
docker version
7.测试
docker run hello-world
4)测试结果
查看以下写下的 hello-world 镜像
docker images
5)卸载docker(了解即可)
#1. 卸载依赖 yum remove docker-ce docker-ce-cli containerd.io #2. 删除资源 rm -rf /var/lib/docker # /var/lib/docker 是docker的默认工作路径!
6)docker run 运行流程
3 - docker运行原理
1)docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
Docker-Server接收到Docker-Client的指令,就会执行这个命令!
原理图
2)为什么Docker比Vm快
1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。
因此在CPU、内存利用率上docker将会在效率上有明显优势。
2、docker利用的是宿主机的内核,而不需要Guest OS。
GuestOS: VM(虚拟机)里的的系统(OS);
HostOS:物理机里的系统(OS);
因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。然而避免引导。加载操作系统内核是个比较费时费资源的过程,
当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的
过程,因此新建一个docker容器只需要几秒钟。
4 - docker常用命令
1)帮助命令
docker verson # 显示docker的版本信息 docker info # 显示docker的系统信息,包括 镜像和容器的数量 docker 命令 --help # 帮助命令
帮助文档的地址:https://docs.docker.com/engine/reference/commandline/build/
2)镜像命令
docker images 查看所有本地主机上的镜像
[root@VM-0-17-centos /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 e73346bdf465 24 hours ago 448MB
# 解释 #REPOSITORY # 镜像的仓库源 #TAG # 镜像的标签 #IMAGE ID # 镜像的id #CREATED # 镜像的创建时间 #SIZE # 镜像的大小
# 可选项 Options: -a, --all Show all images (default hides intermediate images) #列出所有镜像 -q, --quiet Only show numeric IDs # 只显示镜像的id
docker search 搜索镜像
# 搜索mysql镜像 [root@VM-0-17-centos /]# docker search mysql --filter=STARS=3000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 10013 [OK] mariadb MariaDB is a community-developed fork of MyS… 3664 [OK] # 可选项,通过收藏来过滤 --filter=STARS=3000 # 搜索出来的镜像就是STARS>3000
docker pull 下载镜像
# 下载镜像 docker pull 镜像名[:tag] [root@VM-0-17-centos /]# docker pull mysql Using default tag: latest # 如果不写tag,默认是latest latest: Pulling from library/mysql d121f8d1c412: Pull complete # 分层下载,docker image 的核心。联合文件系统 f3cebc0b4691: Pull complete 1862755a0b37: Pull complete f576086003cf: Pull complete 3b72593ce10e: Pull complete Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df640a027 # 签名信息 防伪标志 Status: Downloaded newer image for tomcat:8 docker.io/library/tomcat:8 #真实地址 #下面两个命令等价 docker pull tomcat:8 docker pull docker.io/library/tomcat:8 # 指定版本下载 [root@VM-0-17-centos /]# docker pull mysql:5.7 5.7: Pulling from library/mysql
docker rmi 删除镜像
docker rmi -f 镜像id # 删除指定的镜像 docker rmi -f 镜像id 镜像id 镜像id 镜像id # 删除指定的镜像 docker rmi -f $(docker images -aq) # 删除全部的镜像
3)容器命令
说明:我们有了镜像才可以创建容器,Linux,下载centos镜像来学习
docker pull centos
①新建容器并启动
docker run [可选参数] image # 参数说明 --name="name" # 容器名字 tomcat1 tomcat2, 用来区分容器 -d # 后台方式运行 -it # 使用交互方式运行,进入容器查看内容 -p # 指定容器的端口,-p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 容器端口 -P(大写) # 随机指定端口 # 测试,启动并进入容器 [root@VM-0-17-centos /]# docker run -it centos /bin/bash [root@0d5b92e5b276 /]# ls # 查看容器内的centos,基础版本,很多命令都是不完善的 bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var # 从容器中退回主机 [root@0d5b92e5b276 /]# exit exit [root@VM-0-17-centos /]#
②列出所有运行的容器
# docker ps 命令 # 列出正在运行的容器 -a, --all Show all containers (default shows just running) -n, --last int Show n last created containers (includes all states) (default -1) -q, --quiet Only display numeric IDs [root@VM-0-17-centos /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@VM-0-17-centos /]# docker ps -a # 列出当前运行的容器+历史运行过的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0d5b92e5b276 centos "/bin/bash" 19 minutes ago Exited (0) 3 minutes ago jovial_kowalevski 68c5841c988d hello-world "/hello" 14 hours ago Exited (0) 14 hours ago xenodochial_engelbart 4f5126cf6d2e hello-world "/hello" 15 hours ago Exited (0) 15 hours ago keen_keldysh [root@VM-0-17-centos /]# docker ps -a -n=1 # 显示最近创建的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0d5b92e5b276 centos "/bin/bash" 23 minutes ago Exited (0) 7 minutes ago jovial_kowalevski [root@VM-0-17-centos /]# docker ps -aq 0d5b92e5b276 68c5841c988d 4f5126cf6d2e
③退出容器
exit # 停止运行容器并退出 Ctrl + p + q # 容器不停止运行并退出
④删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf docker rm -f $(docker ps -aq) #删除指定的容器 docker ps -a -q|xargs docker rm #删除所有的容器
⑤启动和停止容器的操作
docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前容器
4)常用的其他命令
①后台启动命令
# 命令 docker run -d 镜像名 [root@VM-0-17-centos /]# docker run -d centos a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c [root@VM-0-17-centos /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 问题docker ps. 发现centos 停止了 # 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止 # nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
②查看日志
[root@VM-0-17-centos /]# docker logs --help Usage: docker logs [OPTIONS] CONTAINER Fetch the logs of a container Options: --details Show extra details provided to logs -f, --follow Follow log output --since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) --tail string Number of lines to show from the end of the logs (default "all") -t, --timestamps Show timestamps --until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) #显示日志 -tf #显示日志信息(一直更新) --tail number #需要显示日志条数 docker logs -t --tail n 容器id #查看n行日志 docker logs -ft 容器id #跟着日志
③查看容器中进程信息 ps
# 命令 docker top 容器id [root@VM-0-17-centos /]# docker top 2ed4a49d6421 UID PID PPID C STIME TTY TIME CMD root 18804 18788 0 13:34 pts/0 00:00:00 /bin/bash
④查看镜像的元数据
# 命令 docker inspect 容器id # 测试 [root@VM-0-17-centos /]# docker inspect 2ed4a49d6421 [ { "Id": "2ed4a49d642189d07b63ed8b42dda322aa3d4cf3a4e0f3d9355ef1574649cd1f", "Created": "2020-10-03T05:34:34.416163618Z", "Path": "/bin/bash", "Args": [],
⑤进入当前正在运行的容器
我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置信息
# 方式1命令 docker exec -it 容器id bashShell # 测试 [root@VM-0-17-centos /]# docker exec -it 2ed4a49d6421 /bin/bash [root@2ed4a49d6421 /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 05:34 pts/0 00:00:00 /bin/bash root 19 0 0 05:50 pts/1 00:00:00 /bin/bash root 32 19 0 05:50 pts/1 00:00:00 ps -ef # 方式2命令 docker attach 容器id # 测试 [root@VM-0-17-centos /]# docker attach 2ed4a49d6421 正在执行当前的代码。。。 # 方式1与方式2的区别 #docker exec 进入当前容器后开启一个新的终端,可以在里面操作。(常用) #docker attach 进入容器正在执行的终端,不会启动新的进程
⑥从容器内拷贝文件到主机上
# docker cp 容器id:容器内路径 主机目的路径 # 进入docker容器内部 [root@VM-0-17-centos test]# docker attach a3c3a339c64c [root@a3c3a339c64c /]# cd home [root@a3c3a339c64c home]# ls # 在容器内新建一个文件 [root@a3c3a339c64c home]# touch Test.java [root@a3c3a339c64c home]# ls Test.java [root@a3c3a339c64c home]# exit exit [root@VM-0-17-centos test]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@VM-0-17-centos test]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3c3a339c64c centos "/bin/bash" 7 minutes ago Exited (0) 13 seconds ago kind_franklin 2ed4a49d6421 centos "/bin/bash" 35 minutes ago Exited (127) 8 minutes ago crazy_ganguly 47ec2453c997 centos "/bin/bash" 3 hours ago Exited (127) 41 minutes ago boring_albattani # 将这个新建的文件拷贝到主机目录上 [root@VM-0-17-centos test]# docker cp a3c3a339c64c:/home/Test.java /home/test/ [root@VM-0-17-centos test]# ls Hello.java Test.java [root@VM-0-17-centos test]# # 拷贝是一个手动的过程,未来我们使用,-v 卷的技术,可以实现
5)小结
5 - docker命令帮助手册(方便查询)
attach Attach to a running container #当前she11下attach 连接指定运行镜像 build Build an image from a Dockerfile #通过Dockerfile定制镜像 commit Create a new image from a container changes #提交当前容器为新的镜像 cp Copy files/folders from the containers filesystem to the host path #从容器中拷贝指定文件或者目录到宿主机中 create Create a new container #创建一个新的容器,同run,但不启动容器 diff Inspect changes on a container's filesys tem #查看docker 容器变化 events Get rea1 time events from the server #从docker 服务获取容器实时事件 exec Run a command in an existing container #在已存在的容器上运行命令 export Stream the contents of a container as a tar archive #导出容器的内容流作为一个tar 归档文件[对应import ] history show the history of an image #展示一个镜像形成历史 images List images #列出系统当前镜像 import Create a new filesystem image from the contents of a tarba1l #从tar包 中的内容创建-一个新的文件系统映像[对应export] info Display system-wide informati on #显示系统相关信息 inspect Return 1ow-1evel information on a container #查看容器详细信息 kill Ki11 a running container # kill指定docker容器 load Load an image from a tar archive #从一个tar包中加载一个镜像[对应save] login Register or Login to the docker registry server #注册或者登陆一个docker源服务器 logout Log out from a Docker registry server #从当前Docker registry 退出 logs Fetch the 1ogs of a container #输出当前容器日志信息 port Lookup the public-facing port which is NAT-ed to PRIVATE_ PORT #查看映射端口对应的容器内部源端口 pause Pause a11 processes within a container #暂停容器 ps List containers #列出容器列表 pull Pull an image or a repository from the docker registry server # 从docker镜像源服务器拉取指定镜像或者库镜像 push Push an image or a repository to the docker registry server #推送指定镜像或者库镜像至docker源服务器 restart Restart a running container #重启运行的容器 rm Remove one or more containers #移除一个或者多个容器 rmi Remove one or more i mages #移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容才可继续或-f强制删除] run Run a command in a new container #创建一个新的容器并运行一个命令 save Save an image to a tar archive #保存一个镜像为一个tar包[对应1oad] search Search for an image on the Docker Hub #在docker hub中搜索镜像 start Start a stopped containers #启动容器 stop Stop a running containers #停止容器 tag Tag an image into a repository #给源中镜像打标签 top Lookup the running processes of a container #查看容器中运行的进程信息 unpause Unpause a paused container #取消暂停容器 version Show the docker vers ion informati on #查看docker版本号 wait Block uyntil a container stops,then print its exit code #截取容器停止时的退出状态值
6 - Docker 安装Nginx(体会暴露端口的重要性)
#1. 搜索镜像 search 建议大家去docker搜索,可以看到帮助文档 #2. 拉取镜像 pull #3. 运行测试 # -d 后台运行 # --name 给容器命名 # -p 宿主机端口:容器内部端口 [root@VM-0-17-centos /]# docker run -d --name nginx01 -p 3344:80 nginx de9b9741a779f92c301330c99bd35e0876a4a4c06e30cad385ce916556d0c4d9 [root@VM-0-17-centos /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES de9b9741a779 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:3344->80/tcp nginx01 [root@VM-0-17-centos /]# curl localhost:3344 # 显示欢迎HTML代码,测试通过 # 进入docker容器 [root@VM-0-17-centos /]# docker exec -it nginx01 /bin/bash root@de9b9741a779:/# whereis nginx nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx root@de9b9741a779:/# cd /etc/nginx root@de9b9741a779:/etc/nginx# ls conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
端口暴露的原理图
思考问题:我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?→ 数据卷!
7 - Docker 安装Tomcat(体会进入容器的重要性)
# 官方的使用 docker run -it --rm tomcat:9.0 # 之前的启动都是后台,停止了容器,容器还是可以查到 # docker run -it --rm image 一般是用来测试,用完就删除(暂时不建议) --rm Automatically remove the container when it exits #下载 docker pull tomcat #启动运行 docker run -d -p 8080:8080 --name tomcat01 tomcat #测试访问有没有问题 curl localhost:8080 # 进入容器 [root@VM-0-17-centos /]# docker exec -it tomcat01 /bin/bash """ 发现问题: 1.Linux命令少了 2.没有webapps 镜像(阉割版),它为保证最小镜像,将不必要的都剔除了→保证最小可运行环境!"""
思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步内部就好了
8 - Docker 部署es+kibana(体会查看当前容器状态的重要性,如何修改容器运行的环境)
# es 暴露的端口很多! # es 十分耗内存 # es 的数据一般需要放置到安全目录!挂载 # --net somenetwork ? 网络配置 # 下载启动elasticsearch(Docker一步搞定) docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 # 启动了Linux变得异常卡顿 docker stats 查看CPU的状态 # 测试一下es 是否成功了 [root@VM-0-17-centos /]# curl localhost:9200 { "name" : "a89b5ba53ef3", "cluster_name" : "docker-cluster", "cluster_uuid" : "u-ELuE3kQxy4lR4Rg48RDA", "version" : { "number" : "7.6.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } #关闭elasticsearch,添加内存的限制,修改配置文件 -e 环境配置修改 docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2 # 测试 CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS dc89b9f38728 elasticsearch02 0.54% 340.4MiB / 1.795GiB 18.52% 772B / 96B 102MB / 729kB 42
使用kibana连接es?思考网络如何才能连接
Docker可视化
什么是portainer?
Docker图形化界面管理工具!提供一个后台面板供我们操作!
# 运行如下命令即可 打开可视化服务 docker run -d -p 8080:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
9 - docker 镜像讲解
1)镜像是什么
镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
将所有的应用和环境,直接打包为docker镜像,就可以直接运行。
如何得到镜像:
- 从远程仓库下载
- 朋友拷贝给你
- 自己制作一个镜像 DockerFile
2)docker镜像的加载原理
①UnionFs(联合文件系统)
我们下载的时候看到一层层的下载就是这个。
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个
虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
②Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。
这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
③平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。
由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
3)分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载 。
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,
这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令
[root@VM-0-17-centos /]# docker inspect redis
4)关于镜像分层的理解
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,
就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的。
件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
特点:
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
10 - commit镜像(提交一个自己的镜像)
docker commit 提交容器成为一个新的副本 # 命令和git原理类似 docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
# 1、启动一个默认的tomcat docker run -d -p 8080:8080 tomcat # 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的! docker exec -it 容器id # 3、拷贝文件进去 cp webapps.dist/* webapps # 4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。 docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG] docker commit -a="赖正华" -m="add webapps app" 8e9e5e16bd84 tomcat02:1.0
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚拟机的快照。
入门成功!!!!