容器这个名词的由来
说道这个容器这个词,包括我们在网络上搜索的时候容器对应的最多的也是集装箱
那么容器这个词是怎么由来呢?在早起海运的时候货物都是随便堆放的,这对于后期的卸载和管理都是一个不小的难题
- 包装困难,每个货物都需要有自己的包装
- 装卸困难,每个货物的大小、重量都不一样需要不同的装卸工具
集装箱(容器诞生后)
- 简化了包装,为避免货物在运输途中受到损坏,必须有坚固的包装,而集装箱具有坚固、密封的特点,其本身就是一种极好的包装
- 首先是装卸效率特别低(普通货船装卸,一般每小时为35t左右,而集装箱装卸,每小时可达400t左右)
上面就是容器诞生的原因了
container这个词有:集装箱和容器两个含义,集装箱技术比较绕口、容器技术就成了container的实际翻译了
什么是容器技术
实机时代
痛点:
- 多个APP放在一台机上:存在资源抢占以及故障影响
- 多个APP放在多台机器:存在资源浪费
解决方案:
- 大家通过虚拟软件来管理虚拟机:创建、运行、销毁解决了当时人们的诉求
虚机时代
随着人们用虚拟化用的越来越溜,对资源的利用率越来越高
思考下我就为了启动一个应用程序,我付出了什么
- 我就的安装一遍操作系统
- 重新部署一遍服务、还的确保一遍就正确
- 虚机挂了、宿主挂了,上面的东西重新来一遍
提炼下目前的痛点:
- 效率低
- 易出错
- 容错低
容器时代
人们需要一个新的技术,来解决当前的痛点,容器技术就诞生了
镜像&容器
容器技术由两部分组成:
- 镜像(特殊格式的打包文件)
- 容器(依赖内核功能创建的镜像运行空间)
镜像:包含了程序、程序依赖的Lib、环境,本质上就是一个压缩包(它解决了环境一致性的问题)
容器:是内核创建的一个隔离的空间,运行镜像(它解决了隔离问题防止程序互相干扰)
- 内核功能Namespace:隔离 (命名空间,是Linux内核功能,对内核分区分为不同的空间,让程序感觉独占一个系统)
- 内核功能Cgroup:限制 (是control groups[控制组]的缩写,是一种Linux内核功能,用于限制,说明和隔离进程集合的资源使用(CPU,内存,磁盘I/O,网络等)
内核的命名空间就类似,一个教学楼,N个班级公用这个教学楼,每个班级都可以上课公用教学楼的资源
如何让程序以为自己在独立使用这个系统呢?我们创建的独立运行空间通过Namespace来让程序感觉自己在独立的系统中运行,那一个系统都应该有什么
Linux namespace 实现了 7 项资源隔离,基本上涵盖了一个小型操作系统的运行要素,包括主机名、用户权限、文件系统、网络、进程号、进程间通信、资源。
NameSpace | 系统调用参数 | 隔离内容 | 内核支持的版本 |
---|---|---|---|
Mount namespaces | CLONE_NEWNS | 挂载点 | Linux 2.4.19 |
UTS namespaces | CLONE_NEWUTS | 主机名 | Linux 2.6.19 |
IPC namespaces | CLONE_NEWIPC | 进程间通信 | Linux 2.6.19 |
PID namespaces | CLONE_NEWPID | 进程号 | Linux 2.6.24 |
Network namespaces | CLONE_NEWNET | 网络 | Linux 2.6.29 |
User namespaces | CLONE_NEWUSER | 用户权限 | Linux 3.8 |
Cgroup namespaces | CLONE_NEWCGROUP | 资源 | Linux 4.6 |
每个namespace的特性都解决了特定的需求,是逐步迭代的,好比之前就支持6个namespace,到现在已经支持7个了
这里简单说下,镜像和容器和Docker的关系:
- Docker创建镜像
- Docker通过实现调用Linux内核功能(Linux namespace)创建运行空间运行镜像
镜像和容器的关系
要说区别其实不太恰当,它们应该是阶段的关系
容器技术和Dokcer的关系
Dokcer实现了容器技术:
- Docker实现了高效产生镜像的功能
- Docker实现了管理容器的功能,调用内核特性(Nmaespace&Cgroup)然后:创建容器、管理容器、销毁容器
- Docker的出现推动了容器技术的飞速发展(一次构建,到处运行[Build once, run everywhere])
容器技术的发展催生了,容器标准OCI(Open Container Initiative 开放容器倡议),Docker也遵循这个标准
OCI(open container initiative开放容器标准)
- 容器镜像标准(镜像怎么打)
- 容器运行时标准(容器怎么运行管理:配置、运行环境、生命周期)
决了什么问题
- 环境不一致(镜像:把所需的环境、代码、数据打包成镜像)
- 程序隔离问题(容器:内核创建的独立运行空间,让程序与程序之间隔离)
- 资源浪费问题(公用底层的:硬件、系统(内核))
- 管理管理麻烦问题(构建镜像方便、管理容器方便)
Docker
为什么是Docker
Docker是容器的解决方案之一,其他的还有Podman、coreos等那为什么选择Docker
最火的容器解决方案
容器创业公司 Sysdig 发布了 2019 年容器使用报告 Docker 占据了容器平台市场的大部分份额,占比为 79%,而排在第二位的是 containerd,占比为 18%,排在第三位的 CRI-O 项目,占比为 4%。这个调查结果与信通院的国内市场调查结果有异曲同工之妙,国内近六成企业选择 Docker 作为容器运行技术。
优势
- DockerFile快速构建一个镜像
- 镜像版本控制
- 还提供了免费的镜像仓库
- 跨平台(win、linux、ubuntu、mac)一次部署到处使用
- 活跃的社区和生态
扩展阅读
NameSpace详解
1、UTS namespace
UTS(UNIX Time-sharing System) namespace提供主机名和域名的隔离,这样每个docker容器就可以拥有独立的主机名和域名,在网络上可以被视作一个独立的节点,而非宿主机上的进程了。
2、IPC namespace
进程间通信(Inter-Process Cmmunication,IPC)涉及的IPC资源包括常见的信号量、消息队列和共享内存。申请IPC资源就申请了一个全局唯一的32位ID,所以IPC namespace中实际上包含系统IPC标识符以及实现POSIX消息队列的文件系统。在同一个IPC namespace下的进程彼此可见。
3、PID namespace
Linux内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。它创建的新的PID namespace称为child namespace(树的子节点),而原先的PID namespace就是新创建的PID namespace的parent namespace(树的父节点)。通过这种方式,不同的PID namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响,反过来,子节点却不能看到父节点PID namespace中的任何内容。
4、mount namespace
mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持,隔离后,不同mount namespace中的文件结构发生变化也互不影响。
5、network namespace
network namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4、IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、套接字(socket)等。一个物理的网络设备最多存在于一个network namespace中,可以通过创建veth pair在不同的network namespace间创建通道,以达到通信目的。
6、user namespace
user namespace主要隔离了安全相关的标识符(identifier)和属性(attribute),包括用户ID、用户组ID、root目录、key(密钥)以及特殊权限。
容器化和虚拟化有啥区别
说道Docker不得不说一下虚拟化,我相信大部分人或多或少都用过Vmware这些虚拟化软件。
我们使用虚拟化软件,可以虚拟出一个物理主机来(我们称之为虚拟机),然后给他重新安装系统
原理对比
虚拟化
虚拟化的原理:在OS中加入一个虚拟化层,虚拟化层可以对下层(HostOS)硬件资源(物理CPU、内存、磁盘、网卡、显卡等)进行封装、隔离,抽象为另一种形式的逻辑资源,再提供给上层(GuestOS)使用。所以你可以理解VMM其实就是联系HostOS和GuestOS的一个中间件,当然虚拟化可以将一份资源抽象为多份,也可以将多份资源抽象为一份。
通过虚拟化技术实现的虚拟机一般被称之为GuestOS(客户),而作为GuestOS载体的物理主机称之为HostOS(宿主)。
容器化
容器技术通通过主机HostOS(内核),虚拟化一个运行空间(本质上是运行在HostOS上),运行程序
- 启动快:虚机这边要启动一个程序首先要创建一个虚拟系统然后在安装成,容器化就是启动个程序这么简单
- 速度快:虚机调度还是需要经过一个虚拟系统层,容器直接运行在(HostOS上)少了一层速度肯定会快