Docker中容器底层实现技术cgroup和namespace

13 篇文章 1 订阅
13 篇文章 0 订阅

Docker中容器底层实现技术cgroup和namespace

cgroup 实现资源限额, namespace 实现资源隔离

一、cgroup

1、概述

cgroup 全称 Control Group

Linux 操作系统通过 cgroup 设置进程使用 CPU、内存 和 IO 资源的限额

--cpu-shares、-m、--device-write-bps 就是在配置 cgroup

cgroup 可在 /sys/fs/cgroup 中找到它

2、启动一个容器--cpu-shares=512

docker  run -it  --cpu-shares 512 progrium/stress -c 1

容器的 ID:6a3c3c8f60c8

在 /sys/fs/cgroup/cpu/docker 下,Linux 为每个容器创建一个 cgroup 目录,以容器长ID 命名:6a3c3c8f60c82d9f651ccf3f17dce279905a053626a6c93d25b4d933929e4efb

ll /sys/fs/cgroup/cpu/docker/

ll /sys/fs/cgroup/cpu/docker/6a3c3c8f60c82d9f651ccf3f17dce279905a053626a6c93d25b4d933929e4efb/

cat  /sys/fs/cgroup/cpu/docker/6a3c3c8f60c82d9f651ccf3f17dce279905a053626a6c93d25b4d933929e4efb/cpu.shares

目录中包含所有与 cpu 相关的 cgroup 配置

文件 cpu.shares 保存的就是 --cpu-shares 的配置,值为 512

3、内存的 cgroup 配置

/sys/fs/cgroup/memory/docker

4、Block IO 的 cgroup 配置

/sys/fs/cgroup/blkio/docker

二、namespace

在容器中,可看到文件系统、网卡等资源,这些资源看上去是容器自己的

如网卡,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡,使得容器更像一个独立的计算机

Linux 实现这种方式的技术是 namespace

namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它

namespace 实现了容器间资源的隔离

Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User

1、Mount namespace

Mount namespace 让容器看上去拥有整个文件系统

容器有自己的 / 目录,可以执行 mount 和 umount 命令,操作只在当前容器中生效,不会影响到 host 和其他容器

2、UTS namespace

UTS namespace 让容器有自己的 hostname

默认情况下,容器的 hostname 是它的短ID,可以通过 -h 或 --hostname 参数设置

docker  run  -h  zolahost  -it  centos

3、IPC namespace

IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起

4、PID namespace

容器在 host 中以进程的形式运行

查看容器在host上的进程

ps  axf

-a : 显示现行终端机下的所有进程,包括其他用户的进程

-x :通常与 a 这个参数一起使用,可列出较完整信息

-f : 用树形格式来显示进程

此次练习使用的是docker版本:

Docker version 19.03.8

从Docker 1.11开始,Docker容器运行已经不是简单的通过Docker daemon来启动,而是集成了containerd、runC等多个组件

A、Docker Daemon

作为Docker容器管理的守护进程,Docker Daemon从最初集成在docker命令中(1.11版本前),到后来的独立成单独二进制程序(1.11版本开始),其功能正在逐渐拆分细化,被分配到各个单独的模块中去

B、Containerd

containerd是容器技术标准化之后的产物,为了能够兼容OCI标准,将容器运行时及其管理功能从Docker Daemon剥离。理论上,即使不运行dockerd,也能够直接通过containerd来管理容器。(containerd本身只是一个守护进程,容器的实际运行时由runC控制)

containerd主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)

containerd向上为Docker Daemon提供了gRPC接口,使得Docker Daemon屏蔽下面的结构变化,确保原有接口向下兼容。向下通过containerd-shim结合runC,使得引擎可以独立升级,避免之前Docker Daemon升级会导致所有容器不可用的问题

C、Docker、containerd和containerd-shim之间的关系

观察进程之间的关联

yum -y install psmisc

查看进程之间的父子关系

pstree -l -a -A dockerd的PID

说明:当Docker daemon启动之后,dockerd和docker-containerd进程一直存在

当启动容器之后,docker-containerd进程(即containerd组件)会创建docker-containerd-shim进程,其中的参数 容器长ID 就是要启动容器的id

docker-containerd-shim子进程,是实际在容器中运行的进程

docker-containerd-shim另一个参数,是一个和容器相关的目录ls /var/run/docker/containerd/,里面的内容有:

find / -name config.json

ls /run/containerd/io.containerd.runtime.v1.linux/moby/

ls /var/run/docker/

ls /var/run/docker/containerd/

其中包括了容器配置和标准输入、标准输出、标准错误三个管道文件

D、RunC

OCI定义了容器运行时标准,runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现

runC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能

Docker默认提供了docker-runc实现,事实上,通过containerd的封装,可以在Docker Daemon启动的时候指定runc的实现

从Docker 1.11之后,Docker Daemon被分成了多个模块以适应OCI标准

拆分之后:

containerd独立负责容器运行时和生命周期(如创建、启动、停止、中止、信号处理、删除等),其他一些如镜像构建、卷管理、日志等由Docker Daemon的其他模块处理

dockerd 对应启动container(容器)的关系:

docker run 访问了docker服务提供的接口

然后由 dockerd 装载 image,拉起 container

E、查看容器自己的进程

进入到某个容器,然后 ps

docker  exec  -it  ID  bash

docker  exec  -it  94028ecfa080  bash

ps  axf

容器中进程的 PID 不同于 host 中对应进程的 PID

容器中 PID=1 的进程当然也不是 host 的 init 进程

容器拥有自己独立的一套 PID,这就是 PID namespace 提供的功能

5、Network namespace

Network namespace 让容器拥有自己独立的网卡、IP、路由等资源

6、User namespace

User namespace 让容器能够管理自己的用户,host 不能看到容器中创建的用户

在容器中创建docker01用户,不会出现在host里面

在host中创建的zola用户,不会出现在容器中

create      创建容器  

run         运行容器  

pause       暂停容器  

unpause     取消暂停继续运行容器  

stop        发送 SIGTERM 停止容器  

kill        发送 SIGKILL 快速停止容器  

start       启动容器  

restart     重启容器  

attach      attach 到容器启动进程的终端  

exec        在容器中启动新进程,通常使用 "-it" 参数  

logs        显示容器启动进程的控制台输出,用 "-f" 持续打印  

rm          从磁盘中删除容器

详情请见,微信公众号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值