关于容器化的碎碎念

关于容器化的碎碎念

很有幸,公司云原生领域的大牛百忙之抽出时间给我团队做了扫盲,趁还没全忘了做个学习笔记,毕竟,每次都问,容易挨打…

容器化与虚拟化的恩怨情仇

**先说结论:**虚拟化分为容器级虚拟化与主机级虚拟化(传统虚拟化),容器无需独立虚拟操作系统,故性能、资源消耗、及运维难度都优于主机级虚拟技术,当然有利有弊,容器的封闭性和安全性低于主机虚拟,这个太高深了,就不深入讨论了。

看图说话,先上图:

image-20210602113919232

  • 主机虚拟:
    • 原理:通过Hpyervisor虚拟硬件环境,并据此安装虚拟操作系统。应用及应用运行所需依赖运行于虚拟操作系统上。
    • 感受:从用户角度看,真实主机操作基本一致
  • 容器虚拟(这里主要是Docker):
    • 原理:Docker Engine基于操作系统内核功能(以早期LXC LinuX Container 为例,使用NameSpaces以隔离硬件资源、使用Cgroups以实现资源的限制及约束。当然docker for Windows出现后,已经不限于Linux内核技术)分配及隔离出一组硬件资源,并在其内运行应用。
    • 感受:常用的场景是“运行无界面的后台服务”或者“运行Web服务”,运行图形界面这个事情,有人在尝试,但是不是主流,就不深入讨论了。如果有兴趣的话,感觉这篇文章写得还是很到位的:在Docker中运行桌面应用 - DockOne.io (dockerone.com)

核心组件

由浅入深,慢慢来,先聊聊核心组件

  • 镜像仓库(Docker Registry):容器仓库包括公有及私有两种,公有最常见的是docker Hub,私有化可以考虑用registry自己搭建。一个 Docker Registry 中可以包含多个 仓库Repository),每个仓库可以包含多个 标签Tag),每个标签对应一个镜像。

  • 镜像(Image):将应用及应用运行依赖的所有内容打包形成镜像,镜像只包含多个只读层(read-only Layer),这些层上下有序堆叠形成了镜像,当利用dockerfile 构建镜像时,每一条命令形成一个层,每一层只包含其下层不同的信息。

    docker file:用来构建docker的文本文件,速查可以考虑Dockerfile reference | Docker Documentation

    好玩的来了,在删除镜像时

    • 由于标签可定位唯一镜像,先取消该镜像对应所有标签(untagged),当判定该镜像所有标签都取消后,触发镜像删除行为,如果有特殊原因导致标签未取消,其实该镜像并未删除;
    • 由于镜像多层堆叠,如当前删除镜像被其他镜像依赖,其实其实该镜像并未删除;
    • 当镜被容器依赖时,其实该镜像不可删除。
  • 容器(Container):运行镜像成为容器后,在只读层中加入顶部可写层(container layer),容器运行时所有数据将写入此层,二当容器删除或终止时,该层数据被删除,如需保留该层数据或实现跨容器数据复用,可采用

    • volumes:容器数据存放于宿主机的一个特定目录下(/var/lib/docker/volumes/),该目录只有docker可以管理,其他进程不能修改。

    • bind mounts(不建议):容器内的数据被存放到宿主机任意位置,除了Docker之外的进程也可以任意对他们进行修改;

      主要的坑在于侵入宿主机文件系统,导致在不同宿主系统迁移出现问题,所以,还是要抽象一层的…

    • tmpfs mount:容器数据只会存放到宿主机的内存中

Docker 架构初解

还是老规矩,先上图(网图侵删):

img

  • Docker Client:客户用来与Docker Daemon建立通信的次抛型客户端(每次都需要通过Docker文件创建),,操作采用命令行模式(命令就不记录了,速查地址:Docker 命令大全 | 菜鸟教程 (runoob.com)
  • Docker Daemon:Docker的守护进程,也是Docker最为核心的后台进程,主要包括:
    • Server:负责接受Docker Client发送的请求;接受请求后,Server通过路由与分发调度,找到相应的Handler来执行请求;
    • Engine:扮演Docker container存储仓库的角色,并且通过执行job的方式来操纵管理这些容器。
      • Job:Engine内部最基本的工作执行单元。Docker可以做的每一项工作,都可以抽象为一个job,Job有一个名称,有参数,有环境变量,有标准的输入输出,有错误处理,有返回状态等。
  • Docker Registry:镜像仓库,可搜索镜像(Search)、下载镜像(Pull)及上传镜像(Push),镜像仓库可为公有云(Docker Hub),也可以自建私有化仓库。
    • 镜像:Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变(State Less)。
  • Graph:本地保存已下载镜像及其之间关系
  • Driver:驱动模块,以实现对Docker容器执行环境的定制
    • graphdriver:完成容器镜像的管理,包括存储与获取,当用户需要下载指定的容器镜像时,graphdriver将容器镜像存储在本地的指定目录,同时当用户需要使用指定的容器镜像来创建容器的rootfs时,graphdriver从本地镜像存储目录中获取指定的容器镜像。
    • networkdriver:完成Docker容器网络环境的配置,其中包括Docker启动时为Docker环境创建网桥;Docker容器创建时为其创建专属虚拟网卡设备;以及为Docker容器分配IP、端口并与宿主机做端口映射,设置容器防火墙策略等
    • execdriver:Docker容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。
  • libcontainer:Docker可以直接调用libcontainer,而最终操纵容器的namespace、cgroups、apparmor、网络设备以及防火墙规则等。这一系列操作的完成都不需要依赖LXC或者其他包
  • Container:Docker架构中服务交付的最终体现形式。Docker按照用户的需求与指令,订制相应的Docker容器:
    • 用户通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统;
    • 用户通过指定计算资源的配额,使得Docker容器使用指定的计算资源;
    • 用户通过配置网络及其安全策略,使得Docker容器拥有独立且安全的网络环境;
    • 用户通过指定运行的命令,使得Docker容器执行指定的工作。
  • rootfs:Linux根文件系统,特定的文件夹,文件夹之间的关系,即组织架构,以及特定的各种文件

一些不太冷的冷知识

1、你用的Docker其实不叫Docker:2017年开源Docker项目命名为Moby

2、Docker遵循的标准:为了避免Docker和rocket打架,共同成立了OCI,一个旨在管理容器标准的轻量级的、敏捷型的委员会

Dock执行分析

img

  1. Docker Client接受docker run命令,解析完请求以及收集完请求参数之后,发送一个HTTP请求给Docker Server,HTTP请求方法为POST,请求URL为”/containers/create? “+”xxx”;
  2. Docker Server接受以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler;
  3. mux.Router将请求路由分发至相应的handler,具体为PostContainersCreate;
  4. 在PostImageCreate这个handler之中,一个名为”create”的job被创建,并开始让该job运行;
  5. 名为”create”的job在运行过程中,执行Container.Create操作,该操作需要获取容器镜像来为Docker容器创建rootfs,即调用graphdriver;
  6. graphdriver从Graph中获取创建Docker容器rootfs所需要的所有的镜像;
  7. graphdriver将rootfs所有镜像,加载安装至Docker容器指定的文件目录下;
  8. 若以上操作全部正常执行,没有返回错误或异常,则Docker Client收到Docker Server返回状态之后,发起第二次HTTP请求。请求方法为”POST”,请求URL为”/containers/”+container_ID+”/start”;
  9. Docker Server接受以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler;
  10. mux.Router将请求路由分发至相应的handler,具体为PostContainersStart;
  11. 在PostContainersStart这个handler之中,名为”start”的job被创建,并开始执行;
  12. 名为”start”的job执行完初步的配置工作后,开始配置与创建网络环境,调用networkdriver;
  13. networkdriver需要为指定的Docker容器创建网络接口设备,并为其分配IP,port,以及设置防火墙规则,相应的操作转交至libcontainer中的netlink包来完成;
  14. netlink完成Docker容器的网络环境配置与创建;
  15. 返回至名为”start”的job,执行完一些辅助性操作后,job开始执行用户指令,调用execdriver;
  16. execdriver被调用,初始化Docker容器内部的运行环境,如命名空间,资源控制与隔离,以及用户命令的执行,相应的操作转交至libcontainer来完成;
  17. libcontainer被调用,完成Docker容器内部的运行环境初始化,并最终执行用户要求启动的命令。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值