【docker】1.docker的虚拟化原理

文章详细介绍了Docker如何通过Namespace实现进程、网络、文件系统等资源隔离,以及CGroup在资源限制中的作用,特别是如何通过LinuxKernelNamespace接口和CGroup机制来控制CPU、内存等资源使用。此外,还讨论了UnionFS在Docker镜像复用中的应用,以及Docker的存储驱动overlay2基于UnionFS的工作原理。
摘要由CSDN通过智能技术生成

虚拟化要解决的核心问题:资源隔离与资源限制。

docker通过Namespace实现资源隔离,CGroup实现资源限制,UnionFS实现存储层的读写控制。

这几种机制都是操作系统级支持的,docker利用它们实现虚拟化过程。

1. Namespace命名空间

linux的6种命名空间:

PID Namespace

进程隔离

不同Namespace中的进程可以有相同的 PID(容器的 init 进程 pid 是 1)。

Net Namespace

网络隔离

每个Namespace都有自己的网络设备、IP 地址、路由表和防火墙规则

Mnt Namespace

文件系统隔离

不同的Namespace有不同的挂载点,容器内看到的是自己独立的文件系统

IPC Namespace

隔离进程间通信

每个Namespace管理自己的IPC资源,包括消息队列、信号量和共享内存,不会相互干扰

UTS Namespace

隔离主机名和域名

每个命名空间都有自己的主机名

User Namespace

隔离用户和用户组

每个命名空间都有自己的用户和组

如何查看一个进程的命名空间id:

// 打印当前进程pid
echo $$

// 查看进程树
pstree -p 8061

// 根据进程pid查看namespace
ls -l /proc/8061/ns
// 以下是输出
lrwxrwxrwx 1 root root 0 Jun 24 12:51 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Jun 24 12:51 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Jun 24 12:51 net -> net:[4026531968]
lrwxrwxrwx 1 root root 0 Jun 24 12:51 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Jun 24 12:51 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jun 24 12:51 uts -> uts:[4026531838]

docker启动一个容器时,会调用Linux Kernel Namespace的接口,设置几种命名空间(默认6全都设置)。容器被创建出了新的命名空间,有别于宿主机的命名空间,以此达到资源的有效隔离。

linux kernel的系统函数:

// child_func 传入子进程运行的程序主函数
// child_stack 传入子进程使用的栈空间
// flags 表示使用哪些 CLONE_* 标志位
// args 用于传入用户参数
int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);

// 比如要实现进程独立的UTS空间:
int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWUTS | SIGCHLD , NULL);

2. CGroup资源限制

要解决的问题:如容器在执行cpu密集型任务时,为了不影响其他容器的性能,出现多个容器抢占资源的问题,需要对多个容器的资源使用进行限制(cpu/内存/磁盘)。

Linux Control Group是Linux内核的一个功能,可以实现:

  • Resource limitation: 限制资源
  • Prioritization: 优先级控制,如CPU利用和磁盘IO吞吐
  • Accounting : 一些审计或一些统计,主要是为了计费
  • Control: 挂起进程,恢复执行进程
举个例子,限制某进程的cpu占用:
// 进入cpu group目录
cd /sys/fs/cgroup/cpu 
// 创建一个测试目录,这里创建后会自动在目录下生成一些文件
mkdir test_limit 
cd test_limit

// 接下来执行一个程序,让cpu跑到100%, 并查看这个进程的pid
go run /xxx/test.go

// 限制test_limit这个进程组的cpu总利用率为20%
// 这里20000指的就是20%
echo 20000 > /sys/fs/cgroup/cpu/test_limit/cpu.cfs_quota_us 
// 向任务控制列表中添加需要被限制的pid 
echo 12345 >> /sys/fs/cgroup/cpu/test_limit/tasks

// 可以top查看cpu利用率是否降到20%

docker底层也是利用上述原理实现的资源限制,cpu、内存、磁盘IO、网络带宽都可以限制。

3. UnionFS联合文件系统

解决的问题:对多个容器来说,如果他们共用一个image,是不需要把每个image都cp一份的,全量的文件系统拷贝会对磁盘造成巨大压力,需要做image的复用,提高磁盘的利用率。

Docker镜像是一种分层存储结构,Dockerfile中每条指令会生成一层,镜像是一层一层堆叠起来的,镜像中的这些层都是只读的。

当启动容器时,会在这些层的基础上创建一个容器层,用于保存容器内部做的所有更改。

写时复制(COW, Copy on Write):当对文件有写操作时,才会从只读的镜像层复制文件到容器层,进行修改。所以无论有多少个容器共享一个image,都是在自己容器内的副本上操作的,不会修改image源文件,也不会相互影响。

UnionFS 是一种为 Linux 操作系统设计的,用于把多个文件系统联合到同一个挂载点的文件系统服务, 将不同文件夹中的层联合(Union)到了同一个文件夹中,整个联合的过程被称为联合挂载(Union Mount)。

Docker的存储驱动是基于UnionFS的overlay2,实现上述联合文件系统的管理。

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值