文章目录

  • Docker概述
    • Docker为什么会出现
    • Docker的历史
    • Docker为什么这么火(有什么优势)
    • Docker是什么
    • Docker能做什么
  • Docker的基本组成
    • Docker为什么比虚拟机快
  • Docker安装、卸载
    • 1、Centos7
      • 配置阿里云的容器镜像加速器
    • 回顾启动hello-world镜像的流程
  • Docker常用命令
    • 帮助命令
    • 镜像命令
      • docker images
      • docker search
      • docker pull
      • docker rmi
      • docker history
      • docker save/load
    • 容器命令
      • docker run
      • docker ps
      • docker rm
      • docker start/stop/restart/kill
      • docker exec
      • docker attach
    • 常用的其它命令
      • docker logs
      • docker top
      • docker inspect
      • docker cp
      • docker stats
    • docker命令小结
    • 作业
      • 练习1
  • 可视化
  • Docker镜像
    • 镜像是什么
    • Docker镜像的加载原理
      • UnionFS(联合文件系统)
      • Docker镜像加载原理
    • 分层理解
    • commit镜像
      • 练习

Docker概述

Docker为什么会出现

来看以下场景:

  • 如果在公司做过开发的童鞋就会知道,一个项目有开发/测试环境,和线上环境。而每套环境都需要部署应用环境,对应用进行配置。
  • 程序在开发环境可以使用,在线上环境不可用。又或者线上环境由于服务器操作系统其他组件的更新,导致该项目的服务不可用。这对于运维来说,考验很大。
  • 环境配置是十分麻烦的,每台机器都要部署环境(集群redis、ES、hadoop),费时费力。

之前在服务器上配置一个应用的环境(Redis MySQL ES JDK Hadoop),非常麻烦,而且环境是不跨平台的。比方说下面的场景:

传统:开发人员将项目打包成jar,然后将其交给运维来部署;
如今:开发+打包+部署,一套流程做完。

所以,能否发布一个项目(比如springboot fat jar + (Redis MySQL JDK ES Hadoop)),连同环境一起打包? Docker就是做这个事情的

java --> jar --> 打包项目且带上环境(docker镜像)–> Docker仓库 --> 下载我们发布的镜像 --> 直接运行即可!

技术的本质:所有的技术的出现都是因为有新问题需要解决。也因此我们才需要去学习。

Docker的历史

2010年,几个搞IT的年轻人,在美国成立了一家公司dotCloud
做一些PaaS的云计算服务,LXC的容器技术。
他们将自己的技术(容器化技术)命名就是Docker

Docker刚刚诞生的时候并没有引起行业的注意。所以为了让公司存活下去,于是把Docker开源了。
后来,越来越多的人发现了docker的优点,开始火了起来。Docker每个月都会更新一个版本。2014年4月9日,Docker 1.0发布。

Docker为什么这么火(有什么优势)

  • 很轻巧

容器出现前,普遍用的是虚拟机,比如常见的VMware。虚拟机很笨重。

  • 应用可以更快的交付和部署

传统方式:一堆帮助文档,安装程序;
docker:打包镜像,发布测试,一键运行。

  • 扩容和缩容更便捷

使用了docker之后,我们部署应用就像搭积木一样简单。

  • 更简单的系统运维

在容器化之后,我们的开发、测试环境都是高度一致的。

  • 更高效的计算资源利用

一个物理机上可以运行很多个容器实例。

Docker是什么

引用维基百科对Docker的介绍:

Docker是Go语言开发的开源项目。

官方文档:https://docs.docker.com 。文档很详细!
官方镜像仓库:https://hub.docker.com

Docker能做什么

  • 容器化技术与虚拟机技术的区别

容器化技术不是模拟一个完整的操作系统;
容器内的应用直接运行在宿主机上,容器是没有自己的内核的,也没有虚拟出硬件;
每个容器间相互隔离,每个容器内都有属于自己的一个文件系统。

Docker的基本组成


Docker是一个C/S架构的系统,Docker的守护进程运行在主机上。客户端通过socket去访问服务端。

Docker为什么比虚拟机快

1、Docker有着比虚拟机更少的抽象层
2、Docker使用的是宿主机的内核,而VM使用的是虚拟出来的Guest OS
因此,新建一个容器时,docker不需要像虚拟机一样重新加载一个操作系统内核,能够做到秒级的加载速度;而虚拟机是加载Guest OS,分钟级别的加载速度。

  • 镜像(image)

docker镜像就好比是一个模板,可以通过这个模板来创建容器服务。一个镜像可以创建多个容器(container)。

  • 容器(container)

Docker利用容器技术,独立运行一个或者一个组应用。
目前可以把这个容器理解为一个简易的Linux系统。

  • 仓库(repository)

用来存放镜像的地方。
仓库分为公有仓库和私有仓库。

Docker安装、卸载

从官方文档获取安装方法。

1、Centos7

1、先卸载旧版本的docker

$ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine

2、设置镜像的仓库

$ sudo yum install -y yum-utils
$ sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo    // 将上面官方的仓库改为国内的镜像仓库地址:
$ sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo// 更新yum源或者出现配置yum源之后,通常都会使用yum makecache 生成缓存,
// 这个命令是将软件包信息提前在本地缓存一份,用来提高搜索安装软件的速度。
$ sudo yum makecache fast// 如果觉得占用磁盘空间,可以使用yum clean指令清除缓存。
$ sudo yum clean all

3、安装docker引擎

// 直接安装最新版本
$ sudo yum install docker-ce docker-ce-cli containerd.io//查看可安装的docker版本
$ yum list docker-ce --showduplicates | sort -r
//安装指定版本的docker
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

4、启动docker服务

$ sudo systemctl start docker

使用docker version来判断是否安装成功:

或运行官方的hello-world镜像来验证。

$ sudo docker run hello-world

5、Docker的卸载

  • Step1:Uninstall the Docker Engine, CLI, and Containerd packages:
$ sudo yum remove docker-ce docker-ce-cli containerd.io
  • Step2:Images, containers, volumes, or customized configuration files on your host are not automatically removed. To delete all images, containers, and volumes:
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd

6、其实可以指定镜像、容器存放的位置
编辑/etc/docker/daemon.json文件即可(如果不存在该文件,则新建)。

配置阿里云的容器镜像加速器

同样是编辑 /etc/docker/daemon.json文件即可。

PS:每个阿里云用户的加速地址都不同的。上面这个我记得当时我是在网络上找的别人的加速地址。
另外,其实腾讯云也有这种加速服务的。

回顾启动hello-world镜像的流程


docker run命令的执行流程如下图:

Docker常用命令

官方参考文档:https://docs.docker.com/reference/

帮助命令

docker version             //显示版本信息
docker info                   //显示docker的系统信息,包括镜像和容器
docker <COMMAND> --help   //万能命令

镜像命令

docker images

查看所有本机的镜像

[root@VM-8-8-centos ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   6 months ago   13.3kB//解释
REPOSITORY          镜像在仓库中的名称
TAG                          镜像的标签
IMAGE ID                 镜像的id
CREATED                镜像的创建时间
SIZE                         镜像的大小 //可选项
Options:-a, --all             Show all images (default hides intermediate images)-q, --quiet           Only show image IDs

docker search

搜索镜像

[root@VM-8-8-centos ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11433     [OK]
mariadb                           MariaDB Server is a high performing open sou…   4341      [OK]
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   848                  [OK]
percona                           Percona Server is a fork of the MySQL relati…   554       [OK]
phpmyadmin                        phpMyAdmin - A web interface for MySQL and M…   324       [OK]
centos/mysql-57-centos7           MySQL 5.7 SQL database server                   91
mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   88
centurylink/mysql                 Image containing mysql. Optimized to be link…   59                   [OK]//可选项
Options:-f, --filter filter     //过滤出符合指定条件的结果//过滤出STARS>=3000的mysql镜像
[root@VM-8-8-centos ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   11433     [OK]
mariadb   MariaDB Server is a high performing open sou…   4341      [OK]

docker pull

拉取镜像
docker pull 镜像名[:tag]

[root@VM-8-8-centos ~]# docker pull mysql
Using default tag: latest     //如果不指定tag,默认就是lastest
latest: Pulling from library/mysql
a330b6cecb98: Pull complete       //分层下载, docker images 的核心
9c8f656c32b8: Pull complete
88e473c3f553: Pull complete
062463ea5d2f: Pull complete
daf7e3bdf4b6: Pull complete
1839c0b7aac9: Pull complete
cf0a0cfee6d0: Pull complete
1b42041bb11e: Pull complete
10459d86c7e6: Pull complete
b7199599d5f9: Pull complete
1d6f51e17d45: Pull complete
50e0789bacad: Pull complete
Digest:     sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c     //签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest       //真实地址,换言之:docker pull mysql 等价于 docker pull docker.io/library/mysql:latest

docker rmi

删除镜像

//删除单个容器
[root@VM-8-8-centos ~]# docker rmi -f <images id>//删除多个容器
[root@VM-8-8-centos ~]# docker rmi -f <images id1> <images id2> <images id3> ...//删除所有镜像
[root@VM-8-8-centos ~]# docker rmi -f $(docker images -aq)// 解释:
-f     表示强制删除
docker images -aq    得到所有的镜像ID

docker history

查看镜像的构建过程(即镜像的历史变更记录)

docker history <镜像ID>

docker save/load

docker save用于将镜像备份到一个tar包
docker load用于从指定tar包中还原镜像

[root@VM-8-8-centos ~]# docker save --helpUsage:  docker save [OPTIONS] IMAGE [IMAGE...]Save one or more images to a tar archive (streamed to STDOUT by default)Options:-o, --output string   Write to a file, instead of STDOUT[root@VM-8-8-centos ~]# docker load --helpUsage:  docker load [OPTIONS]Load an image from a tar archive or STDINOptions:-i, --input string   Read from tar archive file, instead of STDIN-q, --quiet          Suppress the load output

docker save备份镜像:

docker load还原镜像:

容器命令

先拉取容器,这里以centos:latest镜像为例。

docker run

启动指定容器

docker run [可选参数]  <image>常用的可选参数说明:
--name="container name"    //给容器起名字,用来区分容器
-d     //后台方式运行
-it      //使用交互式方式启动,可进入容器查看
-p      //指定端口,也可作主机和容器的端口映射。// e.g:    -p ip:主机端口:容器端口-p 主机端口:容器端口-p 容器端口
-P      //随机指定端口
--rm    //用完即删 Automatically remove the container when it exits

docker ps

列出容器

docker ps [可选参数]常用的可选参数说明:
-a     //列出所有的容器,如果不加该参数,则只显示运行中的容器
-n int   //列出最近创建的int个容器
-q      //只显示容器ID[root@VM-8-8-centos ~]# docker ps -n 1
CONTAINER ID   IMAGE             COMMAND       CREATED          STATUS          PORTS     NAMES
be3b2ad39f46   centos:7.6.1810   "/bin/bash"   10 seconds ago   Up 10 seconds             centos_7.6[root@VM-8-8-centos ~]# docker ps -n 2
CONTAINER ID   IMAGE             COMMAND       CREATED              STATUS              PORTS     NAMES
be3b2ad39f46   centos:7.6.1810   "/bin/bash"   13 seconds ago       Up 12 seconds                 centos_7.6
5ff746ad9c8a   centos:latest     "/bin/bash"   About a minute ago   Up About a minute             centos_8

docker rm

删除指定容器

docker rm <容器ID>            //删除指定容器,不能
docker rm -f $(docker ps -aq)    //删除所有容器
docker ps -aq |xargs docker rm   //也是删除所有容器

docker start/stop/restart/kill

启动、停止、重启和强制停止容器

docker start <容器id>       //启动容器
docker stop <容器id>       //停止容器
docker restart <容器id>    //重启容器
docker kill <容器id>          //强制停止容器

docker exec

在运行的容器中执行一条命令

可选命令:
Options:-d, --detach               Detached mode: run command in the background--detach-keys string   Override the key sequence for detaching a container-e, --env list             Set environment variables--env-file list        Read in a file of environment variables-i, --interactive          Keep STDIN open even if not attached--privileged           Give extended privileges to the command-t, --tty                  Allocate a pseudo-TTY-u, --user string          Username or UID (format: <name|uid>[:<group|gid>])-w, --workdir string       Working directory inside the container//示例
//  进入容器的交互式bash shell
$ sudo docker exec -it <容器id>  /bin/bash
//  以root用户进入容器的交互式bash shell
$ sudo docker exec -u 0 -it <容器id> /bin/bash

docker attach

进入正在运行的容器。
与docker exec -it <容器id> /bin/bash 的区别:不会进入一个新的shell,而是当前容器运行用的shell。

docker attach <容器id>

常用的其它命令

docker logs

查看日志

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:37Z) or relative(e.g. 42m for 42 minutes)-n, --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:37Z) or relative(e.g. 42m for 42 minutes)//示例:
[root@VM-8-8-centos ~]# docker logs -ft -n 1  centos_7.6
2021-09-20T01:39:07.127995518Z [root@be3b2ad39f46 /]#

docker top

查看容器中的进程信息

$ sudo docker top <容器id>
[root@VM-8-8-centos ~]# docker top be3b2ad39f46
UID         PID         PPID        C           STIME       TTY         TIME        CMD
root        4398        4379        0           Sep20       pts/0       00:00:00    /bin/bash

docker inspect

查看容器的元数据

$ sudo docker inspect <容器id>[root@VM-8-8-centos ~]# docker inspect 5ff746ad9c8a
[{"Id": "5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273","Created": "2021-09-20T01:35:08.558366371Z","Path": "/bin/bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 2939,"ExitCode": 0,"Error": "","StartedAt": "2021-09-20T01:35:08.791459407Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273/resolv.conf","HostnamePath": "/var/lib/docker/containers/5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273/hostname","HostsPath": "/var/lib/docker/containers/5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273/hosts","LogPath": "/var/lib/docker/containers/5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273/5ff746ad9c8a8e3642eb39e1d520003dbb7ac7141538484ddfa5d8cf83446273-json.log","Name": "/centos_8","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": ["196c4752f03e46c92a9f456c3c495a69653d8ef7221a603e6ffd71afd13459dc"],"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/d29ea0e0ca0e9ab291d52b3b53416a7f057b719c792256c216d418681ec30bf1-init/diff:/var/lib/docker/overlay2/24b5f032294785128522bd7e768bcc6d43829e8dc659ca2c49c70c94ace55d55/diff","MergedDir": "/var/lib/docker/overlay2/d29ea0e0ca0e9ab291d52b3b53416a7f057b719c792256c216d418681ec30bf1/merged","UpperDir": "/var/lib/docker/overlay2/d29ea0e0ca0e9ab291d52b3b53416a7f057b719c792256c216d418681ec30bf1/diff","WorkDir": "/var/lib/docker/overlay2/d29ea0e0ca0e9ab291d52b3b53416a7f057b719c792256c216d418681ec30bf1/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "5ff746ad9c8a","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": true,"OpenStdin": true,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "centos:latest","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20210915","org.label-schema.license": "GPLv2","org.label-schema.name": "CentOS Base Image","org.label-schema.schema-version": "1.0","org.label-schema.vendor": "CentOS"}},"NetworkSettings": {"Bridge": "","SandboxID": "7a2f54144ca594acbe782cbb3e88eb7459124bdad2276c9d5721a9881526ec1f","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/7a2f54144ca5","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "623ad66a1c64559d4149081b14b5408f54660e683daa5da5b1cc4f49cb824928","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "c3710726a487a0ce29f841cdbcc6eea5eda5a66e10fa85e8b6db3775ca8849d9","EndpointID": "623ad66a1c64559d4149081b14b5408f54660e683daa5da5b1cc4f49cb824928","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
]

docker cp

在容器和本地文件系统之间拷贝文件/目录

//从主机往容器里拷贝文件
docker cp bbb.txt be3b2ad39f46:/tmp///从容器往主机拷贝文件
docker cp be3b2ad39f46:/tmp/ks-script-6pKh_p  /root

PS: 后面我们可以使用 -v (容器数据卷的技术)来实现容器目录和主机目录的自动同步。

docker stats

查看容器的cpu、内存等使用状态

docker stats    //查看所有容器的cpu、内存等使用状态
docker stats <容器id>   //查看指定容器的cpu、内存等使用状态

docker命令小结

前面主要讨论了容器、镜像相关的一些命令,还有很多命令在后面一些知识点会讲到,比如跟远程仓库、Dockerfile相关的…

作业

练习1

部署elasticsearch + kibana

按照官方文档(https://hub.docker.com/_/elasticsearch)下载并启动elasticsearch:

[root@VM-8-8-centos ~]# docker run -itd --name elasticsearch_v7.6.2 -p 19200:9200 -p 19300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

由于ES启动后会占用大量内存,docker stats查看结果如下:

这对于1核CPU-2GB内存的云服务器来说(主要是穷o(╥﹏╥)o)负担较重。因此使用-e参数传入ES的环境变量ES_JAVA_OPTS来控制内存的使用量:

[root@VM-8-8-centos ~]# docker run -itd --name elasticsearch_v7.6.2 -p 19200:9200 -p 19300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m"  elasticsearch:7.6.2

这下ES的内存占用就变小了:

部署好ES后,部署kibana。

思考:如何使用kibana连接es?

可视化

  • Portainer
  • Rancher

Docker镜像

镜像是什么

镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,包括代码、运行时、库、环境变量和配置文件。

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

如何得到镜像?

  • 从远程仓库下载
  • 其他人拷贝给你
  • 自己制作一个镜像Dockfile

Docker镜像的加载原理

UnionFS(联合文件系统)

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

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

Docker镜像加载原理

docker镜像实际上是由一层一层的文件系统组成,这种层级的文件系统叫UnionFS。

bootfs(boot file system) 主要包含bootloader和kernel,bootloader主要是引导并加载kernel。Linux刚启动时会加载bootfs文件系统。在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含bootloader和kernel。当bootloader加载完kernel后,kernel就在内存中了。此时内存的使用权就由bootfs交由kernel。

而rootfs(root file system)在 bootfs之上,包含的就是Linux系统中的/dev/proc/bin/etc等标准目录和文件。rootfs就是各种不同的linux系统发行版,比如Ubuntu、OpenSUSE、CentOS等。

平时我们安装的到虚拟机的CentOS都是好几个G,为什么Docker里才200+M?

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了。因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。

分层理解

在通过docker pull下载镜像时,可以观察下载时的日志输出。可以看到是一层一层下载的,如下图:

所有的Docker镜像都是始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上,创建新的镜像层。

举一个简单的例子,例如基于Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已包含3个镜像层,如下图(这只是一个简单的例子):

在添加额外镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图又是一个简单的例子:每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

上图中的镜像层级跟之前图中的略有区别,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层的文件7是文件5个一个更新版本。

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和Copy on Write。

  • 特点
    Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是我们常说的容器层,容器层之下都叫镜像层。

commit镜像

docker commit     //提交当前容器,成为一个新的副本docker commit -m="提交的描述信息" -a="作者" <容器id>  目标镜像名:[TAG]

练习

启动一个官方的tomcat容器。发现这个tomcat容器的/usr/local/tomcat/webapps 目录是空的。往该目录拷贝文件后,再提交镜像。

[root@VM-8-8-centos ~]# docker commit -m "copy webapps.dist to webapps" -a "cloud-hacker" 1466e04bc744 tomcat9:v1.0
sha256:c5673696fcfadd7a7dffc41bf7959295116dd1fbeb17e679aff63d6ad7d82cc6
[root@VM-8-8-centos ~]#

commit后,docker images查看本地镜像便能看到它。

综上,如果想要保存当前容器状态,就可以通过docker commit来提交获得一个镜像。
这就类似于虚拟机的快照。
学到这里,才算是入门了Docker!

学习方式说明:
理解概念(一开始可以不需要理解有多深入,可以模棱两可),然后一定要实践,最后实践+理论相结合一次搞定这个知识!

Docker学习笔记-入门篇相关推荐

  1. Vue学习笔记入门篇——数据及DOM

    本文为转载,原文:Vue学习笔记入门篇--数据及DOM 数据 data 类型 Object | Function 详细 Vue 实例的数据对象.Vue 将会递归将 data 的属性转换为 getter ...

  2. C# 学习笔记入门篇(上)

    文章目录 C# 学习笔记入门篇 〇.写在前面 Hello World! 这篇学习笔记适合什么人 这篇学习笔记到底想记什么 附加说明 一.命名空间 "进入"命名空间 嵌套的命名空间. ...

  3. R语言学习笔记——入门篇:第一章-R语言介绍

    R语言 R语言学习笔记--入门篇:第一章-R语言介绍 文章目录 R语言 一.R语言简介 1.1.R语言的应用方向 1.2.R语言的特点 二.R软件的安装 2.1.Windows/Mac 2.2.Lin ...

  4. R语言学习笔记——入门篇:第三章-图形初阶

    R语言 R语言学习笔记--入门篇:第三章-图形初阶 文章目录 R语言 一.使用图形 1.1.基础绘图函数:plot( ) 1.2.图形控制函数:dev( ) 补充--直方图函数:hist( ) 补充- ...

  5. 易语言学习笔记——入门篇

    易语言学习笔记20180709 最早接触易语言是三年前的事情了,那时候是因为DNF这个游戏我才知道了易语言这个编程语言,当时对他就非常的憧憬.只不过那时候易语言的学习资源比较少,而且自身的学业比较重就 ...

  6. zabbix学习笔记——入门篇

    目录 一.了解监控 监控的种类 二.zabbix监控 1.介绍zabbix 2.为什么选择zabbix 3.Zabbix可监控对象 4.zabbix监控方式 1.被动监控 2.主动监控 5.zabbi ...

  7. JavaScript学习笔记 - 入门篇(1)- 准备

    为什么学习JavaScript 一.你知道,为什么JavaScript非常值得我们学习吗? 所有主流浏览器都支持JavaScript. 目前,全世界大部分网页都使用JavaScript. 它可以让网页 ...

  8. GeneXus学习笔记——入门篇

    使用GeneXus做开发做了有一段时间了 却发现一个问题(O_O)?就是除了相关的Wiki外 网上其他地方的相关资料都很少 于是乎我就想在这记录一些东西 来帮助以后会用到的人(°ー°") 那 ...

  9. android学习笔记(入门篇)

    +号只是当你第一次定义一个资源ID的时候需要, 告诉SDK此资源ID需要被创建出来 对于所有的View默认的权重是0,如果你只设置了一个View的权重大于0,那么这个View将占据除去别的View本身 ...

最新文章

  1. 怎么在css中加横线分层,CSS分层
  2. Linux Kernel 3.10内核源码分析--块设备层request plug/unplug机制
  3. 一天学完spark的Scala基础语法教程九、迭代器(idea版本)
  4. Unity 8 和 Snap 将会是 Ubuntu 的未来
  5. Jq将字符串复制粘贴到剪贴板
  6. Spark源码分析:多种部署方式之间的区别与联系
  7. 生成jni的android.mk,Android Studio 3.5版本JNI生成SO文件详解
  8. 打破网络沉闷---QQ强制聊天工具再度现身!
  9. 【CS论坛】维护网络安全的四块基石
  10. 第七章_生成对抗网络(GAN)
  11. Android签名验证与反调试机制的对抗技术
  12. 教你写Makefile
  13. 删除flash助手推荐广告
  14. Python3.x 标准模块库目录(下篇)
  15. 3-D Quasi-Recurrent Neural Network for Hyperspectral Image Denoising
  16. 【系统集成项目管理】之项目质量管理
  17. 最快的计算机操作,世界十大最快的超级计算机
  18. 异构计算, GPU和框架选型指南
  19. Python基础与拾遗2:Python中的字符串与字符串格式化
  20. 初学Java时使用记事本开发出现的中文乱码问题

热门文章

  1. 【考研高数-高等数学-基础】第三章 微分中值定理及导数应用
  2. 通讯异常判断之心跳信号编程应用
  3. 前端 Excel文件导入
  4. 栈与队列实现以及相互转化
  5. Nacos是两种模式CP与AP Nocos服务注册和配置中心
  6. 1000个jquery极品插件
  7. AttentionNet 详解
  8. 【跨境电商】独立站运营需要面临哪些困难?(二)
  9. 深入SecureFile—新一代LOB揭秘
  10. onbeforepaste事件用法 onkeyup