容器看这一篇就够了

时间:2024-05-22 17:31:21


容器看这一篇就够了

专有名词

  • containerd是容器技术标准化之后的产物,为了能够兼容OCI(open container i)标准
    主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)
    理论上,即使不运行dockerd,也能够直接通过containerd来管理容器。(containerd也只是一个守护进程,实际运行时由runC控制。)
  • docker-shim是一个真实运行的容器的真实垫片载体,每启动一个容器都会起一个新的docker-shim的一个进程
  • runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现

创建container流程

  • docker Client 发送消息到 docker daemon
  • docker daemon 进行文件夹准备,各种文件参数的处理后发送 GRPC 消息
  • Containerd 的 GRPC Server 接收到消息并处理,生产一个 supervisor 的 StartTask 任务,并将其添加到supervisor的任务队中
  • Supervisor 的主函数对其进行简单处理后放入 startTask 队列
  • 该队里由supervisor的worker进行处理,worker中的最重生产 docker-containerd-shim命令行
  • 由shim进行执行,再生成Runc命令
  • 最终由Runc来执行容器中的的初始化进程并绑定Cgroup

容器的关键技术名词

容器是一种轻量级的虚拟技术,因为它跟虚拟机比起来,它少了一层 hypervisor 层

资源隔离和限制

对于容器来说,最重要的是怎么保证这个进程所用到的资源是被隔离和被限制住的,在 Linux 内核上面是由 cgroup 和 namespace 这两个技术来保证的。
namespace:

  • mout namespace,mout namespace 就是保证容器看到的文件系统的视图,是容器镜像提供的一个文件系统,也就是说它看不见宿主机上的其他文件,除了通过 -v 参数 bound 的那种模式,是可以把宿主机上面的一些目录和文件,让它在容器里面可见的。
  • uts namespace,主要是隔离了 hostname 和 domain。
  • pid namespace,这个 namespace 是保证了容器的 init 进程是以 1 号进程来启动的。
  • net namespace,除了容器用 host 网络这种模式之外,其他所有的网络模式都有一个自己的 network namespace 的文件。
  • user namespace,这个 namespace 是控制用户 UID 和 GID 在容器内部和宿主机上的一个映射,不过这个 namespace 用的比较少。
  • IPC namespace,这个 namespace 是控制了进程兼通信的一些东西,比方说信号量。
  • cgroup namespace,用 cgroup namespace 带来的一个好处是容器中看到的 cgroup 视图是以根的形式来呈现的,这样的话就和宿主机上面进程看到的 cgroup namespace 的一个视图方式是相同的。另外一个好处是让容器内部使用 cgroup 会变得更安全。

cgroups:
1、cgroups 主要是做资源限制的,docker 容器有两种 cgroup 驱动:一种是 systemd 的,另外一种是 cgroupfs 的。

  • cgroupfs 比较好理解。比如说要限制内存是多少,要用 CPU share 为多少,其实直接把 pid 写入对应的一个 cgroup 文件,然后把对应需要限制的资源也写入相应的 memory cgroup 文件和 CPU 的 cgroup 文件就可以了。
  • systemd 的一个 cgroup 驱动。这个驱动是因为 systemd 本身可以提供一个 cgroup 管理方式。所以如果用 systemd 做 cgroup 驱动的话,所有的写 cgroup 操作都必须通过 systemd 的接口来完成,不能手动更改 cgroup 的文件。

2、常用的cgroups

  • 第一个是 CPU,CPU 一般会去设置 cpu share 和 cupset,控制 CPU 的使用率。
  • 第二个是 memory,是控制进程内存的使用量。
  • 第三个 device ,device 控制了你可以在容器中看到的 device 设备。
  • 第四个 freezer,它和第三个 cgroup(device)都是为了安全的。当你停止容器的时候,freezer 会把当前的进程全部都写入 cgroup,然后把所有的进程都冻结掉,这样做的目的是,防止你在停止的时候,有进程会去做 fork。这样的话就相当于防止进程逃逸到宿主机上面去,是为安全考虑。
  • 第五个是 blkio,blkio 主要是限制容器用到的磁盘的一些 IOPS 还有 bps 的速率限制。因为 cgroup 不唯一的话,blkio 只能限制同步 io,docker io 是没办法限制的。
  • 第六个是 pid cgroup,pid cgroup 限制的是容器里面可以用到的最大进程数量

images

docker 镜像是基于联合文件系统的,所以它的存储驱动也是针对不同的文件系统作为定制的,比如 AUFS、btrfs、devicemapper 还有 overlay。docker 对这些文件系统做了一些相对应的一个 graph driver 的驱动,也就是通过这些驱动把镜像存在磁盘上面。

  • 存储流程
  • 文件操作

引擎

containerd

Runtimes 可以从类型区分,比如说 runC 或者是安全容器之类
容器看这一篇就够了