为什么会有docker技术的出现?
一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验
Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。
环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
docker理念
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
虚拟化技术种类
- 全虚拟化架构
底层分为:
- Hardware Layer 硬件层
- Host OS 操作系统
- Virtual Machine Manager 虚拟化层
上层分为:
- Virtual Hardware 虚拟硬件
- Guest OS… 虚拟系统(windows,linux…)
- Applications 应用程序
PS:VMWar就是一种全虚拟化的虚拟机
- OS层虚拟化架构
底层分为:
- Hardware Layer 硬件层
- Host OS 操作系统
- Virtualization Layer 虚拟化层
上层分为:
- Host OS 操作系统
- Applications 应用程序
PS:相比于全虚拟化,OS虚拟化技术省去了虚拟硬件,直接共用底层硬件,但是上层操作系统必须与底层操作系统相同,docker虚拟化就是OS虚拟化技术
- 硬件层虚拟化
底层分为:
- Hardware Layer 硬件层
- Virtualization Layer 虚拟化层
上层分为:
- Guest OS… 虚拟操作系统
- Applications 应用程序
PS:硬件层虚拟化是直接基于硬件进行虚拟化,上层可以安装多种虚拟操作系统
比较docker和传统虚拟化方式的不同之处:
-
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
-
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
-
每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
docker架构图
理解docker镜像,容器,仓库
- 镜像
镜像是容器的只读模板和UnionFs文件系统(镜像是分层的,上层镜像基于下层镜像,最底层的是基础镜像),可以形象的理解为java类,定义的java对象的属性和功能
- 容器
容器是一个精华版的Linux系统包含了运行在其中的应用程序,容器是镜像的实例,一个镜像可以启动多个容器,好比一个java类可以创建多个对象
- 仓库
仓库用于存放镜像文件,类似于Git的代码仓库,提交镜像到仓库,在任意docker客户端连接仓库,可以下载镜像
Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTful API。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。
docker常用命令
- 帮助命令
- docker version 查看docker版本
- docker info 查看docker详细信息
- docker --help 查看docker命令文档
- 镜像命令
-
docker images [OPTINS] 查看本地所有镜像
- -a 列出本地所有镜像(包含中间映像层)
- -q 只显示镜像ID
- –digests 显示镜像的摘要信息
- –no-trunc 显示完整的镜像信息
-
docker search [OPTINS] 查找某个镜像
- –no-trunc 显示完整的镜像描述
- -s 列出收藏数不小于指定值的镜像
- –automated 只列出automated build(自动化构建)
-
docker pull 下载镜像
- docker pull 镜像名称:[TAG版本号]
-
docker rmi 删除某个镜像
- docker rmi -f 镜像ID 删除单个镜像
- docker rmi -f 镜像名:TAG 镜像名:TAG 删除多个镜像
- docker rmi -f ${docker images -q} 删除全部镜像
-
- 容器命令
-
docker run [OPTINS] IMAGES [COMMAND] 启动容器(如果容器不存在先新建)
- –name 指定容器名称,不指定这随机分配一个
- -d 后台运行容器,并返回容器ID,也称为守护式容器
- -i 以交互模式运行容器,通常与-t一起使用
- -t 为容器分配一个伪输入终端,通常与-i一起使用
- -P 随机端口映射,(宿主机prot:容器prot)
- -p 指定端口号映射,(宿主机prot:容器prot)
-
docker ps [OPTINS] 列出所有正在运行的容器
- -a 列出所有正在运行的容器,包括历史运行过的容器
- -l 显示最近创建的容器
- -n 显示最近N个创建的容器4
- -q 只显示容器ID
- –no-trunc 不截断输出
-
退出正在运行的容器
- exit 容器停止并退出
- Ctrl+p+q 容器不停止退出
-
docker start 容器ID或容器名 启动容器
-
docker restart 容器ID或容器名 重启容器
-
docker stop 容器ID或容器名 停止容器
-
docker kill 容器ID或容器名 强制停止容器
-
docker rm 容器ID 删除已停止的容器
- docker rm -f ${docker ps -qa} 删除全部容器
-
docker logs -f -t --tail 容器ID 查看容器日志
- -f 打印最新日志
- -t 加入时间戳
- –tail 显示最后多少条 例如:–tail 10
-
docker top 容器ID 查看指定容器内运行的进程
-
docker inspect 容器ID 查看容器的详细信息
-
进入正在运行的容器并打开交互终端
- docker exec -it 容器ID /bin/bash 在容器中打开新终端,并且可以启动新的进程
- docker attach 容器ID 直接进入容器,不会启动新的进程,如果多个用户同时操作,界面会统一
-
从容器中拷贝文件到宿主机
- docker cp 容器ID:容器拷贝目录 宿主机目录
-
注:在docker run -d启动后台守护式容器,如果运行的容器不会自动挂起(必须有前台响应),则会直接退出容器,例如:docker run -d centos;但是如果容器会自动挂起,则不会退出,例如:docker run -d tomcat;针对后台守护式启动没有前台挂起退出的容器,可以使用 docker run -d centos /bin/bash
docker镜像
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系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的kernel(系统内核),自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
- 分层的镜像
实际上我们在pull镜像时就可以看到,docker镜像是一层层的在下载,这种设计的最大好处就是"共享",比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
ps:docker镜像都是只读的,当容器启动时,一个新的可写层