系列文件目录
第一章:容器技术发展进程
第二章:容器底层技术
目录
- 系列文件目录
- 前言
- 一、Namespace
- 先从Linux提供的“命名空间API说起”
- clone()
- setns()
- mount命名空间
- UTS命名空间
- Network命名空间
- User命名空间
- IPC命名空间
- PID命名空间
- 二、Cgroups
- 1. Cgroups功能介绍:
- 2. Cgroups子系统介绍
- 三、容器种类
- 总结
前言
容器底层技术依赖内核的Cgroups和Namespace
一、Namespace
先从Linux提供的“命名空间API说起”
-
clone()
通过flags参数来控制创建新进程的特性,使得"新创建的进程"拥有独立的Namespace
本质上clone()是一个通用的fork()版本,fork()的功能由flags参数控制。/proc/PID/ns目录下为每个命名空间对应一个文件,这些描述符链接可以用来判断两个命名空间是否在同一个命名空间。如果两个进程在同一个命名空间,内核会保证/proc/PIC/ns导出的inode号是一样的。
#define _GNU_SOURCE
#include <sched.h>
int clone(int (*fn)(void *), void *stack, int flags, void *arg);
/*
**int (*fn)(void *) --子进程要执行的函数
**void *stack --子进程栈
**int flags --CLONE_NEW* flags的组合
**void *arg --传给子进程参数
*/
-
unshare()
将"当前进程"和所在的Namespace分离,并加入到一个新的Namespace中
#define _GNU_SOURCE
#include <sched.h>
int unshare(int flags);
/*
**int flags --需要脱离的命名空间并创建新的命名空间CLONE_NEW*
*/
-
setns()
将“当前进程”关联一个存在的命名空间
setns()将调用的进程和一个特定的命名空间解除关系并将该进程和一个同类型的命名空间关联。使用setns()和execve()能构建一个简单但有用的工具,一个和特定命名空间关联的程序并且在命名空间中可以执行一个命令。
#define _GNU_SOURCE
#include <sched.h>
int setns(int fd, int nstype);
/*
**int fd --fd引用/proc/[pid]/ns/ link连接,或者是一个PID file descriptor
**int nstype --用来检查fd关联的Namespace是否与nstype表明的Namespace一致,如果填0将不检查
*/
mount命名空间
- 用于隔离一组进程看到的文件系统挂载点集合(处于不同mount命名空间的进程看到的文件系统不一样,赋予容器不同的文件系统)
- CLONE_NEWNS
- mount() / unmount()系统调用
UTS命名空间
- 隔离了两个系统变量,节点名+域名(UTS赋予了每个容器各自的主机名+域名)
- CLONE_NEWUTS
- uname()系统调用返回UTS
- setnodename()系统调用,设置节点名
- setdomainname()系统调用,设置域名
Network命名空间
- 隔离和网络有关的资源,使得每个网络命名空间有其自己的网络设备、IP地址、IP路由表、/proc/net目录、端口号等。让每个container拥有自己的网络设备(虚拟的)和网络端口号。
- CLONE_NEWNET
User命名空间
- 隔离用户ID和组ID,一个用户ID在命名空间之外非特权,而在命名空间之内具有特权,让不同User命名空间的container拥有不同的特权。
- CLONE_NEWUSER
IPC命名空间
- 隔离进程间通信资源
- CLONE_NEWIPC
- System V IPC表示符和POSIX消息队列
PID命名空间
- 隔离进程ID号,不同命名空间的进程ID可以相同,保证了每个container能有自己的1号init进程。
- CLONE_NEWPID
- 一个进程有2个PID,一个ID属于PID命名空间,一个ID属于主机系统
二、Cgroups
Cgroups是控制组群的简写(Control groups),是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如cpu、内存、磁盘、IO输入输出等)。Cgroups是LXC(Linux Container)实现容器虚拟化的基础。
这个项目最早由Google的工程师在2006年发起,最早的名称为“进程容器(process containers)”。但在Linux内核中,容器(container)这个词有许多不同的意义,为了避免混乱,被重命名为cgroups,并合入到Linux kernel 2.6.24版本中。
1. Cgroups功能介绍:
Cgroups功能 | 描述 |
资源限制 | 对资源可以设定一个不超过的上线值。例如:控制组可以被设置不超过设定值的内存限制,也包括虚拟内存。 |
优先级 | 设置资源的占有比例,让占有比例多的获得更多的资源,间接达到优先级的效果。例如:一些组可能会得到大量的CPU或者磁盘IO吞吐量。 |
结算 | 用来度量系统实际用了多少资源 |
控制 | 冻结组或检查点和重启动 |
2. Cgroups子系统介绍
Cgroups子系统 | 描述 |
cpu | 使用调度程序提供对CPU的cgroup任务访问 |
cpuset | 为cgroup中的任务分配独立CPU(在多核系统)和内存节点 |
cpuacct | 自动生成cgroup中任务所使用的CPU报告 |
memory | 设定cgroup中任务使用内存的限制,并自动生成由那些任务使用的内存资源报告 |
blkio | 为块设备设定输入/输出限制,比如物理设备(磁盘、固态硬盘、USB等) |
devices | 可允许或者拒绝cgroup中的任务访问设备 |
freezer | 挂起或者恢复cgroup中的任务 |
三、容器种类
容器类型 | 技术路线 | 注释 |
lxc(linux container) | LXC容器常常被考虑为介于chroot和virtual machine之间的一个事物。LXC的目标是创建一个和标准安装的linux系统尽可能一样的环境,但不需要单独的kernel。 LXC可以为容器绑定特定的cpu和memory,分配特定比例的cpu时间,IO时间,限制可以使用的内存大小,提供device访问控制,提供独立的namespace(network、pid、ipc、mnt、uts)
LXC用了一下kernel feature:
| lxc-checkconfig 用于判断linux内核是否支持LXC lxc-create 用于创建一个容器 lxc-execute 用于在一个容器执行应用程序 lxc-cgroup 用于获取或调整与cgroup相关的参数 |
systemd-nspawn |
| 以systemd服务启动systemd-nspawn容器: [Service] ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --machine =%I |
cells | linux kernel的namespace和cgroups机制 | 哥伦比亚大学论文:http://systems.cs.columbia.edu/projects/cells/ 浙大github项目:http://condroid.github.io/ 以色列公司网址:https://www.cellrox.com/ |
containerd | Containerd是一个行业标准的容器运行时container runtime,强调简单性、健壮性和可移植性。它可以作为Linux和Windows的守护进程,也可以管理其主机系统的容器完整的生命周期:image镜像的传输和存储、容器执行和监督、低级存储和网络附件等。 Containerd被设计为嵌入到更大的系统中,而不是被开发人员或最终用户直接使用。 | containerd是CNCF成员,是已经毕业状态,很稳定 |
CRI-O | 基于oci的Kubernetes容器运行时接口的实现。 crio的目的是在符合OCI的运行时和kubelet之间提供集成路径。具体来说,它使用符合OCI的运行时实现了Kubelet容器运行时接口(CRI)。CRI- o的范围与CRI的范围绑定在一起。
不支持:编译、签名、push镜像image到各种image存储仓库; | github项目:https://github.com/cri-o/cri-o |
总结
- mount命名空间、UTS命名空间、Network命名空间、User命名空间,这4个命名空间可以理解为构建container环境Env的。
- IPC命名空间、PID命名空间,这2个命名空间可以理解为container运行时相关的。