1.帮助命令:
sudo docker version #查看docker版本
sudo docker info #查看docker信息
sudo docker --help #查看docker详细信息
2.镜像命令:
sudo docker images #列出本地主机上的镜像
REPOSITORY:仓库源 TAG:镜像标签 IMAGE ID:镜像ID CREATED:镜像创建时间 SIZE:镜像大小
sudo docker images -a #列出本地所有的镜像
sudo docker images -q #当前镜像的ID
sudo docker images --digest #显示摘要信息(备注)
sudo docker images --no-trunc #显示完整镜像信息
2.1 sudo docker search +某个**镜像的名字,例如:
sudo docker search ubuntu #搜索ubuntu镜像
sudo docker search ubuntu -s 30 #列出超过30颗星的ubuntu
sudo docker pull +某个镜像的名字 ,下载镜像,例如:
sudo docker pull tomcat #下载tomcat镜像,等价于docker pull tomcat:latest,如若需要其他版本,需要添加自己的版本号
2.2 删除镜像:sudo docker rmi +某个镜像名字的ID
sudo docker rmi hello-world #等价于sudo docker rmi hello-world:latest
sudo docker rmi -f hello-world #强制删除镜像
sudo docker rmi -f hello-world nginx #强制删除多个镜像,中间以空格隔开
sudo docker rmi -f $(docker images -qa) #删除全部镜像
3.容器命令:
3.1 新建并启动容器
sudo run [OPTIONS] IMAGE [COMMAND] [ARGS ...] #新建并启动容器
OPTIONS说明(常用):有些是一个减号,有些是两个减号
- -name = “容器新名字” :为容器指定一个名称
- i :以交互模式运行容器,通常与-t同时使用 ,-it
- t:为容器重新分配一个伪输入终端,通常与-i同时使用
- -P:随机端口映射
- p: 指定端口映射,有以下四种格式:
ip:hostPort:containerPort
ip::containerPrt
hostPort:containerPort
containerPort
例如:
sudo docker run -it ubuntu:18.04 #新建一个Ubuntu18.04容器 并启动,容器号系统随机生成,例:root@d6937c3ce15d:/#
sudo docker run -it --name myUbuntu ubuntu:18.04 #新建一个Ubuntu18.04容器 ,取别名myUbuntu ,并启动
sudo docker run -it -p 8888:8080 tomcat #docker端口8888映射tomcat端口8080 p 指定端口
sudo docker run -it -P tomcat # dockerP随机生成端口 映射 tomcat 端口8080
3.2 列出当前所有正在运行的容器
sudo docker ps [OPTIONS]
[OPTIONS]说明(常用)
-a :列出当前所以有正在运行的容器+历史上运行过的容器
-I: 显示最近创建的容器
-n: 显示最近创建的n个容器
-q:静默模式,只显示容器的编号
- -no-trunc : 不截断输出
3.3 停止 启动 退出 删除容器
exit #容器停止退出
ctrl + P + Q (组合键) :容器不停止退出
启动容器: sudo docker start +容器ID 或容器名
停止容器: sudo docker stop +容器ID 或容器名
强制停止: sudo docker kill + 容器ID或容器名
删除已停止的容器: sudo docker rm + 容器ID或者容器名 (注意:rmi是删除镜像)
一次性删除多个容器:sudo docker rm -f $(sudo docker ps -a -q)
或者:sudo docker ps -a -q | sudo xargs docker rm
3.4 重要
3.4.1 启动守护式容器
sudo docker run -d + 容器名,例如:
sudo docker run -d ubuntu:18.04
3.4.2 查看容器日志
sudo socker logs -f -t --tail +容器ID
-t : 是加入时间戳
-f : 跟随最新的容器打印
- -tail数字 显示最后多少条
3.4.3 查看容器内运行的进程
sudo docker top + 容器ID
3.4.4 查看容器内部细节
sudo docker inspect + 容器ID
3.4.5 进入正在运行的容器并以命令行交互
sudo docker exec -it + 容器ID bashShell
重新进入 sudo docker attach + 容器ID
上述两个区别:attach: 直接进入容器启动命令行终端,不会启动新的进程
exec : 是在容器中打开新的终端,并且可以启动新的进程 (可以在外面执行)
3.4.6 从容器内拷贝文件到主机上
sudo docker cp 容器ID : 容器内容路径 目的主机路径
4.Docker 镜像原理
4.1 Docker 镜像:
(1)UnionFS(联合文件系统):
Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several director into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特征:一次同时加载多个文件系统,但从外面看来,只能看到一个文件系统,联合加载会把各文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
(2)Docker镜像加载原理:
docker的镜像实际上由一层层的文件系统组成,这种层级文件系统是UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们的典型的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发行版,bootfs基本是一致,rootfs会有差别,因此不同的发行版可以公用bootfs。
(3)分层的镜像
例如:sudo docker pull hello-world,一层层在下载(基于联合文件系统分层原理)
为什么Docker镜像要采用这种分层结构?
最大的好处就是-共享资源。比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
(4)特点:Docker镜像都只是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
(5)Docker镜像commit操作补充
docker commit 提交容器副本使之成为一个新的镜像
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 容器ID要创建的目标镜像名:[标签名]
例如:将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明信息。
sudo docker commit -a "runoob.com" -m "my apache" a404c6c174a2 mymysql:v1
5.Docker 容器数据卷
5.1 是什么
Docker的理念:将应用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的。
容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit 生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。
为了能保存数据在docker中,我们使用卷。
5.2 能干嘛
容器的持久化
容器间继 承+共享数据 (容器到主机,数据到容器)
5.3 数据卷
(1)直接命令添加
sudo docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
例如:
宿主机上打开一个终端,输入:
sudo docker run -it -v /myDataVolume:/dataVolumeContainer ubuntu:18.04 # 宿主机中会产生一个myDataVolume文件夹 docker 容器中也有一个dataVolumeContainer文件夹
在宿主机上的myDataVolume文件夹中创建一个文件,并输入:host保存退出
sudo gedit host.txt
会发现 宿主机和容器中都会有一个host.txt
打开容器中的host.txt
此时在容器中的host.txt中写入:container 保存并退出。在宿主机上的myDataVolume文件夹中打开host.txt ,发现:
说明此时在容器中和宿主机中可以数据共享
当容器退出后,在宿主机上的myDataVolume文件夹的host.txt中重新编辑任何字符 ,再重新打开刚才关闭的容器会发现,打开容器中的host.txt 出现了 刚才在宿主机上编辑的字符。说明容器停止后,主机修改的数据与容器同步
-------------
命令(带权限)
sudo docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 #ro : read only 只能读
例如:
sudo docker run -it -v /myDataVolume:/dataVolumeContainer:ro ubuntu:18.04
在docker容器中创建了一个只读的dataVolumeContainer文件夹,不能向里面的文件进行写操作,也不能在文件夹中添加任何新的文件,只能查看。只能通过主机向其中写操作
(2)DockerFile添加
1.根目录下新建myDocker文件夹并进入
2.可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷
VOLUME["/dataVolumeContainer2","/dataVolumeContainer3"]
说明:出于可移植和分享的考虑,用-v 主机目录:容器目录 这种方法不能够直接在DockerFile中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定的目录。
3.File构建:
例:新建Dockerfile:sudo gedit Dockerfile 输入如下:
#volume test
FROM ubuntu:18.04
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,------success1"
CMD /bin/bash
4.build后生成镜像
sudo docker build -f /myDocker/Dockerfile -t wjy/myubuntu . #在/myDocker文件夹中使用Dockerfile 创建一个标签为wjy/myubuntu的镜像
sudo docker imags
5.新建并启动容器
sudo docker run -it wjy/myubuntu
进入容器中的dataVolumeContainer1文件夹,并新建testcontainer
cd dataVolumeContainer1
mkdir testContainer
在主机上重新打开一个终端输入
sudo docker images
sudo docker inspect c70c75945f2e
可以发现根据上述第一个箭头所指的路径,可以找到我们在容器中新建的文件夹,在主机上也有一个相同的。
5.4 数据卷容器
- 是什么:命名的容器挂在数据卷,其他容器通过挂在这个(父容器)实现数据共享,挂在数据卷的容器,称之为数据卷容器。(活动硬盘上挂活动硬盘,实现数据的传递依赖)
- 容器间传递共享(- -volumes-from)
(1)先启动一个父容器dc01,进入dataVolumeContainer2,在里面新建一个dc01_dir文件夹。(里面会有dataVolumeContainer1、dataVolumeContainer2两个文件夹,因为它是基于上面wjy/myubuntu镜像创建的)
sudo docker run -it --name dc01 wjy/myubuntu
cd dataVolumeContainer2
mkdir dc01_dir
然后ctrl + P +Q 不停止退出 dc01容器
创建一个dc02 继承于dc01,并在dataVolumeContainer2中新建一个dc02_dir文件夹
sudo docker run -it --name dc02 --volumes-from dc01 wjy/myubuntu
cd dataVolumeContainer2
mkdir dc02_dir
会发现里面会有一个上面建立的dc01_dir文件夹,和刚才新建的dc02_dir文件夹
然后ctrl + P +Q 不停止退出 dc02容器
创建一个dc03 继承于dc01,并在dataVolumeContainer2中新建一个dc03_dir文件夹
sudo docker run -it --name dc03 --volumes-from dc01 wjy/myubuntu
cd dataVolumeContainer2
mkdir dc03_dir
会发现里面会有前两次建立的dc01_dir,dc02_dir文件夹,和刚才新建的dc03_dir文件夹
sudo docker ps #下面建立的三个容器dc01、dc02、dc03
dc02 和dc03都继承于dc01,重新进入dc02和dc01 会发现 都会有刚才新建的三个文件夹
下面将dc01容器删掉会发现 dc02 和dc03中依然会有创建的三个文件夹。其实将其中的任意一个或两个容器删掉,都不会对剩下的容器中的三个文件夹的存在有影响(图就不贴了,理解就好)
-------
结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。