Docker
在前两年读研时经常会有实验室的师兄提起, 属于一直有所耳闻, 未曾深入了解的范畴. 目前在工作中, 发现Docker
是当前程序员必备技能之一, 公司微服务架构中,云计算的实现中,项目容器化的实践中 均使用Docker
作为实现工具. 所以需要对Docker
有一个基础而全面的认知才行. 这里以上述专栏为契机, 简单认识下Docker
.
Requirements
引子, 在开发过程中,项目代码的运行环境起码要经历三套环境,开发环境
, 测试环境
, 生产环境
, 这三套环境一般会选择重新搭建; 搭建环境是费时又费力,并且随着操作系统的不同,或者操作流程的差异, 无法保证这一套环境的表现与开发环境保持一致. 那么对于解决当前环境迁移与依赖的问题目前的解决方案有哪些呢?
VM vs Container
目前存在两种技术解决方案, 1.虚拟机(VM)技术. 2.容器(Container)技术;
VM
虚拟机技术是通过操作系统
级别的隔离,实现的应用间的隔离;下图展示的为虚拟机技术架构:
上图的架构中可以看到,当要运行期望的项目APP
时 需要 环境依赖 + 系统依赖
, 而操作系统是缓慢而笨重的,并且占用大量的内存空间, 这不免有一种杀鸡用牛刀的感觉.那么如果去除掉系统依赖
仅存在环境依赖就可以提升内存有效利用率,更轻量,更便捷; 这种实现技术就是容器(Container);
Container
Container
在英文中有集装箱的含义, 这与容器技术是可以联想的;
集装箱的好处:
- 集装箱之间是隔离的;
- 可以反复使用;
- 快速的装载与卸载;
- 规格标准化,可以放置在船舶中也可以放在码头;
与虚拟机通过操作系统实现隔离不同,容器技术只隔离应用程序的运行时环境但容器之间可以共享同一个操作系统,这里的运行时环境指的是程序运行依赖的各种库以及配置。下图是容器技术的架构图:
从架构图中,可以看到相比于虚拟机,容器更加轻量级,资源占用少; 对于同样规格的硬件资源,可部署的资源更多.那么容器技术的最佳实现工具是什么的? Docker!!!
Docker Definition
Docker
是一个Go
实现的开源项目, 用于容器的创建与使用. 其通过将程序与相关依赖包打包到docker container
方式,保证程序的平滑的运行在各种操作系统中,也就是屏蔽了系统环境的差异性, 实现了BORE, build once run everywhere
.
Docker
中存在三个关键概念:
dockerfile
image
container
1 | 实际上你可以简单的把image理解为可执行程序,container就是运行起来的进程。 |
Docker Usage
Docker
使用C/S
架构, docker client
负责处理用户输入, docker server
实现对应功能;下面介绍三个常用命令的工作流程:
docker build
: 当我们写完dockerfile
交给docker“编译”时使用这个命令,那么client在接收到请求后转发给docker daemon,接着docker daemon根据dockerfile
创建出“可执行程序”image。docker run
: 有了“可执行程序”image后就可以运行程序了,接下来使用命令docker run,docker daemon接收到该命令后找到具体的image,然后加载到内存开始执行,image执行起来就是所谓的container。docker pull
: 实现也很简单,那就是用户通过docker client发送命令,docker daemon接收到命令后向docker registry发送image下载请求,下载后存放在本地,这样我们就可以使用image了
Docker Implementation principle
docker基于Linux内核提供这样几项功能实现的:
NameSpace
我们知道Linux中的PID、IPC、网络等资源是全局的,而NameSpace
机制是一种资源隔离方案,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace
,各个NameSpace
下的资源互不干扰,这就使得每个NameSpace
看上去就像一个独立的操作系统一样,但是只有NameSpace
是不够。Control groups
虽然有了NameSpace
技术可以实现资源隔离,但进程还是可以不受控的访问系统资源,比如CPU、内存、磁盘、网络等,为了控制容器中进程对资源的访问,Docker采用control groups技术(也就是cgroup
),有了cgroup
就可以控制容器中进程对系统资源的消耗了,比如你可以限制某个容器使用内存的上限、可以在哪些CPU上运行等等。