Jaccorot 日事日毕日清日高

深入理解k8s笔记

2020-12-04

容器基础

容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。

对于Docker等大多数Linux容器来说,Cgroups技术是用来制造约束的主要手段,而Namespace技术则是用来修改进程视图的主要方法。

隔离:Linux Namespace机制

Linux操作系统提供了PID、Mount、UTS、IPC、Network和User这些Namespace,用来对各种不同的进程上下文进行“障眼法”操作

  • PID Namespace

    在Linux系统中创建线程的系统调用是clone(),比如:

    int pid = clone(main_function, stack_size, SIGCHLD, NULL); 
    

    这个系统调用就会为我们创建一个新的进程,并且返回它的进程号pid。

    而当我们用clone()系统调用创建一个新进程时,就可以在参数中指定CLONE_NEWPID参数,比如:

    int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 
    

    这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的PID是1。

  • Mount Namespace

    • Linux容器文件系统: rootfs
      • rootfs只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核
      • 保证一致性
    • 切换进程的根目录(Change Root)
      • 优先使用pivot_root系统调用,如果系统不支持,才会使用chroot
    $ chroot $HOME/test /bin/bash
    
  • Network Namespace

限制:Linux Cgroups

Linux Cgroups的全称是Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。

简单来说,就是一个子系统目录加上一组资源限制文件的组合。

/sys/fs/cgroup

$ mount -t cgroup 
cpuset on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cpu on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
cpuacct on /sys/fs/cgroup/cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct)
blkio on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
memory on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
...


# 限制进程在长度为cfs_period的一段时间内,只能被分配到总量为cfs_quota的CPU时间。
$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_period_us  
100000
$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_quota_us   
20000
# 把被限制的进程的PID写入container组里的tasks文件
$ echo 226 > /sys/fs/cgroup/cpu/container/tasks 


#意味着这个Docker容器,只能使用到20%的CPU带宽。

分层镜像设计

  • 可读写层

    • 挂载方式为:rw
  • init层

    • Init层是Docker项目单独生成的一个内部层,专门用来存放/etc/hosts、/etc/resolv.conf等信息
    • 用户执行docker commit只会提交可读写层,所以是不包含这些内容的
  • 只读层

    • 挂载方式为:ro+wh,即readonly+whiteout

    • 修改时,在可读写层创建一个whiteout文件,把只读层里的文件“遮挡”起来

      比如,你要删除只读层里一个名叫foo的文件,那么这个删除操作实际上是在可读写层创建了一个名叫.wh.foo的文件。这样,当这两个层被联合挂载之后,foo文件就会被.wh.foo文件“遮挡”起来,“消失”了


Similar Posts