文章目录
- 虚拟化容器
- 容器隔离实现
- 隔离文件 chroot
- 隔离访问 namespace
- 隔离资源 cgroups
- Docker
- kubernetes
虚拟化容器
容器的首要目标是让软件分发部署过程从传统的发布安装包、靠人工部署转变为直接发布已经部署好的、包含整套运行环境的虚拟计划镜像。
一个计算机软件能够给正确运行,需要以下三个方面的兼容性来共同保障:
- ISA兼容(Instruction Set Architecture): 目标机器指令集兼容性,臂如ARM架构计算机无法直接运行x86架构编译的程序。
- ABI兼容(Application Binary Interface): 目标系统或依赖库的二进制兼容性,臂如windows系统环境中无法直接运行Linux程序。
- 环境兼容: 臂如没有正确设置配置文件、环境变量、文件权限等,任何一个都可能让程序无法运行。
根据抽象目标和兼容性高低的不同,虚拟化技术分为:
- 指令集虚拟化:通过软件来模拟不同ISA架构处理过程,将虚拟机发出的指令进行转换符合ISA的指令。能够提供完全不受权限的兼容性。但每条指令都要由软件进行转换和模拟,性能损失最大。
- 硬件抽象层虚拟化技术: 以软件或通过硬件来模拟处理器、芯片组、显卡等设备的工作过程。虚拟机为代表,vmware。
- 操作系统层虚拟化:指令集和硬件抽象层虚拟化都会运行一套完全真实的操作系统来解决ABI兼容性和环境兼容性。操作系统虚拟化不会提供真实的操作系统,而是采取隔离手段,使得不同进程拥有独立的系统资源和资源配额。看上去独享操作系统,但实际上共用系统内核。容器化。容器化牺牲一定隔离性和兼容性,换来的是更快启动速度、运行性能和更低的执行负担。
- 运行库虚拟化: 运行库使用软件翻译的方法来模拟系统,以一个独立进程来代替操作系统内核来提供目标软件运行所需的全部能力。这种虚拟化方法的ABI兼容性高低,取决于软件是否能够足够准确和全面地完全翻译工作。 WSL
- 语言层面虚拟化:由虚拟机将高级语言生成地中间代码转换为目标机器可以直接执行地指令。
容器隔离实现
隔离文件 chroot
change root,命令功能是当某个进程经过chroot
操作之后,它的根目录就会被锁定在命令行参数所指定的位置,以后它或者他的子进程不能再访问和操作该目录之外的文件。chroot存在漏洞提升的问题,从而出现pivot_root实现文件隔离,直接切换根文件系统(rootfs),有效避免了chroot命令可能出现的安全性漏洞。
理论上Unix设计哲学为一切皆文件,只要隔离了文件系统,一切资源都应该被自动隔离才对。但是从硬件层面暴露的低层次资源,磁盘,网络内存等。到经过操作系统层面封装的高层次资源,如进程ID、用户ID、进程间通信都存在大量非文件形式暴露的操作入口,因此chroot为代表的文件隔离,仅仅是容器化崛起之路的起点。
隔离访问 namespace
Linux命令空间。
linux的名称空间是一种由
内核
直接提供的全局资源封装,是内核针对进程设计的访问隔离机制。进程在一个独立的linux名称空间中超系统看去,会觉得自己彷佛就是这方天地的主人,拥有这台linux主机上的一切资源,文件系统独立,独立的PID编号、UID\GID编号和网络等。
Linux名称空间支持的资源种类的隔离:
- Mount: 隔离文件系统,功能上类似
chroot
。 - UTS: 隔离主机的Hostname和Domain names
- IPC: 隔离进程间通信的渠道。
- PID:隔离进程编号,无法看到其他名称空间中的PID,意味着无法对其他进程产生影响。
- Network: 隔离网络资源,如网卡、网络栈、端口等。
- User: 隔离用户和用户组。
- Cgroup: 隔离cgroups信息,进程有自己的cgroups的根目录试图。
- Time: 隔离系统时间。
隔离资源 cgroups
独立控制分配给各个进程的资源使用配额。
linux解决以上问题的方案是控制群组(Control Groups),它与名称空间一样都是直接由内核提供的功能,用于隔离或者说分配并限制某个进程组能够使用的资源配额,资源配额包括处理器时间、内存大小、磁盘IO速度等。
控制组子系统:
- blkio: 为块设备(磁盘、固态硬盘)设定I/O限额。
- cpu: 控制cgroups中进程的处理器占用比率。
- cpuacct:自动生成cgroups中进程所使用的处理器时间的报告。
- devices: 设置cgroups中的进程访问某个设备的权限(读、写、创建三种权限)
- freezer: 挂起或者恢复cgroups中的进程。
- memory: 设定cgroups中进程使用内存的限制,并自动生成内存资源使用报告。
- net_cls:使用等级标记符标记网络数据包,可允许Linux流量控制识别从具体cgroups中生成的数据包。
- net_prio:用来设置网络流量的优先级。
- hugetlb:针对HugeTLB系统进行限制。
- perf_event: 允许Perf工具基于cgroups分组做性能监测。
Docker
docker除了包装linux内核的特性之外,它的价值还有:
- 跨机器的绿色部署: docker定义了一种将应用机器所有环境依赖都打包到一起的格式。
- 以应用为中心的部署
- 自动构建:docker提供了开发人员从在容器中构建产品的全部支持,开发人员无需关注目标机器的具体配置,即可使用任意的构建工具链,在容器中构建出最终产品。
- 多版本支持: 支持类似git一样管理容器的连续版本,检查版本之间的差异,提交和回滚操作。可以从历史记录中查看容器如何被构建。
- 组件重用: docker允许将任务现有容器作为基础镜像来使用,以此构建出更加专业的镜像。
- 共享: 拥有公共镜像库,方便共享,减少重复工作量。
- 工具生态: 开放了一套自动化和自行拓展的接口,能够给拓展功能,例如:容器编排、管理界面、持续集成。
contanerd-shim: 适配进程,默认和runC搭配工作。
runC是一个轻量级、基于命令行的容器运行时,它由OCI规范支持,用于创建和运行容器。核心功能:
- 容器运行时: 可以直接创建和管理容器。
- 低级运行时:容器引擎底层运行容器的核心工具,处理容器生命周期中的关键操作,例如启动、停止和销毁机器。
- 基于linux内核技术:使用linux内核特性,实现资源隔离和限制
kubernetes
服务编排框架,能够将大型软件系统所依赖的集群环境也进行虚拟化,使得集群得以跨数据中心的绿色部署,并根据实际情况自动扩缩。
- docker-manager: 通过http方式发送指令给docker engine进行管理容器。
- kubelet:集群节点中的代理程序,负责于管理集群的Master通信。
- CRI: 容器运行时接口,定义容器运行时应该如何接入kubelet的规范标准。dockermanager被替代为
KubeGenericRuntimeManager
和Kubelet通过GRPC进行通信。 - dockershim服务: 作为docker与CRI的适配层。
- cri-containerd: CRI适配器。