容器进阶看这一篇就够了


在这里插入图片描述

1、专有名词

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

2、前期回顾

cgroup
  • Linux内核提供的限制,记录和隔离进程组所使用的资源,被整合到kernel
  • 通过不同的子系统(blkio,cpu,cpuacct等)来实现对不同资源使用的控制和记录
Linux Namespace
  • pid 容器有自己独立的进程表和1号进程
  • net 容器有自己独立的network info
  • ipc 在ipc通信时候,需要加入额外信息来标示进程
  • mnt 每个容器有在即唯一的目录挂在
  • uct 每个容器有独立的hostname和domain
chroot

隔离根文件系统

Layer-StyleSystem
  • boot file system(bootfs),包含bootloader和kernal,在启动完成后,kernel在内存中,bootfs解除挂载
  • root file system(rootfs),包括类似/bin,/usr,等目录,这些和kernal无关,和不同的Linux分发版本有关
FS in Docker
  • 传统Linux启动时,将rootfs设置为readonly并检查完整性,然后设置成read-write
  • Docker在启动container的时候,也是把rootfs设置为readonly,然后通过aufs把一个readwrite的文件系统
    挂载到rootfs之上,并且把下层文件系统设置成readonly,这样构成一个完整的操作系统
Layer FS
  • 对于每一层readonly的FS,在docker中成为image
  • 对于顶上read-write的FS,称为container
  • 对于readonly中内容的修改,采用的是COW的技术,把文件复制到read-write层并改写,
    实际用户看到的是当前container层中的文件,image中的文件不会被影响
Image
  • 除了base image之外,每一层image都有一个parent image
  • 没有parent image的镜像叫base image
  • 基于COW的技术,image部分是不会被修改的,因此container可以共享image层的FS,提高了存储的效率
镜像命名和版本管理
  • base image是docker 官方提供的基础镜像
  • 普通镜像的命名规范{namespace}/{repository name}:{tag}
  • namespace是docker hub的用户明,实际是起到了namespace的作用
  • repository, 类似于github的项目,例如ubuntu,mysql等
  • tag,表示版本信息,例如cesc/mysql:5.5,tag是可选的,默认值是latest
运行Container
  • 运行一个container的本身就是开启一个具有独立namespace的进程
    sudo docker run [OPTIONS] IMAGE[:TAG] [COMMAND][ARG…]
COMMAND
  • Command标志的是在container中实际运行的首进程
  • 如果image里面包含了CMD的指令,那么在启动container的时候,不需要制定Command,
    否则会使用制定的Command来覆盖image中的CMD
  • 通过attach命令可以重新attach一个后来运行的container
  • 通过docker inspect {Container ID}来获取container 的更多的信息,
    包括网络,Volume, 实际在Host上的进程ID等信息
Network架构
  • 在Host主机上的一个veth{id}的虚拟网卡和一个container里面的eth0网卡一一映射
  • Host上的bridge负责把数据流在不同的veth间转发,实现网络的IO
  • bridge(docker0)使用RFC1918私有网络,给每个container分配IP

docker ps -a -q | xargs docker stop

网络设置
  • 通过 --net 参数来修改container的网络设置,默认是bridge的方式
  • none 表示关闭container的网络连接
  • host 表示使用主机的网络栈,这个时候host主机不会创建veth虚拟网卡映射
  • container:{name|id},使用另外一个container的网络栈
DNS
  • 默认使用host的DNS配置
  • 可以通过–dns的参数来制定container自己的dns配置
端口映射
目录映射
容器间通信
  • 通过Link参数,把container的端口信息暴露到另一个container中,实现container之间的通信
  • 云平台web应用需要链接上mysql的container,docker通过环境变量的方式把一个容器的信息写到
    另一个容器中
    docker run --name redis -dt ***/redis
    docker run --link redis:db -t ** sh -c "export db是个别名

2、创建container流程

宏观:

  • 检查本地镜像 没有就从仓库拉去 可调节配置
  • 分配一个文件系统,并在只读的镜像层外挂在一层可读写层
  • 从宿主机配置的网桥接口中桥接一个虚拟接口到容器
  • 从地址池中配置一个ip给容器
  • 执行用户制定的指令
  • 执行完毕后容器终止

微观:

  • 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

3、容器的关键技术名词

容器是一种轻量级的虚拟技术,因为它跟虚拟机比起来,它少了一层 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 的驱动,也就是通过这些驱动把镜像存在磁盘上面。
docker 镜像是基于 bootfs 之上的。

  • 存储流程
  • 文件操作

4、引擎

containerd

Runtimes 可以从类型区分,比如说 runC 或者是安全容器之类
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值