1 Docker底层原理
1.1 Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过socket从客户端访问。
Docker-Server接收到Docker-Client的指令,就会执行这个命令。

1.2 Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层!
- Docker利用的是宿主机的内核,VM利用的是Guest OS

所以说,新建一个容器的时候,docker不需要像虚拟机一样,重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的;而docker是利用宿主机的操作系统,省略了这个复杂的过程,是秒级的。

2 Docker常用命令
2.1 帮助命令
docker version 显示docker的版本
docker info 查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help 帮助命令
命令的帮助文档
https://docs.docker.com/reference/
2.2 镜像命令
docker images 查看本地主机上的所有镜像:
[root@zlk ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a , --all 列出所有镜像
-q, --quiet 只显示镜像的id
docker search 搜索镜像:
[root@zlk ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation... 12635 [OK]
# 可选项,通过搜索来过滤
--filter=STARS=5000 搜索出来的镜像,STARS大于5000
[root@zlk ~]# docker search redis --filter=STARS=5000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
redis Redis is an open source key-value store that... 10937 [OK]
docker pull 下载镜像:
[root@zlk ~]# docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
# 下载镜像 docker pull 镜像名[:tag]
[root@zlk ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认是latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete #分层下载,docker image的核心 联合文件系统
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c666666666666666f7738b66666666709
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
docker pull mysql
# 等价于
docker pull docker.io/library/mysql:latest
# 指定版本下载
docker pull mysql:5.7

docker rmi 删除镜像:
docker rmi -f 镜像ID # 删除指定镜像
docker rmi -f 镜像ID 镜像ID 镜像ID 删除指定的多个镜像
docker rmi -f $(docker images -aq) 删除全部镜像
2.3 容器命令
注意:有了镜像才可以创建容器。(以mysql镜像为例)
docker run [可选参数] image 新建容器并启动:
常用参数说明:
--name="name" 容器名字 Tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-P 指定容器的端口, -P 8080:8080
-P 主机端口:容器端口
# 测试,启动并进入容器
[root@zlk ~]# docker run -it mysql /bin/bash
[root@6ae3c9bb6a51 /]# ls # 查看容器内的mysql,基础版本,很多命令都是不完整的
bin boot dev docker-entrypoint-initdb.d entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# 从容器中退回主机
[root@6ae3c9bb6a51 /]# exit
exit
[root@zlk /]# ls
bin data etc lib media mydata proc run srv tmp var
boot dev home lib64 mnt opt root sbin sys usr
docker ps [可选参数] 列出所有运行的容器:
# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器 + 带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号

退出正在运行的容器:
exit # 直接容器停止并退出
ctrl+p+q # 容器不停止退出,docker ps 可以查看到
docker rm 删除容器:
docker rm 容器id 删除指定容器,不能删除正在运行的容器,如果强制删除,rm -f
docker rm -f $(docker ps -aq) 删除所有容器
[root@zlk /]# docker ps -a #查看所有容器
[root@zlk /]# docker rm 2bc63e25611d # 不能删除正在运行的容器
Error response from daemon: You cannot remove a running container 2bc63e25611dea862ad877730bc87b2dc9ee7bcb5bfb50dc604dc146700f1b41. Stop the container before attempting removal or force remove
[root@zlk /]# docker rm 6ae3c9bb6a51 #删除一个停止运行的容器
6ae3c9bb6a51
[root@zlk /]# docker ps -aq #查看所有容器的id
[root@zlk /]# docker rm -f $(docker ps -aq) #删除所有容器
启动和停止已有容器的操作:
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前的容器
[root@zlk /]# docker run -it centos /bin/bash
[root@990384ccba9f /]# exit
exit
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@zlk /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
990384ccba9f centos "/bin/bash" 25 seconds ago Exited (0) 18 seconds ago funny_elgamal
[root@zlk /]# docker start 990384ccba9f
990384ccba9f
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
990384ccba9f centos "/bin/bash" About a minute ago Up 7 seconds funny_elgamal
[root@zlk /]# docker stop 990384ccba9f
990384ccba9f
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2.4 常用其他命令
后台启动容器:
[root@zlk ~]# docker run -d centos
# 问题:docker ps 发现,centos停止了
# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

docker logs -tf --tail 容器id (查看日志):
# 自己编写一段shell脚本
[root@zlk /]# docker run -d centos /bin/bash -c "while true;do echo hello;sleep 2;done"
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e705ce9ef994 centos "/bin/sh -c 'while t..." About a minute ago Up About a minute priceless_lichterman
# 显示日志
--tf 显示日志
--tail number 要显示日志条数
[root@zlk /]# docker logs -tf --tail 10 e705ce9ef994
docker top 容器id (查看容器中进程信息):
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e705ce9ef994 centos "/bin/sh -c 'while t..." 8 minutes ago Up 8 minutes priceless_lichterman
[root@zlk /]# docker top e705ce9ef994
UID PID PPID C STIME TTY TIME CMD
root 5624 27182 0 17:50 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
root 27182 27163 0 17:41 ? 00:00:00 /bin/sh -c while true;do echo hello;sleep 2;done
docker inspect 容器id(查看镜像的元数据)
# 测试
[root@zlk /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c92de96ff9f centos "/bin/bash -c 'while..." 13 minutes ago Up 13 minutes agitated_robinson
[root@zlk /]# docker inspect 1c92de96ff9f

进入当前正在运行的容器:
容器都是使用后台方式运行的,需要进入容器,修改一些配置。
docker exec -it 容器id /bin/bash
[root@zlk /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e705ce9ef994 centos "/bin/sh -c 'while t..." 21 minutes ago Up 21 minutes priceless_lichterman
# 方式一
[root@zlk /]# docker exec -it e705ce9ef994 /bin/bash
[root@e705ce9ef994 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 方式二
docker attach 容器id
# 测试
[root@zlk /]# docker attach e705ce9ef994
正在执行当前代码.......
[root@zlk ~]# docker rm -f $(docker ps -aq) # 前面循环没停,直接全停了
docker exec # 进入容器后开启一个新的终端,可以在里面执行操作
docker attach # 进入容器正在执行的终端,不会启动新的进程,且执行过程中不能退出
从容器内拷贝文件到主机上:
docker cp 容器id:容器内路径 主机路径
这里的拷贝采用的是手动操作,在后面我们将进一步学习使用 -v 操作,也就是卷的技术,可以实现自动同步。
[root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@kzlk ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 8 months ago 231MB
[root@zlk ~]# docker run -it centos /bin/bash # ctrl+p+q退出
[root@93823941b78c /]# [root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93823941b78c centos "/bin/bash" 16 seconds ago Up 15 seconds romantic_sinoussi
[root@zlk ~]# cd /home/
[root@zlk home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93823941b78c centos "/bin/bash" About a minute ago Up About a minute romantic_sinoussi
# 进入容器内部
[root@zlk home]# docker attach 93823941b78c
[root@93823941b78c /]# cd /home/
[root@93823941b78c home]# ls
# 在容器内新建一个文件
[root@93823941b78c home]# touch test.java
[root@93823941b78c home]# ls
test.java
[root@93823941b78c home]# exit
exit
[root@zlk home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@zlk home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93823941b78c centos "/bin/bash" 3 minutes ago Exited (0) 7 seconds ago romantic_sinoussi
# 查看当前主机目录
[root@zlk home]# ls
admin ceshi kuangshen.java
# 将文件拷贝到主机上
[root@zlk home]# docker cp 93823941b78c:/home/test.java /home/
[root@zlk home]# ls
admin ceshi kuangshen.java test.java
2.5 小结

docker 的命令非常多,下述是最常用的容器和镜像的命令,之后学习的命令会更多!
attach Attach to a running Container # 当前 shell下 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 filesystem # 查看 docker 容器变化
events Get real time events form the server # 从 docker 服务获取容器实时事件
exec Run a command in an existing container # 在已存在的容器上运行命令
export Stream the containers 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 tarball # 从 tar 包中的内容创建一个新的文件系统映像【对应 export】
info display system-wide infomation # 显示系统相关信息
inspect return low-level infomation on a container # 查看容器详细信息
kill kill 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 logs of a container # 输出当前容器日志信息
port lookup the public-facing port which is NAT-ed to PRIVATE_PORT # 查看映射端口对应的容器内部源端口
pause pause all 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 images # 移除一个或者多个镜像(无容器使用该镜像才可以删除,否则需删除相关容器才可继续或 -f 强制删除)
run run a command in a new container # 创建一个新的容器并运行一个命令
save save an image to a tar archive # 保存一个镜像为一个tar包【对应 load】
search search for an image on the docker hub # 在 docker hub 中搜索镜像
start start a stopped container # 启动容器
stop stop a running container # 启动容器
tag tag an image into a repository # 给源镜像搭标签
top lookup the running processes of a container # 查看容器中运行的进程信息
unpause unpause a paused container # 取消暂停容器
version show the docker version infomation # 查看 docker 版本号
wait block until a container stops,then print its exit code # 截取容器停止时间的退出状态值
2.6 作业练习----Docker 安装 Nginx
# 1、搜索镜像 search 建议去docker上搜索,可以看到详细信息和帮助文档
[root@zlk ~]# docker search nginx
# 2、下载镜像
[root@zlk ~]# docker pull nginx
# 3、运行测试
[root@zlk ~]# docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest de1111b9436b 36 hours ago 142MB
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
[root@zlk ~]# docker run -d --name nginx01 -p 3344:80 nginx
50666666ad4e9e6b9666666666c8ec08666666633
[root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50c35333a98 nginx "/docker-entrypoint...." 57 seconds ago Up 57 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@zlk ~]# curl localhost:3344
# 浏览器查看 http://IP:3344/
# 进入容器
[root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
506666e98 nginx "/docker-entrypoint...." 38 minutes ago Up 38 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@zlk ~]# docker exec -it nginx01 /bin/bash
root@506666e98:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@5066666e98:/# cd /etc/nginx/
root@5066666e98:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
root@5066666e98:/etc/nginx#
# 停止容器
root@503666w98:/etc/nginx# exit
exit
[root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
506666e98 nginx "/docker-entrypoint...." 43 minutes ago Up 43 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@zlk ~]# docker stop 5066666e98
506666e98
# 浏览器查看 http://IP:3344/
2.7 作业练习----docker安装Tomcat
# 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台 -d,停止了容器之后,容器还是可以通过docker ps查到 ,官方推荐的docker run -it --rm tomcat:9.0,一般用来测试,用完就删除
# 下载再启动
docker pull tomcat
# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat
# 测试访问没有问题,会出现404
# IP:3355 访问失败
# 进入容器
docker exec -it tomcat01 /bin/bash
ls
# 发现问题:1、Linux命令缺失 2、没有WebApps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除,保证最小可运行的环境
[root@zlk ~]# docker exec -it tomcat01 /bin/bash
root@c95eb14e8fd4:/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@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
root@c95eb14e8fd4:/usr/local/tomcat/webapps# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps.dist/
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
思考:每次部署项目,都要进入容器内,特别麻烦,所以在容器外部提供一个映射路径,webapps
2.8 作业练习----docker部署es+kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录! 挂载
# --net somenetwork 网络配置
# 启动elasticsearch
[root@zlk home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
# 启动了linux就卡主了,docker stats 查看cpu状态
# 测试一下es成功了
[root@zlk home]# curl localhost:9200
{
"name" : "a920894a940b",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ",
"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"
}
# 增加内存限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
2.9 端口暴露概念

2.10 可视化
- portainer(先用这个):图形化界面管理工具,提供一个后台面板供我们操作。
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 测试
[root@zlk home]# curl localhost:8088
<!DOCTYPE html
><html lang="en" ng-app="portainer">
# 外网访问 http://ip:8088
3 Docker镜像
3.1 镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
也就是说,我们所有的应用都能够直接打包成Docker镜像,然后就可以运行!
3.2 UnionFS(联合文件系统)【Docker核心组件】
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统。对于Docker来说,它是Docker镜像和容器的基础,因为它可以将Docker镜像做成分层次的结构,从而使得镜像的每一层可以被共享,通过分层达到继承的目的,后面我们会学习到基于基础镜像制作出各种具体的应用镜像(DockerFile)
通俗的来讲,就是我们在docker pull下载镜像的时候会分层下载,已经存在的部分进行共享,只下载当前没有的那一部分,这样会极大地节省内存空间。
3.3 Docker镜像加载原理
Docker的镜像实际根据联合文件系统由一层一层的文件系统组成。
Linux 文件系统结构:
Linux 文件系统由 bootfs 和 rootfs 两部分组成。

(1)bootfs(boot file system):主要包含bootloader和kernel(Linux内核),bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,而在Docker镜像的最底层也是bootfs这一层,这与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后,整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时后 bootfs 就被 umount (卸载)了。
(2)rootfs(root file system):rootfs在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等。
docker镜像加载原理:
Docker的镜像层都是只读的,只有容器层是可写的,容器层就是最上面的一层。
平时我们安装进虚拟机的CentOS系统都是好几个G,为什么Docker这里安装的才200M?

对于一个精简的OS系统,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的kernel(也就是宿主机或者服务器的boosfs+内核),自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs部分。
这样的话也就可以解释之前我们所说的,虚拟机启动是分钟级别的,而容器是秒级的!
3.4 分层镜像

镜像都是从相同的base镜像构建的,宿主机只需要在磁盘上保留一份Base镜像,同时内存中也只需要加载一份Base镜像,这样我们就能够在所有的镜像容器中进行公用。
docker image inspect 镜像名: 可以查看镜像元数据。

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层Ubuntu16.04之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层.....依次累加。如下图所示(当前有3个镜像层)。

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

下图中演示了一个稍微复杂的3层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。(文件7会覆盖文件5)
在这种情况下,上层镜像层中的文件7覆盖了底层镜像层中的文件5。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中,镜像层数+1,整体文件数不变。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
上述三层镜像,Docker最终会将其堆叠并合并,对外提供统一的视图,如下图所示:

4 Docker原理
Docker镜像都是只读的,在我们启动容器的时候,一个新的可写层被加载到镜像的顶部!
这一层就是我们常说的容器层(run),容器层之下的都是镜像层(远程 pull)!所有的操作都是基于容器层。

5 Commit镜像
docker commit 提交容器成为一个新的副本
# 命令和Git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名.[tag]
**用途:**如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照。这样的话可以节省掉很多的步骤,直接拿过来用即可!
实战提交一个镜像:
- 启动一个默认的tomcat
- 发现这个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps 下面是没有文件的
- 自己拷贝进去了基本的文件
- 将修改后的容器通过commit提交为一个镜像,我们以后使用修改后的镜像即可,这就是修改后的镜像
#运行一个默认的tomcat镜像
[root@zlk ~]# docker run -it -p 8080:8080 tomcat
[root@zlk ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
792ca37197e8 tomcat "catalina.sh run" 34 seconds ago Up 32 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp upbeat_mcnulty
[root@zlk ~]# docker exec -it 792ca37197e8 /bin/bash
#发现这个默认的tomcat 是没有webapps应用,是因为镜像的原因,官方的镜像默认webapps下没有文件,自己拷贝进去基本的文件
root@792ca37197e8:/usr/local/tomcat# cp -r webapps.dist/* webapps
#浏览器访问,测试成功
http://47.105.220.36:8080/
#提交修改后的容器成为一个新的镜像
[root@zlk ~]# docker commit -a="星悦糖" -m="add webapps app" 792ca37197e8 tomcat02:1.0
sha256:d6d429f9d2ba25af8f66bd3e7a7de489cf2219828ea755ce1d0a1a7816c27731
[root@zlk ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 d6d429f9d2ba 28 seconds ago 672MB
到现在为止我们的Docker才算入门!接下来我们进一步学习Docker进阶!
原文链接: https://blog.csdn.net/friggly/article/details/126163263