Docker
什么是容器
-
容器技术是一种虚拟化的方案
-
传统虚拟机是通过中间层,将一台或多台独立的机器虚拟运行在硬件之上
-
而容器时直接运行在系统内核之上的用户空间
-
因此,容器虚拟化也被称为操作系统虚拟化
-
由于运行在操作系统上,所以容器只能运行相同或相似内核的操作系统
容器和传统虚拟化的区别
传统虚拟化:通过虚拟化技术模拟真实的硬件从而创建出来的一台拥有完整功能的逻辑计算机。
Docker容器:Docker容器也是一种虚拟化技术,和传统虚拟化不一样的是Docker只模拟一个程序最核心的运行环境,所以十分小巧,启动更快。
虚拟化分为以下两类:
- 主机级虚拟化
- 全虚拟化
- 半虚拟化
- 容器级虚拟化
容器分离开的资源:
- UTS(主机名与域名)
- Mount(文件系统挂载树)
- IPC
- PID进程树
- User
- Network(tcp/ip协议栈)
Docker虚拟化技术和传统虚拟化技术架构对比:
对比 | 特点 |
---|---|
虚拟机 | 完整的系统功能,隔离性更好,占用空间大(通常以G为单位) 运行占用资源较多,启动慢(分钟级启动) |
容器 | 只有程序运行的核心环境,不需要安装直接运行镜像即可 隔离性一般,十分小巧占用空间极小(一般以M为单位),启动快(秒级启动) |
Linux Namespaces
命名空间(Namespaces)是Linux内核针对实现容器虚拟化而引入的一个强大特性。
每个容器都可以拥有自己独立的命名空间,运行其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器间彼此互不影响。
namespaces | 系统调用参数 | 隔离内容 | 内核版本 |
---|---|---|---|
UTS | CLONE_NEWUTS | 主机名和域名 | 2.6.19 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 | 2.6.19 |
PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等 | 2.6.29 |
Mount | CLONE_NEWNS | 挂载点(文件系统) | 2.4.19 |
User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
CGroups
控制组(CGroups)是Linux内核的一个特性,用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,Docker才能避免多个容器同时运行时的系统资源竞争。
控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制。
CGroups能够限制的资源有:
- blkio:块设备IO
- cpu:CPU
- cpuacct:CPU资源使用报告
- cpuset:多处理器平台上的CPU集合
- devices:设备访问
- freezer:挂起或恢复任务
- memory:内存用量及报告
- perf_event:对cgroup中的任务进行统一性能测试
- net_cls:cgroup中的任务创建的数据报文的类别标识符
具体来看,控制组提供如下功能:
- 资源限制(Resource Limitting)组可以设置为不超过设定的内存限制。比如:内存子系统可以为进行组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出Out of Memory警告
- 优先级(Prioritization)通过优先级让一些组优先得到更多的CPU等资源
- 资源审计(Accounting)用来统计系统实际上把多少资源用到合适的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间
- 隔离(Isolation)为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统
- 控制(Control)挂起、恢复和重启等操作
安装Docker后,用户可以在/sys/fs/cgroup/memory/docker/
目录下看到对Docker组应用的各种限制项,包括
[root@localhost ~]# cd /sys/fs/cgroup/memory/
[root@localhost memory]# ls
cgroup.clone_children memory.kmem.slabinfo memory.memsw.limit_in_bytes memory.swappiness
cgroup.event_control memory.kmem.tcp.failcnt memory.memsw.max_usage_in_bytes memory.usage_in_bytes
cgroup.procs memory.kmem.tcp.limit_in_bytes memory.memsw.usage_in_bytes memory.use_hierarchy
cgroup.sane_behavior memory.kmem.tcp.max_usage_in_bytes memory.move_charge_at_immigrate notify_on_release
memory.failcnt memory.kmem.tcp.usage_in_bytes memory.numa_stat release_agent
memory.force_empty memory.kmem.usage_in_bytes memory.oom_control system.slice
memory.kmem.failcnt memory.limit_in_bytes memory.pressure_level tasks
memory.kmem.limit_in_bytes memory.max_usage_in_bytes memory.soft_limit_in_bytes user.slice
memory.kmem.max_usage_in_bytes memory.memsw.failcnt memory.stat
什么是Docker
-
Docker是容器技术的一个前端工具,容器是内核的一项技术,Docker只是把这一项技术的使用得以简化,使之普及而已
-
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
-
Docker是通过内核虚拟化技术(namespaces(命令空间)及cgroups(控制组)等)来提供容器的资源隔离与安全保障等,由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要虚拟机(VM)额外的操作系统开销,提高资源利用率。
注:此内核是linux内核
Docker官网:https://www.docker.com/
Docker解决什么问题
- 要想使用LXC管理容器,要学习很对LXC工具。LXC命令列表
- 必要时要定制模板
- 每一个名称空间都是安装生成的,在该名称空间中运行的进程会生成一些文件(数据库之类的),当该宿主故障时,如何迁移到其他宿主机上
- 批量创建较困难
总结起来就是通过LXC管理容器比起传统虚拟化的虚拟机的使用复杂度没有多大降低,更何况隔离性也没有虚拟机那么好。当然了好处在于每个容器中的进行都可以直接使用宿主机的性能,中间没有额外开销(节约资源)。LXC在分发和大规模使用上没有很好的方法。于是后来就出现了Docker,早期的Docker可以看作为是LXC的增强版(主要解决分发和大规模使用)。
Docker本身不是容器,Docker只是容器的易用工具。容器是Linux内核的技术,Docker只是简化容器这种技术的使用。
Docker运行架构:
综上所述:LXC面临大规模使用和在其他的主机上复刻容器(分发)很难,于是Docker就在这方面着手解决。所以早期的Docker就是LXC的二次封装。功能上是通过LXC作为容器管理引擎,但是创建容器时,不在是用模板现场安装生成,而是事先通过一种叫做镜像的技术。把一个操作系统的用户空间用到了所有组件编排好,编排好以后整体打包成一个文件。这个文件就叫做镜像文件(Image)。使用Docker创建容器时,Docker不会激活LXC的模板创建安装。而是连接到镜像仓库,下载一个创建容器所需要的镜像。 Docker极大的简化了容器的使用,比如想要运行一个nginx 直接Docker run nginx 就行了。
每个容器本身可以运行一个多一组进程,Docker为了使容器的使用更加易于管理,采用在一个Docker容器中之运行一个进程。这样会带来一下好处和坏处。
好处:
- 每个容器只运行一个进程,多个进程走容器间通信(更加隔离性,更容器分发)
坏处:
- 所需要的存储空间增加了
- 调试容器中的进程比较困难
开发人员开发的好的程序只需要打包到一个Docker镜像中,便可以到处运行在拥有在Docker的机器上。一些特殊进程类似数据库这种,需要采用共享存储才可以更好的解决分发问题。通过将应用打包为镜像这种机制,可以很好的解决分发的问题。 在大规模使用场景上也是很简单的,在每个机器上只需要有一份镜像文件便可以启动N个示例。(具体参考Docker镜像,分层部署-联合挂载这一特性)
有了Docker的镜像机制后就可以很好的解决分发和大规模使用了。 当然想好用好容器还是要有容器编排工具的。
Docker底层技术
- 名称空间:Docker通过名称空间机制为容器提供隔离的工作空间。
- 控制组:Linux可以通过控制组设置进程使用CPU、内存和I/O资源的限额。Docker引擎正是依赖这种底层技术来限制容器使用的资源。
- 联合文件系统:可以将其他文件系统合并到一个联合挂载点。联合文件系统是实现Docker镜像的技术基础。Docker镜像可以通过分层来实现继承。
- 容器格式:Docker引擎将名称空间、控制组和联合文件系统打包到一起所使用的就是容器格式。默认的容器格式是Libcontainer。
Docker优势
- 应用程序快速、一致地交付
- 开发人员在本地编写应用程序代码,通过Docker与同事进行共享。
- 通过Docker将应用程序推送到测试环境中,执行自动测试和手动测试。
- 开发人员发现程序错误时,可以在开发环境中进行修复,然后重新部署到测试环境来进行测试和验证。
- 完成应用程序测试之后,向客户提供补丁程序非常简单,只需将更新后的镜像推送到生产环境中。
- 响应式部署和伸缩应用程序
- 更简单的系统运维
- 更高效的计算资源利用
Docker容器编排
- 能够把这种应用程序之间的依赖关系、从属关系、隶属关系等等反映在启动、关闭时的次序和管理逻辑中,这种功能被称为容器编排。
常见的容器编排工具:
- machine+swarm(把N个Docker主机当一个主机来管理)+compose(单机编排)
- mesos(实现统一资源调度和分配)+marathon
- kubernetes --> k8s