docker基础命令&镜像原理
原创者:文思
一、阿里云镜像加速配置
镜像放在github上,但由于一些原因,访问国外站点很慢,好在有阿里。
https://dev.aliyun.com/search.html
注册一个阿里云帐户,登陆开发者中心,获取加速器地址
二、Hello-World
1、开启服务并运行hello-world:
Unable tofind image 'hello-world:latest' locally
latest:Pulling from hello-world
表示第一次没有从本地获取hello-world镜像,准备从GitHub上拉取一个hello-world镜像并在容器内运行。
b6d845cb453c:Pull complete
3535063d9957:Pull complete
Digest:sha256:135a30bd414bd8d23e386763e36f3dc4ee8ed25d2d6068082c0af796513d9d0d
Status: Downloadednewer image for hello-world:latest
拉取成功。
2、运行原理
Docker是一个cs结构的系统,Docker守护进行运行在主机上,然后通过Socket连接从客户端访问。
比较两图的差异,左图虚拟机的Guest OS层和Hypervisor层在docker中被Docker Engine层所替代。
(1)docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有优势。
(2)docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。我们知道,引导、加载操作系统内核是一个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
3、Docker帮助命令
docker version
docker info
docker –help
三、常用命令
根据图表可以理解为,鲸鱼=docker,集装箱=容器实例
1、镜像命令
docker images:列出本地主机上的镜像
可用参数-a -q -qa
REPOSITORY:表示镜像的仓库源
TAG:镜像标签
IMAGEID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一个仓库源可以有多个TAG,代表这个仓库源的不同版本,我们使用REPOSITORY:TAG来定义不同的镜像。如果不指定镜像的版本标签,将默认使用latest。
docker serarch:查找docker上镜像
运行命令docker search tomcat:
图中的stars代表的点赞数,当然点赞越多越受欢迎
docker search –s 30 tomcat:找点赞数超过30的tomcat
docker pull镜像名[:TAG]:拉取镜像,TAG可不写,默认拉最新的latest
可以看到已经把tomcat拉取到本地了。
docker rmi镜像名:删除本地镜像
docker rmi hello-world:因为hello-world镜像在被使用,所以无法删除。
使用-f参数强制删除,docker rmi –f hello-world可以看到已强制删除:
删除多个镜像,镜像之间用空格:docker rmi –f镜像1 镜像2
删除全部镜像:docker rmi -f $(docker images -qa)
2、容器命令
docker pull
centos 提前拉取centos镜像做演示用。
docker run [OPTIONS] IMAGE [COMMAND][ARG…]:docker的主流命令之一,新建并启动容器。
OPTIONS说明(常用):有些是一个减号,有些是两个减号
--name=”容器新名字”:为容器指定一个名称
-d:后台运行容器,并返回容器ID,即启动守护线程式容器
-i:以交互模式运行容器,通常与-t同时使用。
-t:为容器重新分配一个伪输入终端。
上图表示以88ec626ba223为模板生成了一个cae36ac3a0a4这样的容器。
ll命令可以看到这是一个标准的centos:
关闭并退出容器:exit
或者Ctrl+p+q只退出但并不关闭容器
docker ps [OPTIONS]列出当前正在运行的容器
docker start 容器名:启动容器
docker stop 容器名:停止容器
docker kill 容器名:强制停止容器:
docker rm ID[name]:删除已关闭的容器,加-f强制删除
还记的删除全部镜像的命令吗,举一反三,删除全部容器:
docker rm –f ${docker ps -a -q}
重要内容:重要内容:重要内容:
很重要的一点说明:docker容器后台运行,就必须有一个前台进程。
容器运行的命令如果不是那些一直挂起的命令(比如top,tail),就会自动退出。
可以看到启动后就立刻退出了。
这是docker的机制问题,比如web容器ngix为例,正常情况下配置启动服务service ngix start,ngix作为后台进行模式运行,这样导致docker前台没有运行的应用,docker认为没有前端交互,觉得没什么事可做,所以就自动关闭了。
所以最佳解决方案是将要运行的程序以前台进程的形式运行:docker run –d centos /bin/sh –c “whiletrue;do echo hello;sleep 2;done”
以上命令是以守护进程方式启动docker并弹出交互伪终端,并在伪终端中进行脚本输出”每2秒无线循环输出hello”。这样docker就感觉到一直存在前端交互,所以不会自动关闭。
docker logs -t -f 765eefae47d8查看docker的日志可以看到每2秒就输出
查看容器内进程:docker top容器id
查看容器内部细节:docker inspect 容器id
重新进入已启动的容器:docker attach 容器ID
启动容器后,Ctrl+p+q退出不关闭容器,再docker attach ez6d44eb3e11:
已重新进入容器(没有启动新的进程)。
docker exec 在docker外的宿主机上进行docker内部操作(启动了新的进程),
示例:docker exec -t ea6d44eb3e11 ls -l /tmp
docker exec -it ea6d44eb3e11 /bin/bash
可以看到exec可以外部直接操作docker内部,也可以进入docker后再操作,由此可见功能比attach强大。
容器内文件拷贝到主机:docker cp容器ID:容器内路径 目的主机路径
其它命令自行学习扩展。
四、镜像原理
1、镜像原理
镜像:联合文件系统(UnionFS)是镜像的基础,联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加。同时可以将不同目录挂载到同一个虚拟文件系统下。
Docker镜像的加载原理:
Docker的镜像由一层一层的文件系统组成(联合文件系统),bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs,这一层与典型的linux系统一样,包含boot加载器和内核。rootfs(root file system)在bootfs之上,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。换句话说rootfs就是不同的操作系统的发行版本,比如Ubntu,Centos等。
可以看到docker中CentOS为什么还不到200M,一般我们用的都是好几个G。
因为对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需提供rootfs就可以了。
但为什么tomcat那么大?需要理解docker的联合文件系统的分层理念
这样的好处就是每层的资源可以进行共享。
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,容器层之下的都叫镜像层。
2、镜像commit
docker commit:提交容器副本使之成为一个新的镜像
到这了,感觉有了一点实战的味道了。
案例演示:
docker run -it -p 8080:8080 tomcat
可以看到tomcat启动啦。命令中的8080:8080就表示将tomcat的8080端口影射到docker的8080端口(docker端口:tomcat端口)
访问122服务器上的docker的8080端口,可以看到tomcat及文档的页面。
删除tomcat镜像中的文档,模拟tomcat的自定义配置操作:
然后再访问122服务器上的docker的8080端口,查看tomcat文档的页面:
可以看到这里已经没有文档页面了。将此配置好的tomcat作为新镜像提交,镜像名叫t1/appTomcat1(t1是自定义的包路径):
可以看到已经提交到本地了一个新镜像。然后把正在运行的容器删除以验证:
启动新镜像tomcat,这次用docker7777端口来映射tomcat的8080: