容器底层技术

系列文件目录

第一章:容器技术发展进程

第二章:容器底层技术


目录


前言

容器底层技术依赖内核的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命名空间

  1. 用于隔离一组进程看到的文件系统挂载点集合(处于不同mount命名空间的进程看到的文件系统不一样,赋予容器不同的文件系统)
  2. CLONE_NEWNS
  3. mount() / unmount()系统调用

UTS命名空间

  1. 隔离了两个系统变量,节点名+域名(UTS赋予了每个容器各自的主机名+域名)
  2. CLONE_NEWUTS
  3. uname()系统调用返回UTS
  4. setnodename()系统调用,设置节点名
  5. setdomainname()系统调用,设置域名

Network命名空间

  1. 隔离和网络有关的资源,使得每个网络命名空间有其自己的网络设备、IP地址、IP路由表、/proc/net目录、端口号等。让每个container拥有自己的网络设备(虚拟的)和网络端口号。
  2. CLONE_NEWNET

User命名空间

  1. 隔离用户ID和组ID,一个用户ID在命名空间之外非特权,而在命名空间之内具有特权,让不同User命名空间的container拥有不同的特权。
  2. CLONE_NEWUSER

IPC命名空间

  1. 隔离进程间通信资源
  2. CLONE_NEWIPC
  3. System V IPC表示符和POSIX消息队列

PID命名空间

  1. 隔离进程ID号,不同命名空间的进程ID可以相同,保证了每个container能有自己的1号init进程。
  2. CLONE_NEWPID
  3. 一个进程有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:

  1. kernel namespace(ipc,uts,mount,pid,network,user)
  2. Apparmor and SELinux profiles
  3. Seecomp policies
  4. Chroot(using pivot_root)
  5. Kernel capabilities
  6. CGroups(control groups)

lxc-checkconfig  用于判断linux内核是否支持LXC

lxc-create  用于创建一个容器

lxc-execute  用于在一个容器执行应用程序

lxc-cgroup  用于获取或调整与cgroup相关的参数

systemd-nspawn
  1. systemd-nspawn可以在轻量级的命名空间容器中运行command或OS,和chroot相似,但更强大,它完全虚拟化了文件系统层次结构,以及进程树、各种IPC子系统、主机名和域名。
  2. systemd-nspawn将容器中各种内核接口的访问限制为只读(例如:/sys,/proc/sys,/sys/fs/selinux)。host的网络接口和系统时钟不能再容器内修改,不能创建设备节点。
  3. systemd-nspawn可以以命名启动容器,也可以作为systemd的service启动。
  4. 根据systemd-nspawn的man page介绍,其预期用途是用于调试、测试以及构建与引导和系统管理有关的软件包、发行版和软件。

以systemd服务启动systemd-nspawn容器:

[Service]

ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --machine =%I

cellslinux 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成员,是已经毕业状态,很稳定

github项目:https://github.com/containerd/containerd

CRI-O

基于oci的Kubernetes容器运行时接口的实现。

crio的目的是在符合OCI的运行时和kubelet之间提供集成路径。具体来说,它使用符合OCI的运行时实现了Kubelet容器运行时接口(CRI)。CRI- o的范围与CRI的范围绑定在一起。

  1. 支持多种image镜像格式,包括已经存在的docker image镜像格式。
  2. 支持多种下载image镜像的方式,包括信任和镜像校验。
  3. 容器镜像管理(管理image layer镜像层,overlay文件系统等)。
  4. 容器生命周期管理。
  5. 满足CRI要求的监控和日志记录。
  6. CRI要求的资源隔离。
  7. 这是一个Kubernetes容器运行时接口(CRI)的实现,它将允许Kubernetes直接启动和管理Open Container Initiative (OCI)容器。

不支持:编译、签名、push镜像image到各种image存储仓库;

github项目:https://github.com/cri-o/cri-o

总结

  1. mount命名空间、UTS命名空间、Network命名空间、User命名空间,这4个命名空间可以理解为构建container环境Env的。
  2. IPC命名空间、PID命名空间,这2个命名空间可以理解为container运行时相关的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值