精华内容
下载资源
问答
  • 不跟风,容器技术的真实优、缺点
    千次阅读
    2020-12-03 14:55:45

     

    传统虚拟机 和 容器云的 真实 优缺点对比:

    (本文基于的前提:同样是在DevOps自动化程度很高的情况下。

        很多时候有人说 容器云平台更先进,那是因为他们传统的模式做得不好,如果把传统的模式做好,不见得比容器化平台的自动化程度低。)

     

    1、构建和部署方面

    传统的方案是:

    • a)使用支持虚机部署的DevOps平台,每个节点安装有agent,可以执行命令、上传文件等做很多事(参见阿里的 云效、StarAgent);

    • b)使用jenkins,功能很成熟、强大,可以自定义脚本,有很多现成的插件;

    • c)使用批量自动化工具,ansible,saltstack等。

    容器云方案:

    • a)使用容器云平台,但大多数都是商业版的,开源的选择不多,一般都用Rancher;

    • b)类似于DevOps平台的用法,编写pipline一键打包(实际上也是基于构建脚本和Dockerfile),上传到镜像仓库,然后基于kubernetes yaml定制化部署。

     

    总结:

        从构建和部署来说,容器云方案相比Jenkins等方案,优势并不明显,而且jenkins+脚本+插件,可以全方位操控打包过程和服务器,定制化程度比容器平台还高(因为它直接深入到OS内部执行命令,且整个过程集中自动化管理,而容器要在OS内部做操作,一般是在构建镜像时写在Dockerfile中、每个镜像单独管理,有过大规模实施的人都知道,Dockfile功能还是很鸡肋,而且不方便统一管理,很多构建编译过程,大家都倾向于在流水线上去实现,然而新兴容器平台的流水线,通常没有老牌的Jenkins那么成熟,特别是使用开源容器云平台,比如Rancher,很多时候不能满足需求,需要二次开发,相对而言,商业的容器云平台要好一点)。

     

    2、自动扩容和缩容

        自动扩容和缩容,通常的前提是无状态服务,且不要求固定IP。

        拿一个后管项目来说,它只部署一个节点,无扩容、缩容需求。

        再拿一个用户基础服务项目,当调用量大时,倒是可以扩容,传统方案是,前端挂载了负载均衡设备Nginx,做4层或7层转发,添加节点时要修改Nginx配置。有这种需求时,执行一下手动扩缩容,好像也不难。

        但是说实话,对于一般中小公司,自动“扩缩容”的需求还是很少,最多只是少数入口流量会爆发的地方才用得着。而使用运维自动工具和平台,手动扩容也很简单。

        只有一个问题,就是面对超大规模的系统,手工操作确实不合适。我认为,总体规模5000个节点以下,传统的运维自动化工具+虚拟机都很好做。真正的超大规模,可能是上万个节点,机房都有好几个那种。

     

    3、支持多种发布策略

        蓝绿发布、金丝雀(灰度)发布,蓝绿的话,重新部署一套,然后一键切换流量,使用传统方式也不难。金丝雀的话,先发布一小部分,关键是网络配置,重启nginx,也不难。分析同上,关键是服务器规模有多大。

     

    再来看看,有人总结的容器几大优点:

    1)更小的计算开销意味着更低的总体成本。

        的确,比起虚机独立操作系统而言,Docker更节省资源。

        但是Docker的资源隔离和控制,比起虚机有更高的学习成本。不可否则,虚拟机的隔离方法更成熟,更有效,就拿VMware厂商来说,它有很多很多的黑科技去优化资源使用,比如超额分配(后面会讲)。

    2)低风险的快速部署、移植

        没错,应用自带操作系统,在哪里都能运行。

        由于其高一致性,测试完了,直接推生产,不用考虑服务器环境问题,导致的和测试环境不一样。

        但是,有数据持久化需求怎么办,日志怎么处理,网络问题怎么解决,还有不少问题要解决,OS不能完全代表“可快速部署和移植”。

    3)运行环境更容易管理

        有利有弊。以前要修改服务器的东西,打补丁等,需要一个个虚拟机去操作,好处是,处理一个立即生效,应用不需要动。使用Docker,好处是只需要更新基础镜像,缺点是要生效,必须更新应用,更新应用意味着要停机重启。

     

    有人总结了4、5个优点,其实容器技术显著的优点只有两个:

        1、高资源利用率;

        2、标准化、可移植

    侧面印证:我们公司之前做了一个很正式的容器技术评估报告,列了一堆容器的优点、很全面,但实际上,很多都是自动化相关的,那是因为我们本身的自动化程度太低,而不能说是容器技术的优点;然后容器技术剩下的优点实际上就是我上面列的那两条。当时根据现有资源估算的结果是,使用容器只需要现有资源的1/4,可以节约75%的服务器成本(那也是因为,传统的虚机CPU和内存的利用率实在是太低!如果能好好管理和利用,实际上节约不到这么多,下面详细说明)。

        注意,资源利用率细节,相对于虚拟机,虚拟化Hypervisor层的开销是减少了,但整体并没有一些人说的那么夸张,比如节省75%,这要看具体情况。首先,容器通常是用的最小化操作系统,而虚拟机用的完整版系统,这样对比是不公平的,如果虚拟机也用最小化操作系统,其实也可以将系统内存控制在50MB以下,而容器如果使用完整版的系统,内存也能达到300MB以上。实际上,我们正式运行的容器,我看了一下,简单Java应用,也使用了2.2G内存,不见得比虚拟机要节省多少(虚拟机,你分配4G内存给它,实际上也不代表它一定独占4G物理内存)。

        值得一提,商业化的虚拟化平台,都支持超额分配,比如vSphere5.0+,每个物理内核(cores)最多支持25个vCPU,一个普通服务器有2颗CPU、总物理核数为2*12=24,按常规建议是1:1~1:3之间分配vCPU,可以分出48~144个vCPU,最高可以按1:25比例超额分配,但是在此Dell白皮书中,vCPU:pCPU 指导原则如下:

        1:1至3:1没有任何问题

        3:1至5:1可能会引发性能下降

        6:1或更高通常会引发问题

        无所谓,其实CPU通常是足够的,按照1:3分配就够了。内存才是瓶颈,内存分配有3种模式:Limit(上限),Reservation(保留,即私有)和 Shares(共享,即内存不够时,按设置的权重争抢)。很显然,内存是天然支持超额分配的,而且虚拟化平台的内存管理,有许多的优化技术(可参见VMware官方技术文档),应该是很成熟了。

        所以,我个人觉得,在相当一个大的物理服务器下,比如256G内存来说,从 极限 资源利用率 来看,Docker占不了多少便宜:假设我部署 48个应用,每个应用真实占用 4G内存,用Docker部署,操作系统占用50MB,Docker引擎占用100M,实际占用内存约为:48*(4G+50MB)+100MB,而换成虚拟机部署,假设Hypervisor引擎占用500MB,则实际占用内存约为:48*(4G+50MB)+500MB。虚拟机也就多占用了400MB内存而已。有些人可能会喷,用Docker就是要多分配一些应用啊,一个256G的物理服务器,怎么才止48个容器,Docker的场景是那种很微小的应用,一个占用0.5G的,可以分配512个容器!。好吧,就算这样,虚拟化平台难道不可以分配512个虚拟机?据我所知,是可以的(vCPU也就1:10),我阿里云的虚拟机就是1vCPU+1GB内存的,最小的好像是256MB内存,256MB内存的系统,你登录进去看,也还有200多MB的剩余,说明系统本身占用内存才几十MB。这里有篇文章,计算了各种配置的物理机,能够做的最大虚拟机数量:虚拟机服务器经典应用配置方案,可以看到,48核+256G内存的服务器,就可以分配400个左右的“微型”虚拟机。所以,我觉得,从资源利用率角度来讲,Docker和虚拟机差别不大,Docker并不是传说中的那样,一个物理机可以运行1000个容器,我们生产也不会这样做,我亲身实践过,我们也会控制一个物理节点分配容器的数量。但容器有一个潜在的优势,那就是它的管理太方便了,随时启停、随时创建和销毁,所以容器的资源利用更灵活,在频繁启停、创建和销毁服务器的场景中,其资源利用率确实大大高于虚拟机(举个很生动的例子:我们有一个Jenkins自动打包的服务器,如果同时有20个打包任务执行,服务器只有4C+8G配置,性能不够,需要加资源,方案1:创建20个2C+4G的虚拟机来分摊执行任务,方案2:创建20个2C+4G的容器来分摊执行任务,表面上看,两个方案最大的差别不在资源利用率,但是方案2,任务执行完,20个容器的资源就自动释放了,而方案1的虚拟机还占用着资源,这个时候的资源利用率,容器完胜,所以我说容器适合那种 频繁启停、创建和销毁服务器的场景)。

     

        容器技术的缺点:

    1) 有较高的学习成本(不是针对个人,而是针对整个研发及运维团队)

    2) 复杂度增加,引入了不少新东西,比如网络层面,引入Calico、Traefik等

    3) 某些应用有一定的改造成本,且不是所有应用都适合

    4) 增加基础环境的搭建和维护难度(自己维护Kubernetes等一系列环境组件)

    5) 抛弃传统成熟稳定的东西,用一堆新的东西,有一定技术风险(有较多bug,我遇到过最严重的一次是,K8s引起一个Linux内核错误,导致物理机直接死机)

     

    我再来总结一下,容器几大优点:

    1)高资源利用率;更小的计算开销意味着更低的总体成本。

            的确,比起虚机独立操作系统而言,Docker能节省一点点资源(5%~?,具体看情况)。

            更多的场景是,容器的灵活启停、创建和销毁,对资源的动态利用率,完胜虚拟机那种静态的方式。

    2)标准化、可移植;低风险的快速部署、移植

            没错,应用自带操作系统,在哪里都能运行。

            由于其高一致性,测试完了,直接推生产,不用考虑服务器环境问题,导致的和测试环境不一样。

    3)运行环境更容易管理

            自动调度,自动扩容和缩容,故障自愈,全方位监控。

    4)支持多种发布策略

            蓝绿发布、金丝雀(灰度)发布等非常容易。

     

        个人建议:

        容器技术的高资源利用率,标准化和可移植性,是难以抗拒的优点!!以至于为了具备这种优点,而不惜增加人力物力对容器技术的投入。如果公司本身的自动化程度很完善,短期内,就按传统的来,不急着应用容器。但是从长远来看,还是得想办法将容器技术运用起来。最初的应用,可以是和传统的技术进行融合,取长补短。等到对容器技术驾轻就熟之后,且全面胜过传统技术之后,方可深入全面应用。

     

     

     

    更多相关内容
  • docker 容器技术ppt

    2018-10-31 15:34:08
    docker内部培训的PPT,简介了docker容器技术的强大。为什么要使用docker容器技术
  • 《每天5分钟玩转Docker容器技术》是一个有关容器技术的教程,有下面两个特点: 系统讲解当前最流行的容器技术 从容器的整个生态环境到各种具体的技术,从整体到细节逐一讨论。 重实践并兼顾理论 从实际操作的角度...
  • 每天5分钟玩转Docker容器技术.pdf 每天5分钟玩转Docker容器技术.pdf
  • 每天5分钟玩转Docker容器技术.CloudMan(详细书签).zip 每天5分钟玩转Docker容器技术.CloudMan(详细书签).zip
  • 完整版 每天5分钟玩转Docker容器技术,高清 pdf,欢迎交流学习!
  • 这个是Docker虚拟化容器技术的介绍,有兴趣学习Docker的可以下载看看
  • 云时代的持续演进与云原生技术的发展, 容器整体市场的情况概述, 容器的发展前景 容器技术与场景 容器的新特性为云上业务发展提供紧身裤保障 容器与新技术及新场景的广泛整合。
  • 容器技术概述

    千次阅读 2022-01-08 10:12:30
    2.容器的内核技术组成 3.虚拟机和容器之间的区别 4.容器解决什么问题? 5.容器的分类 1.什么是容器 官方一点讲: 容器是一种沙盒技术,主要目的是为了将应用运行在其中,与外界隔离;及方便这个沙盒可以被...

    目录

    1.什么是容器

    2.容器的内核技术组成

    3.虚拟机和容器之间的区别

    4.容器解决什么问题?

    5.容器的分类

    6. 基本名称空间对比


    1.什么是容器

    官方一点讲:

    容器是一种沙盒技术,主要目的是为了将应用运行在其中,与外界隔离;及方便这个沙盒可以被转移到其它宿主机器。本质上,它是一个特殊的进程。通过名称空间(Namespace)、控制组(Control groups)、切根(chroot)技术把资源、文件、设备、状态和配置划分到一个独立的空间。

    通俗点的理解就是一个装应用软件的箱子,箱子里面有软件运行所需的依赖库和配置。开发人员可以把这个箱子搬到任何机器上,且不影响里面软件的运行。

    通俗点讲:

    现实中的容器就是用来装东西的

    linux中的容器:

    -linux中的容器是用来装应用的

    -容器就是将软件打包成标准化单元,用于开发,交付和部署,

    -容器技术已经成为应用程序封装和交付的核心技术

    2.容器的内核技术组成

    1)内核技术

    -Cgroups(Control Groups)-资源管理

    -SELinux 安全

    -NameSpace-名称空间

    2)Linux的NameSpace

    -UTS、NETWORK、MOUNT、USER、PID、IPC

    名称作用
    UTS隔离主机名
    NETWORK可以设置ip
    MOUNT可以支持文件系统
    USER可以支持用户
    PID可以查看不同的进程
    IPC可以在进程中发信号

    注:六个名称空间同用就非常的接近虚拟机

    3.虚拟机和容器之间的区别

    虚拟机

    通常包括整个操作系统和应用程序。还需要与他们一起运行的虚拟机管理程序来控制虚拟机。

    因为它们包括操作系统,因此它们的大小是几千兆字节( 1千兆字节= 1GB)。

    虚拟机的缺点:

    -是它们需要几分钟的时间才能启动操作系统,和初始化它们托管的应用程序。

    容器

    容器的优点

    1.敏捷环境:容器技术的最大优势是比创建VM(虚拟机)实例更快的速度。它们的轻量化在性能和占用空间方面的开销更小。

    2.提高生产力:容器通过消除跨服务依赖性和冲突来提高开发人员的生产力。每个容器都可以被看作是一个不同的微服务,因此可以独立升级,而不需要考虑它们的同步。

    3.版本控制:容器的每个镜像都可以进行版本控制,因此可以跟踪不同版本的容器,注意版本之间的差异等。

    4.计算环境可移植性:容器封装了运行应用程序所必需的所有相关细节,如应用程序依赖性和操作系统。这有助于简化容器镜像从一个环境到另一个环境的可移植性。例如,可以使用相同的镜像在Windows / Linux或dev(生产) / test(测试) / stage(阶段)环境中运行。

    5.标准化:大多数容器基于开放标准,可以运行在所有主要的Linux发行版,微软等。

    6.安全:容器将一个容器的进程与另一个容器以及底层基础架构隔离开来。因此,一个容器中的任何升级或更改都不会影响另一个容器。

    容器的缺点

    1.复杂性增加:使用n个容器运行一个应用程序,复杂性因素也随之增加。在生产环境中管理这么多的容器将是一项具有挑战性的任务。像Kubernetes和Mesos这样的工具可以用来管理n个容器。

    2.本机Linux支持:大多数容器技术(如Docker)都基于Linux容器(LXC)。因此,与在Linux上原生地运行这些实例相比,在微软环境下运行这些容器就显得有点麻烦了,它们的日常使用会带来复杂的问题。

    3.不成熟:容器技术在市场上相对较新,因此上市时间较慢。开发人员可用资源的数量是有限的,如果遇到一些问题,可能需要一些时间才能找出解决方案。

    4.容器解决什么问题?

    当应用程序计算环境发生变化时,许多问题都会出现。有可能是开发人员将代码从开发环境推送到测试环境,然后再继续。例如:开发人员在Windows中编写应用程序代码,但上层环境(测试,阶段或产品)是基于Linux的。在这种情况下,当操作系统发生变化时,某些功能可能会停止工作。所以,基本上,当配套的软件环境不一样的时候,间歇性故障的几率会更高。

    正如Docker的发明者Solomon Hykes所说:“你使用Python 2.7进行测试,然后在生产环境中运行Python 3,可能会发生一些奇怪的事情。或者你会依赖某个版本的一个SSL库,但是装了另外版本的SSL库。你在Debian上进行你的测试,生产环境是在RedHat上,可能发生各种奇怪的事情。

    这种变化可能不仅是计算环境,也可能是网络的变化。 Hykes还补充说:“网络拓扑结构可能不同,或者安全策略和存储可能不同,但是软件必须在其上运行。

    5.容器的分类

    操作系统容器

    根据维基百科,“操作系统级虚拟化是一种计算机虚拟化方法,其中操作系统的内核允许存在多个独立的用户空间实例,而不仅仅是一个,这种实例有时称为容器,虚拟化引擎(VEs)或监狱(jails)(FreeBSD jail或chroot jail),从运行程序的角度来看,它们可能看起来就像真正的计算机。

    如上所述,它们共享主机操作系统的内核,但提供用户空间隔离。不同的应用程序可以安装,配置,并可以运行,就像我们在主机操作系统上运行应用程序一样。同样,分配给容器的资源只对该容器可见。任何其他外来操作系统镜像将无法访问另一外来操作系统的资源。

    当需要配置一组具有相同配置的操作系统时,它们非常有用。因此,它有助于创建模板,这可以用来创建与另一个操作系统类似的风格。

    要创建OS(操作系统)容器,我们可以利用容器技术,如LXC,OpenVZ,Docker,Linux VServer,BSD JailsSolaris zones。

    应用程序容器

    根据维基百科,“应用程序虚拟化是一种软件技术,它将计算机程序从其执行的底层操作系统中进行封装。完全虚拟化的应用程序并不是按照传统的意义来安装的,尽管它仍然像以前一样被执行。应用程序在运行时表现得像是直接与原始操作系统及其管理的所有资源进行交互,但可以在不同程度上进行隔离或sandboxed(沙盒)处理。

    在这种情况下,术语“虚拟化”是指被封装的工件(应用程序),它与硬件虚拟化中的含义完全不同,它指的是被抽象的物件(物理硬件)。

    应用程序容器被设计为将服务作为单个进程打包和运行,而在OS容器中,可以运行多个服务和进程。

    像Docker和Rocket这样的容器技术就是应用程序容器的例子。

    6. 基本名称空间对比

    ## 主机名
    # 容器
    /]# hostname
    9de447fdef33
    # 真实服务器
    ~]# hostname
    VM-centos
    
    ## 进程
    # 容器
    /]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 07:53 pts/0    00:00:00 /bin/bash
    root        16     1  0 07:56 pts/0    00:00:00 ps -ef
    # 真实服务器
    ~]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 Jan06 ?        00:00:12 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    root         2     0  0 Jan06 ?        00:00:00 [kthreadd]
    root         4     2  0 Jan06 ?        00:00:00 [kworker/0:0H]
    root         6     2  0 Jan06 ?        00:00:03 [ksoftirqd/0]
    root         7     2  0 Jan06 ?        00:00:00 [migration/0]
    .....
    
    ## 文件系统
    # 容器
    /]# ls /
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    # 真实服务器
    ~]# ls / 
    bin  boot  data  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    
    ## 用户
    # 容器
     /]# cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
    systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
    # 真实服务器
    ~]# cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin
    libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
    rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
    ntp:x:38:38::/etc/ntp:/sbin/nologin
    abrt:x:173:173::/etc/abrt:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    chrony:x:997:995::/var/lib/chrony:/sbin/nologin
    tcpdump:x:72:72::/:/sbin/nologin
    syslog:x:996:994::/home/syslog:/bin/false
    展开全文
  • 容器技术之发展简史

    千次阅读 2020-10-16 13:36:20
    简介:容器技术催生了云原生思潮,云原生生态推动了容器技术发展。整理容器技术近 20 年的发展历史,大致可以将其分为四个历史阶段。作者 | 刘奖背景“云原生技术有利于各组织在公有云、私有云和混合云等新型动态...
    简介:容器技术催生了云原生思潮,云原生生态推动了容器技术发展。整理容器技术近 20 年的发展历史,大致可以将其分为四个历史阶段。

    1.png

    作者 | 刘奖

    背景

    “云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。”

    聊容器技术避不开云原生,聊云原生也避不开容器技术。容器技术和云原生就是一对双螺旋体,容器技术催生了云原生思潮,云原生生态推动了容器技术发展。从 2013 年 docker(container)技术诞生,到 2015 年 CNCF 这个云原生领域重量级联盟便成立,这不是历史的巧合而是历史的必然。作为云原生关键技术之一的容器,从 2013  年诞生以来一直是行业关注的焦点之一。借用一张业界广泛引用的云原生容器技术进阶图来了解一下容器技术和云原生诞生的历史背景。

    2.png

    先让我们一起来看看容器技术发展的历史纪年表,先直观感受一下这片如火如荼的热土吧!

    1979 年,Unix v7 系统支持 chroot,为应用构建一个独立的虚拟文件系统视图。
    1999 年,FreeBSD 4.0 支持 jail,第一个商用化的 OS 虚拟化技术。
    2004 年,Solaris 10 支持 Solaris Zone,第二个商用化的 OS 虚拟化技术。
    2005 年,OpenVZ 发布,非常重要的 Linux OS 虚拟化技术先行者。
    2004 年 ~ 2007 年,Google 内部大规模使用 Cgroups 等的 OS 虚拟化技术。
    2006 年,Google 开源内部使用的 process container 技术,后续更名为 cgroup。
    2008 年,Cgroups 进入了 Linux 内核主线。
    2008 年,LXC(Linux Container)项目具备了 Linux 容器的雏型。
    2011 年,CloudFoundry 开发 Warden 系统,一个完整的容器管理系统雏型。
    2013 年,Google 通过 Let Me Contain That For You (LMCTFY) 开源内部容器系统。
    2013 年,Docker 项目正式发布,让 Linux 容器技术逐步席卷天下。
    2014 年,Kubernetes 项目正式发布,容器技术开始和编排系统起头并进。
    2015 年,由 Google,Redhat、Microsoft 及一些大型云厂商共同创立了 CNCF,云原生浪潮启动。
    2016 年 - 2017 年,容器生态开始模块化、规范化。CNCF 接受 Containerd、rkt项目,OCI 发布 1.0,CRI/CNI 得到广泛支持。
    2017 年 - 2018 年,容器服务商业化。AWS ECS,Google EKS,Alibaba ACK/ASK/ECI,华为 CCI,Oracle Container Engine for Kubernetes;VMware,Redhat 和 Rancher 开始提供基于 Kubernetes 的商业服务产品。
    2017 年 - 2019 年,容器引擎技术飞速发展,新技术不断涌现。2017 年底 Kata Containers 社区成立,2018 年 5 月 Google 开源 gVisor 代码,2018 年 11 月 AWS 开源 firecracker,阿里云发布安全沙箱 1.0。
    2020 年 - 202x 年,容器引擎技术升级,Kata Containers 开始 2.0 架构,阿里云发布沙箱容器 2.0....

    整理容器技术近 20 年的发展历史,大致可以将其分为四个历史阶段,下文将详细介绍这四个历史阶段。

    3.jpg

    技术萌芽期

    容器技术需要解决的核心问题之一是运行时的环境隔离。

    容器的运行时环境隔离,目标是给容器构造一个无差别的运行时环境,用以在任意时间、任意位置运行容器镜像。由于 docker 的布道,大家习惯性认为容器的运行时环境隔离就是 OS 虚拟化,或者容器等于 namespace + cgroup + 安全防护机制。我不太赞同这种看法,这个只是一段历史时期、一种容器运行时的实现技术,还有很多种其它可能的技术方案来实现容器运行环境。所以,回到需求的本源:容器需要运行时隔离技术来保证容器的运行环境符合预期。习惯上,大家把这种实现容器隔离技术的组件叫做容器运行时。

    从另外一个角度看,容器隔离技术解决的是资源供给问题。为啥需要容器隔离技术来解决资源供给问题呢?成也萧何,败也萧何!摩尔定律实在太过强大,它让我们有了越来越多的计算资源可以使用。10 年前做小型机时,小型机的典型规格是 32 路 8 核 CPU,现在一台 4 路 PC 服务器计算能力都超过 10 年前的小型机服务器。小型机的典型用法是把整机切分为多个分区使用。观察当下云服务硬件发展趋势,越来越有熟悉的感觉,我们在把小型机相关技术“军转民”。现在我们一台 PC 服务器拥有了非常强大的、能和十年前小型机媲美的计算能力,巧合的是当下 PC 服务器的典型用法也和十年前的小型机用法类似,切割为 1-8vCPU 的虚拟机/容器使用。

    为什么人们总是习惯于把一个大的服务器资源切分为小的分区使用而不是研发能够充分发挥大型服务器整机计算能力的软件呢?个人认为背后有两个制约因素:

    • 待解决问题本身内在的并行度有限。随着多核多处理器系统的日益普及,IT 行业从 2004 年开始进行串行编程到并行编程的升级改造。开始阶段针对特定行业应用的并行化改造效果非常明显,但是后来发现随着并行度提高改造成本越来越大、收益却越来越低。受阿姆达尔定律制约,解决特定问题的并行度超过一定临界点之后收益将逐渐变小。所以一味提高系统并行度并不是经济的做法。
    • 人类智力有限。受人类智力限制,系统越复杂、并行度越高,软件越容易出故障,软件维护代价成指数级增长。所以,从软件工程看,大家也趋向于接口化、模块化、单元化的软件架构设计,尽量控制软件的复杂度,降低工程成本。

    从经验看,1-8 个 CPU 的并行度是软件工程的舒适区,这个也是容器化、微服务等技术背后的驱动因素之一。

    有点跑题了。。。总之,基于隔离的资源供给不是伪需求。对于软件运行环境的隔离要求,从操作系统出现之初就有了。多任务分时操作系统和进程虚拟地址都是为了解决多个任务运行在同一台主机上的资源共享问题,让每个进程都以为自己独占主机。当然仅仅是进程隔离是远远不够的。纵观当前的资源隔离技术,我们大致可以将资源隔离技术分成 5 类:

    4.jpg

    • 进程隔离。OS 以进程作为 Task 运行过程的抽象,进程拥有独立的地址空间和执行上下文,本质上 OS 对进程进行了 CPU 和内存虚拟化。但是进程之间还共享了文件系统、网络协议栈、IPC 通信空间等多种资源,进程之间因为资源争抢导致的干扰很严重。这个层级的隔离适合在不同的主机上运行单个用户的不同程序,由用户通过系统管理手段来保证资源分配与安全防护等问题。
    • OS 虚拟化。OS 隔离,也就是大家常说的操作系统虚拟化(OS virtualization),是进程隔离的升华版。进程隔离是为每个进程实现了单独的地址空间及 CPU 上下文,OS 隔离则是利用操作系统分身术为每一组进程实例构造出一个独立的 OS 环境,以进一步虚拟化文件系统、网络协议栈、IPC 通信空间、进程 ID、用户 ID 等 OS 资源。OS 隔离需要解决三个核心问题:独立视图、访问控制及安全防护。Chroot、Linux namespace 机制为进程组实现独立视图,cgroup 对进程组进行访问控制,而 Capabilities、Apparmor、seccomp 等机制则实现安全防护。当然,OS 是一个非常复杂、动态变化的系统,OS 分身术虽然让进程组感觉有了独立的 OS,但是真实实现还是一个 OS 实例,所以整体防护能力还是堪忧。
    • 硬件虚拟化。OS 虚拟化是实现 OS 内核的分身术,而硬件虚拟化则是实现硬件设备的分身术。硬件虚拟化技术的出现,让同一个物理服务器上能够同时运行多个操作系统,每个操作系统都认为自己在管理一台完整的服务器。不同操作系统之间是严格隔离的,Guest 操作系统对硬件的访问都是受 VMM 或 CPU 的严格监管的。硬件虚拟化既有很好的安全性,也有很好的隔离性,缺点就是引入的硬件虚拟化层导致了额外的性能开销。
    • 硬件分区。这个是传统小型机体系采用的资源分隔技术,就是从硬件或固件层彻底把一台大型服务器分隔为多个硬件单元,从而获得最高等级的安全性和隔离性。但是小型机作为一个逐步没落的技术路线,其不足之处还是显而易见的:资源分隔粒度不灵活、系统成本偏高、系统可扩展性受限。
    • 语言运行时隔离。对于 Java、nodejs 等需要 language runtime 的 managed language,我们还有一个选项,就是在 language runtime 里实现隔离。针对函数计算等云原生服务,理论上在语言运行时实现隔离机制是最优路径。但是这条路线目前实现上还有不少现实的制约,所以目前多数函数计算还是采用的容器 / VM 技术来实现的隔离。

    在 OS 虚拟化这条技术路线上,最大的技术贡献来源于 Google。

    2003 - 2006 年,Google 陆续发布的“三驾马车”,奠定了大数据计算的框架,随后进一步创造了“云”的概念。也是从这时期开始,进程隔离技术进入了一个更高级的阶段。在 Google 提出的云计算框架下,被隔离的进程不仅仅是一个与外界隔绝但本身却巍然不动的 Jail,它们更需要像一个个轻便的容器,除了能够与外界隔离之外,还要能够被控制与调配,从而实现分布式应用场景下的跨平台、高可用、可扩展等特性。

    2006 年,Google 推出 Process Containers,用来对一组进程进行限制、记账、隔离资源(CPU、内存、磁盘 I/O、网络等)。由于技术更加成熟,Process Container 在 2006 年正式推出后,第二年就进入了 Linux 内核主干,并正式更名为 Cgroups,标志着 Linux 阵营中“容器”的概念开始被重新审视和实现。

    在 2008 年,通过将 Cgroups 的资源管理能力和 Linux Namespace (命名空间)的视图隔离能力组合在一起,一项完整的容器技术 LXC (Linux Container)出现在了 Linux 内核中,这就是如今被广泛应用的容器技术的实现基础。

    总体看,在 2013 年 docker 被发明以前,Linux 操作系统已经大体上解决了容器核心技术之一的运行环境隔离技术,或者说 Linux OS 虚拟化技术已经基本上成型了。虽然容器运行环境隔离技术已经基本就位,我们仍需等待另外一项关键技术才能迎来容器技术的腾飞时刻。

    技术迸发期

    2013 年之前,云计算行业一直在为云原生的正确打开姿势而操心。Platform as a Service(PaaS)看起来是个有前途的方向。2006 年 Fotango 公司发布的 Zimi 服务,可以说是 PaaS 行业的鼻祖,具有按使用付费、免运维(Serverless)、API 化配置和服务等典型云原生的特征;2008 年 Google 推出 GAE;2011 年 Pivotal 发布 Cloud Foundry。这些早期的 PaaS 平台进行了非常有益的探索,推动了云计算生态的健康发展,但是这些早期探索技术并没有形成大的行业趋势,而是局限在一些的特定的领域。直到 Docker 开源,大家才如梦方醒,原来不是方向不对,而是应用分发和交付的手段不行。

    Docker 真正核心的创新是容器镜像(docker image),一种新型的应用打包、分发和运行机制。容器镜像将应用运行环境,包括代码、依赖库、工具、资源文件和元信息等,打包成一种操作系统发行版无关的不可变更软件包。

    • 容器镜像打包了整个容器运行依赖的环境,以避免依赖运行容器的服务器的操作系统,从而实现 “build once,run anywhere”。
    • 容器镜像一旦构建完成,就变成 read only,成为不可变基础设施的一份子。
    • 操作系统发行版无关,核心解决的是容器进程对操作系统包含的库、工具、配置的依赖,但是容器镜像无法解决容器进程对内核特性的特殊依赖。这个在实际使用容器的过程中也经常跳进这个大坑:

    Docker 的宣传口号是 “Build,Ship and Run Any App,Anywhere”。我们已经理解了 docker 通过container image 解决“Run Anywhere”的机制,那么“Run Any App”是如何实现的呢?其实也是依赖 container image,用户可以打包任何容器进程所依赖的环境,而不用改造应用来适配 PaaS 定义的运行环境。真是“Run Any App”一举打破了 PaaS 行业面临的困境,创造出了无限的可能性,大力推动了云原生的发展。让我们一起来向这个伟大的创意致敬!

    5.png

    至此,容器技术体系已经解决了最核心的两个问题:如何发布软件如何运行软件,腾飞时刻即将到来。2014 年前司前老板对我说“别成天搞 Linux kernel 了,要不你看看 docker?” 经过短暂的调研,我给了前老板一个简单而清晰的回答,“无它,唯打包工具尔!”因为这个回答,云原生为我打开的一扇大门就悄悄关上了。回想一下历史,有时也挺懊悔的,因为自己太年轻而没有看清楚容器技术 + 编排系统的威力,更没有体会到云原生即将到来的气息!

    Docker 作为一个单机软件打包、发布、运行系统,其价值是非常巨大的;但是仅仅将 docker 技术局限在单机范围不能发挥这个创新技术的最大价值,自然下一步业界希望基于 docker 技术构建一个云化的集群系统,来对业务容器进行编排管理。

    聊到容器编排系统,我们需要从 Google 聊起。2008 年,Google 基于 LXC 推出首款应用托管平台 GAE (Google App Engine),首次把开发平台当做一种服务来提供。

    GAE 是一种分布式平台服务,Google 通过虚拟化技术为用户提供开发环境、服务器平台、硬件资源等服务,用户可以在平台基础上定制开发自己的应用程序并通过 Google 的服务器和互联网资源进行分发。Google 在 GAE 中使用了一个能够对 LXC 进行编排和调度的工具 —— Borg (Kubernetes 的前身)。Borg 是 Google 内部使用的大规模集群管理系统,可以承载十万级的任务、数千个不同的应用、同时管理数万台机器。Borg 通过权限管理、资源共享、性能隔离等来达到高资源利用率。它能够支持高可用应用,并通过调度策略减少出现故障的概率,提供了任务描述语言、实时任务监控、分析工具等。如果说一个个隔离的容器是集装箱,那么 Borg 可以说是最早的港口系统,而 LXC + Borg 就是最早的容器编排框架。

    2013 年 docker 推出之后迅速席卷全球,2014 年 Google 基于内部使用的 Borg 系统创建了开源项目 Kubernetes(简称 K8s),用于解决大规模集群的容器部署、运行、管理等问题。Kubernetes 在容器的基础上增加了一层的新的管理抽象 Pod,以便更好地利用容器进行应用的功能模块切分。得益于 Google 在大规模集群基础设施建设的强大积累,脱胎于 Borg 的 K8s 很快成为了行业的标准应用,堪称容器编排的必备工具。

    作为回应,Docker 公司在 2015 年发布的 Docker 1.12 版本中也加入了一个容器集群管理系统 Docker swarm,以及配套的 Docker machine、Docker Compose 等工具,力图构建完善的容器编排系统,和 Kubernetes 展开正面竞争。从此,容器江湖分为两大阵营:Google 派和 Docker 派;而容器编排系统则是 Kubernetes,Docker Swarm 和 Apache Mesos 三国并立。各大派系的竞争愈演愈烈,逐渐延伸到行业标准的建立之争。让我们一起来回忆一下这段风起云涌的江湖历史吧!

    2013 年 Docker 公司推出 docker 之后,紧接着 CoreOS 应运而生。CoreOS 是一个基于 Linux 内核的轻量级操作系统,专为云计算时代计算机集群的基础设施建设而设计,拥有自动化、易部署、安全可靠、规模化等特性。其在当时有一个非常显眼的标签:专为容器设计的操作系统。借着 Docker 的东风,CoreOS 迅速在云计算领域蹿红,一时间,Docker + CoreOS 成为业内容器部署的黄金搭档。
    同时,CoreOS 也为 Docker 的推广与社区建设做出了巨大的贡献。然而,日渐壮大的 Docker 似乎有着更大的“野心”。不甘于只做“一种简单的基础单元”的 Docker,自行开发了一系列相关的容器组件,同时收购了一些容器化技术的公司,开始打造属于自己的容器生态平台。显然,这对于 CoreOS 来说形成了直接的竞争关系。2014 年末,CoreOS 推出了自己的容器引擎 Rocket (简称 rkt),试图与 Docker 分庭抗礼。rkt 和 Docker 类似,都能帮助开发者打包应用和依赖包到可移植容器中,简化搭环境等部署工作。rkt 和 Docker 不同的地方在于,rkt 没有 Docker 那些为企业用户提供的“友好功能”,比如云服务加速工具、集群系统等。反过来说,rkt 想做的,是一个更纯粹的业界标准。

    上面这段材料引至于“从虚拟化到云原生——容器技术的发展史”,为什么大段大段地引用这部分材料呢?这里面最关键的脉络是由于技术公司之间的商业竞争,在竞争合作之间寻找平衡从而导致了标准规范的诞生,而标准规范的诞生是整个云原生生态最重要的基石

    容器引擎(docker vs rocket)、容器编排(Docker swarm vs Kubernetes vs Apache Mesos)的相互竞争的结果就是大家坐下来谈接口标准。2015 年 6 月,Docker 带头成立 OCI,旨在“制定并维护容器镜像格式和容器运行时的正式规范(OCI Specifications)”,其核心产出是 OCI Runtime Spec(容器运行时规范)、OCI Image Spec(镜像格式规范)、OCI Distribution Spec(镜像分发规范)。所以 OCI 组织解决的是容器的构建、分发和运行问题

    一个月之后,Google 带头成立了 Cloud Native Computing Foundation(CNCF),旨在“构建云原生计算 —— 一种围绕着微服务、容器和应用动态调度的、以基础设施为中心的架构,并促进其广泛使用”。所以 CNCF 组织解决的是应用管理及容器编排问题。这两个围绕容器的基金会对云原生生态的发展发挥了非常重要的作用,二者不是竞争而是相辅相成,共同制定了一系列行业事实标准。这些行业事实标准的确立,各行业注入了无限活力,基于接口的标准的具体实现不断涌现,呈现出一片百花齐放的景象。

    6.jpg

    其中,与容器相关的最为重要的几个规范包括:CRI、CNI、CSI、OCI Distribution Spec、OCI Image Spec、OCI Runtime Spec 和 Shimv2。其中的 CRI、OCI Image Spec、OCI Runtime 和 Shimv2 规范和阿里云沙箱容器关系非常密切。

    所以,非常感谢这个云原生、容器技术迸发的黄金期,一群有创意的人走到一起共同创造了这几个关键的规范,为各个厂商提供各具特色且遵循规范的技术实现提供了可能性

    商用探索期

    经过 5 年的技术发展期,容器技术基本成熟,云原生体系也具雏型。从 2017 年开始,各大云厂商开始试水容器服务及进步的云原生服务。从目前的商业形态看,容器相关的公共云服务大致可以划分为三种形态:

    1. 通用容器编排服务。在容器编排系统三国杀结果出来以前,基于多方下注策略构建的容器编排服务系统。其中 AWS 是自研的编排系统,Azure 的 ACS 同时支持 Docker Swarm、DC/OS 和 Kubernetes,阿里云 ACS 则是支持 Docker swarm 和 Kubernetes。Google 和华为则是坚定支持 Kubernetes 而未推出支持其它容器编排系统的容器服务。随着 Kubernetes 一统容器编排江湖,这条路线的容器服务日渐式微,Azure 更是在今年初直接终止了 ACS 服务。
    2. Kubernetes 容器编排服务。Google 是理所当然最早试水 Kubernetes 容器编排服务的大厂,也较早开展了 K8s 容器编排服务。随着 2017 年各大厂在 CNCF 这张谈判桌上达成了 Kubernetes 兼容性认证流程,Kubernetes 编排服务市场迎来一轮大爆发,到 2018 年各大云厂商的 K8s 容器编排服务就完整就位了。
    3. Serverless 容器实例服务。从 2017 年开始,行业开始试水 Serverless 容器实例服务,把用户从维护容器基础设施的繁重任务中解放出来从而聚焦业务本身。Google Cloud Run 核心目标是支持 Knative,所以其使用形态上附加了不少约束条件。

    7.png

    从上图可以看出,从 2014 年开始探索公共云容器服务,特别是经过 2017 - 2018 年这两年的抢跑期,容器服务的基本商业形态已经比较明晰了。发展态势可以概括为:

    • 行业对容器化的接受程度已经很高,容器化普及率也是逐年提升。
    • 容器编排系统已经一战定江山,K8s 成为事实上的容器编排之王。
    • Serverless 容器实例服务受到市场的欢迎,客户群体日益扩大。
    • 长期看托管容器编排服务和 Serverless 容器实例服务将长期共存,协同满足客户对服务成本和弹性能力的需求。

    商用模式探索期间,核心目标是快速试错引导和确认客户需求,构建适用的产品形态。这个期间的产品技术架构的构建思路是利用现有成熟技术快速搭建商用形态,在试错过程中不断前行。

    其中,容器编排托管服务节点级的典型架构是利用 IaaS 系统生成 VM,然后在 VM 里面部署 kubelet、docker、containerd、runC 等容器服务组件,也就是 VM + 容器的技术架构。一个 VM 可以承载同一个用户的多个容器 / Pod 实例。而 Serverless 容器实例服务的节点级架构更直接,在一个 VM 里面只部署一个容器 / Pod 实例,从而实现 Serverless。这种短平快的打法快速推进了商用模型的探索,起到了非常重要的历史作用,但是其在弹性能力、部署密度、资源成本方面的历史局限性还是很大的。

    8.jpg

    商用拓展期

    到 2019 年,容器服务的商业形态以及市场趋势已经很明显了,行业整体进入了商业拓展阶段,对外宣传吸引更多的客户群体,对内苦练内功提升产品技术竞争力,行业正在经历从“有”到“优”的技术升级。行业正在经历这个技术升级的历史阶段,还谈不上结论,只能一起来聊聊趋势及预判。本系列专题的关注点是容器隔离技术,所以先不聊商业拓展和容器编排而聚焦于容器引擎技术发展趋势。到现在为止,我们大体上可以把容器引擎技术划分为两代:

    1. Container on VM。也就是按照分层设计思路,通过 IaaS + PaaS 的架构构建容器服务,这个是商用探索阶段的典型架构。基于各大云厂商成熟的 IaaS 基础设施生产虚拟机,在虚拟机里面部署容器服务组件。这种架构采用的是 lift and shift 策略,把容器服务的运维责任从用户转移到云厂商。采用和用户相同的软件组件,只是转移运维责任,有利于引导客户逐步上云、接受云原生思维。但是这个时期云厂商提供的服务是单纯的运维托管,相对用户自建容器服务并没有太明显的技术优势,甚至受多租户隔离的限制部分使用体验还不如用户自建容器服务
    2. Container with hardware virtualization。如果沿用 Container on VM 的分层设计架构,云厂商很难构建独有的技术优势。对于 Serverless 容器实例服务,服务交付平面已经从 IaaS 的硬件接口上移到 OS Syscall,所以不要遵循 VM + 容器的分层设计思路。我们需要从需求本源出发,容器服务需要高性能、强隔离、够安全和低成本的容器引擎。当前行业研发热点之一就是如何构建这样一个容器引擎,具体技术思路请留意后续系列文章。

    小结

    总结来看,容器服务生态大概经历了四个阶段,分别解决或试图解决不同的问题:

    1. 技术萌芽期:解决了容器运行环境的隔离问题
    2. 技术迸发期:解决了软件分发及容器编排问题
    3. 商用探索期:确认了容器的商用服务形态
    4. 商用拓展期:扩大适用场景和部署规模,通过技术创新提升产品竞争力

    闲言碎语

    聊了这么多历史,让我们再来闲聊一下 docker 这个公司和 docker 这门技术吧!

    2019 年 11 月 13 日,私有云基础设施公司 Mirantis 在其官方博客宣布,收购 Docker 公司企业级业务,包括接管它的 700 多个客户,这标志着 Docker 公司从 2013 年开始的商业化探索彻底失败。在不了解容器发展历史的人看来,这种结果很难理解,Docker 是容器热潮的开创者,容器则是这一轮云计算技术演进的开启者,为什么明明站在风口上了,却仍然飞不起来?

    其实,Docker 今天的命运,在 4 年前就决定了。

    2014 年 Kubernetes 发布后,迅速吸引了包括 Redhat 在内的一批重量级成员,并在一年之后迅速发布 Kubernetes 1.0 以支撑正式商用。作为回应 Docker 公司主导成立了 OCI,旨在为容器镜像格式和运行时制定一个开放标准,从而继续占据容器生态的话语权。但是 2015 年 7 月 CNCF 成立之后,迅速弯道超车开辟新的战场,主攻容器编排与应用管理。随后 2016 年 Kubernetes 社区制定了容器运行时的接口规范 CRI,只要实现这个 CRI 规范的容器运行时就可以和 K8s 生态对接,从引发了容器引擎的研发热潮。cri-containerd,cri-o,frakti 等引擎不断涌现,加上原有的 rkt 引擎,docker 变成了容器引擎芸芸众生中的一员。从哪儿来到哪儿去,docker 又回到了最初的状态,一个单机版软件打包运行工具,基本上完美错过了云原生浪潮。

    但是在相当长的时期内,docker 这个客户端容器管理工具(UI)还是会长期存在的,毕竟强大的用户群体在哪儿。但是在云服务厂商的技术栈中,docker 的地位会越来越弱,逐步被 K8s 专用的容器引擎替代。虽然现在 docker 的群众基础依然强大,但是星星之火已经点燃,趋势已然显现,剩下的只是时间问题!

    参考文献

    课程推荐

    去年,CNCF 与 阿里云联合发布了《云原生技术公开课》已经成为了 Kubernetes 开发者的一门“必修课”。
    今天,阿里云再次集结多位具有丰富云原生实践经验的技术专家,正式推出《云原生技术实践公开课》。课程内容由浅入深,专注讲解“ 落地实践”。还为学习者打造了真实、可操作的实验场景,方便验证学习成果,也为之后的实践应用打下坚实基础。点击链接查看课程:https://developer.aliyun.com/learning/roadmap/cloudnative2020

    阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

    原文链接:https://developer.aliyun.com/article/775778?

    版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
    展开全文
  • 容器技术已然成为企业数据中心的标配技术,企业通过容器技术尝试快速交付业务,然而事实上仍未达到容器技术在企业中迅速铺开的阶段。如何通过高效可靠的容器技术,帮助企业迅速实现内部存量应用的容器化,以及提供...
  • 虽然云原生到底包括哪些概念和技术并没有一个公认的答案,但容器技术是云原生的基础和核心应该是现阶段的一个共识。 但是容器技术经过多年的发展和演变,各种实现方案和早期版本相比已经有了巨大的差异,而且仍然在...

    云原生的概念在最近两年得到了广泛的关注,各大云厂商和技术团队都纷纷推出了各种“云原生”的技术和产品。虽然云原生到底包括哪些概念和技术并没有一个公认的答案,但容器技术是云原生的基础和核心应该是现阶段的一个共识。

    但是容器技术经过多年的发展和演变,各种实现方案和早期版本相比已经有了巨大的差异,而且仍然在不断演进的过程中。各种组件的产生、随之而来的接口规范、基于接口规范实现的新可选组件让相关的名称和概念更加复杂。新的开发使用者很难全面理解容器相关的各类名词和概念,以及这些名词和概念在真实的容器部署环境中的作用和关系。

    笔者作为容器运行时开发人员,对于容器相关的概念仍然经常犯迷糊。docker、libcontainer、containerd、shim、runc分别起什么作用?CRI、OCI是什么层次的规范、有什么区别?各个组件的功能和协作方式是怎样的?使用k8s管理容器后相关组件和结构又有怎样的变化?这些问题经常让笔者困扰。这篇文章将尝试将这些问题做一个全面的回答,尽量完整的解释相关的名词,从而对容器的具体实现和部署有一个全面的认识。为了更清晰的说明容器概念和技术的当前状态,避免混淆,本文将尽量避免对容器技术历史版本的具体概念和架构做详细介绍。

    一、docker相关概念和组件

    容器技术并不是从docker才开始出现的,docker最主要的三项特性:镜像化、空间隔离和资源隔离,其对应的技术unionfs、namespace和cgroup在docker技术出现前就已经在linux内核中工作了很多年。lxc(linux container)是最早组合使用这些技术来实现容器的,docker的早期版本干脆就是基于lxc实现的namespace和cgroup管理。但docker确实是让容器化部署变得真正可用、易用的关键技术,在docker出现后,容器技术才真正成为一种高效的业务部署模式而被广泛使用。到目前为止,docker(系列技术和组件)仍然是使用最广泛的容器技术和容器领域的事实标准。

    经过长期演变,docker从最初的单个整体模块变成了多个通过标准接口协同工作的多个模块。在不同的使用场景下(例如k8s部署场景),使用到的模块会有所不同。这一节首先分析一下使用docker创建运行容器时涉及到的组件和组件间的关系。

    上图展示了docker运行容器时的主要组件和组件间的关系。(图片来自https://www.cnblogs.com/sparkdev/p/9129334.html,本文参考了博客作者sparkdev的多篇相关文章)

    组件包括:

    docker:docker既是整套技术和产品的名称,又是其中一个组件的名称。到今天,docker组件只是一个最外围的入口,为使用者提供一种命令行形式的客户端(CLI)来执行容器的各种操作,使用golang实现。docker客户端将用户输入的命令和参数转换为后端服务的调用参数,通过调用后端服务来实现各类容器操作。

    这个组件其实是可替代性最强的组件,有很多的替代性实现,例如各种其他语言的docker客户端和库。这个客户端组件使用docker这个名称是为了和最早期的docker使用习惯保持一致。在docker的早期实现中,所有功能都实现在一个二进制程序docker中,docker既能作为客户端,又能作为服务端,所有操作都是基于docker程序完成的。

    dockerd:dockerd是运行于服务器上的后台守护进程(daemon),负责实现容器镜像的拉取和管理以及容器创建、运行等各类操作。dockerd向外提供RESTful API,其他程序(例如docker客户端)可以通过API来调用dockerd的各种功能,实现对容器的操作。但时至今日,在dockerd中实现的容器管理功能也已经不多,主要是镜像下载和管理相关的功能,其他的容器操作能力已经分离到containerd组件中,通过grpc接口来调用。又被称为docker enginedocker daemon

    containerd:containerd是另一个后台守护进程,是真正实现容器创建、运行、销毁等各类操作的组件,它也包含了独立于dockerd的镜像下载、上传和管理功能。containerd向外暴露grpc形式的接口来提供容器操作能力。dockerd在启动时会自动启动containerd作为其容器管理工具,当然containerd也可以独立运行。containerd是从docker中分离出来的容器管理相关的核心能力组件,https://www.docker.com/blog/docker-containerd-integration/https://www.docker.com/blog/what-is-containerd-runtime/介绍了将其从docker中独立出来的原因(虽然基于这两篇文章笔者还是没太看懂这个操作在当时的必要性...)。但是为了支持容器功能实现的灵活性和开放性,更底层的容器操作实现(例如cgroup的创建和管理、namespace的创建和使用等)并不是由containerd提供的,而是通过调用另一个组件runc来实现。

    runc:runc实现了容器的底层功能,例如创建、运行等。runc通过调用内核接口为容器创建和管理cgroup、namespace等Linux内核功能,来实现容器的核心特性。runc是一个可以直接运行的二进制程序,对外提供的接口就是程序运行时提供的子命令和命令参数。runc内通过调用内置的libcontainer库功能来操作cgroup、namespace等内核特性。

    可以看到从docker cli、dockerd、containerd到runc,这些组件都号称提供了容器操作能力,但上层组件提供的可能只是接口封装、状态展现相关的能力,而下层组件则负责更基础、更核心的内核功能调用、底层功能实现。虽然不太容易清楚的区分各层组件提供的具体能力,但将这些层次想象成软件设计中的功能抽象、接口封装和底层实现就能大体理解这些组件间的关系和拆分成多个组件的原因。

    containerd-shim:除了这些主要组件外,图中还有containerd-shim这个组件。containerd-shim位于containerd和runc之间,当containerd需要创建运行容器时,它没有直接运行runc,而是运行了shim,再由shim间接的运行runc。据开发者介绍(https://groups.google.com/g/docker-dev/c/zaZFlvIx1_k?pli=1),shim主要有3个用途:

    1. 让runc进程可以退出,不需要一直运行。这里有个疑问,为了让runc可以退出所以再启动一个shim,听起来似乎没什么意义。我理解这样设计的原因还是想让runc的功能集中在容器核心功能本身,同时也便于runc的后续升级。shim作为一个简单的中间进程,不太需要升级,其他组件升级时它可以保持运行,从而不影响已运行的容器。

    2. 作为容器中进程的父进程,为容器进程维护stdin等管道fd。如果containerd直接作为容器进程的父进程,那么一旦containerd需要升级重启,就会导致管道和tty master fd被关闭,容器进程也会执行异常而退出。

    3. 运行容器的退出状态被上报到docker等上层组件,又避免上层组件进程作为容器进程的直接父进程来执行wait4等待。这一条没太理解,可能与shim实现相关,或许是shim有什么别的方式可以上报容器的退出状态从而不需要直接等待它?需要阅读shim的实现代码来确认。

    除了上述组件,还有一些相关名称和概念值得一提。

    lxc:上文中提到,lxc是最早的linux容器技术,早期版本的docker直接使用lxc来实现容器的底层功能。虽然使用者相对较少,但lxc项目仍在持续开发演进中。

    libcontainer:docker从0.9版本开始自行开发了libcontainer模块来作为lxc的替代品实现容器底层特性,并在1.10版本彻底去除了lxc。在1.11版本拆分出runc后,libcontainer也随之成为了runc的核心功能模块。

    moby:moby是docker公司发起的开源项目,其中最主要的部分就是同名组件moby,事实上这个moby就是dockerd目前使用的开源项目名称,docker项目中的engine(dockerd)仓库现在就是从moby仓库fork而来的。

    docker-ce:docker的开源版本,CE指Community Edition。docker-ce中的组件来自于moby、containerd等其他项目。

    docker-ee:docker的收费版本,EE指Enterprise Edition。其基础组件来源和docker-ce是一样的,但附加了一些其他的组件和功能。docker-ee只能在一些企业版操作系统或云计算平台中使用,相关的资料也很少见,应该没有多少使用者。https://medium.com/devops-dudes/2020-differences-between-docker-ce-and-ee-abd10b646597中对其做了一些介绍,并将其称作“docker公司垂死挣扎的挣钱手段”。。。

    二、kubernetes引入的相关概念和组件

    kubernetes:kubernetes(简写为k8s)是google开源的容器编排、部署、运维系统。k8s的目标是更清晰便捷的使用和管理容器,因此其功能是构建在docker等容器技术之上的。这里我们只讨论k8s与容器技术相关的部分概念,而不对k8s本身的概念和组件做过多探讨。

    上图是k8s在单个节点上的容器运行架构。可以看到,上图中除了已经介绍过的docker相关组件dockerd、containerd、containerd-shim、runc之外,还多了kubelet和dockershim两个组件。

    kubelet:kubelet是k8s在单机节点上的服务进程,负责为k8s系统管理这台节点上的容器。k8s系统对容器的创建、删除等调度行为都需要通过节点上的kubelet来完成。

    dockershim:kubelet并没有直接和dockerd交互,而是通过了一个dockershim的组件间接操作dockerd。dockershim提供了一个标准的接口,让kubelet能够专注于容器调度逻辑本身,而不用去适配dockerd的接口变动。而其他实现了相同标准接口的容器技术也可以被kubelet集成使用,这个接口称作CRI。dockershim和CRI的出现也是容器生态系统演化的历史产物。在k8s最早期的版本中是不存在dockershim的,kubelet直接和dockerd交互。但为了支持更多不同的容器技术(避免完全被docker控制容器技术市场),kubelet在之后的版本开始支持另一种容器技术rkt。这给kubelet的维护工作造成了巨大的挑战,因为两种容器技术没有统一的接口和使用逻辑,kubelet同时支持两种技术的使用还要保证一致的容器功能表现,对代码逻辑和功能可靠性都有很大的影响。为了解决这个问题,k8s提出了一个统一接口CRI,kubelet统一通过这个接口来调用容器功能。但是dockerd并不支持CRI,k8s就自己实现了配套的dockershim将CRI接口调用转换成dockerd接口调用来支持CRI。因此,dockershim并不是docker技术的一部分,而是k8s系统的一部分。

    在2020年12月,k8s宣布从其1.20版本开始将默认不再使用dockershim,并将在后续版本中删除dockershim。这也意味着kubelet不再通过dockerd操作容器,docker这个名词不再直接出现在k8s官方生态中。但kubelet仍然基于来自于docker的containerd、runc等组件,因此其底层容器管理逻辑并没有很大的变化。其组件架构变化如下图:

    可以看到,在新的架构中,kubelet直接与containerd交互,跳过了dockershim和dockerd这两个步骤。containerd通过其内置的CRI插件提供了CRI兼容接口。

    cri-containerd:在k8s和containerd的适配过程中,还曾经出现过cri-containerd这个组件。在containerd1.0版本中,containerd提供了cri-containerd作为独立进程来实现CRI接口,其定位和dockershim类似。但在containerd1.1版本中,就将这个功能改写成了插件形式直接集成到了containerd进程内部,使containerd可以直接支持CRI接口,cri-containerd也就成了历史名词,其repo(https://github.com/containerd/cri)也被合入了containerd,作为其一个内置插件包存在(github.com/containerd/containerd/pkg/cri)。

    三、容器运行时相关标准和概念

    在上文中已经出现了两种接口标准:CRI和OCI。

    这两种接口标准的出现使容器技术的组件化和标准化成为了可能,也随之产生了大量符合接口规范的不同容器实现技术,很大程度上促进了容器技术的发展和市场的繁荣。

    CRI:CRI是Container Runtime Interface(容器运行时接口)的缩写。如上文所述,它是k8s团队提出的容器操作接口标准,符合CRI标准的容器模块才能集成到k8s体系中与kubelet交互。符合CRI的容器技术模块包括dockershim(用于兼容dockerd)、rktlet(用于兼容rkt)、containerd(with CRI plugin)、CRI-O等。

    rkt与rktlet:rkt是CoreOS公司主导的容器技术,在早期得到了k8s的支持成为k8s集成的两种容器技术之一。随着CRI接口的提出,k8s团队也为rkt提供了rktlet模块用于与rkt交互,rktlet和dockersim的意义基本相同。随着CoreOS被Redhat收购,rkt已经停止了研发,rktlet已停止维护了。

    CRI-O:CRI-O是Redhat公司推出的容器技术。从名字就能看出CRI-O的出发点就是一种原生支持CRI接口规范的容器技术。CRI-O同时兼容OCI接口和docker镜像格式。CRI-O的设计目标和特点在于它是一项轻量级的技术,k8s可以通过使用CRI-O来调用不同的底层容器运行时模块,例如runc。

    OCI:OCI是Open Container Initiative(开放容器倡议)的缩写。OCI是以docker为首的容器技术公司创建的组织,也是这个组织制定的容器相关标准的统称。OCI标准主要包括两部分:镜像标准和运行时标准。符合OCI运行时标准的容器底层实现模块能够被containerd、CRI-O等容器操作模块集成调用。runc就是从docker中拆分出来捐献给OCI组织的底层实现模块,也是第一个支持OCI标准的模块。除了runc外,还有gVisor(runsc)、kata等其他符合OCI标准的实现。

    gVisor:google开源的一种容器底层实现技术,对应的模块名称是runsc。其特点是安全性,runsc中实现了对linux系统调用的模拟实现,从而在用户态实现应用程序需要的内核功能,减小了恶意程序通过内核漏洞逃逸或攻击主机的可能性。

    kata:Hyper和Intel合作开源的一种容器底层实现技术。kata通过轻量级虚拟机的方式运行容器,容器内的进程都运行在一个kvm虚拟机中。通过这种方式,kata实现了容器和物理主机间的安全隔离。

    容器运行时:最后讨论一下容器运行时的概念。在前文中,笔者尽量避免使用“容器运行时”这个名词,因为这个名词从容器技术出现开始就被用来描述各种容器技术,已经无法作为一个精确的技术名称使用了。docker是容器运行时,dockershim是容器运行时,containerd是容器运行时,runc还是容器运行时。大体上,容器运行时这个名词相当于是“容器技术的某种具体实现”这么一个模糊概念。在CRI和OCI标准的名称中,也都说明自己是容器运行时的标准,但很显然两者约束的对象不是同一层次的。大体上,我们可以把符合CRI接口的这类容器运行时称作高层容器运行时,这类运行时技术提供容器的创建、运行、删除等高层功能接口。而符合OCI接口的运行时则称作底层容器运行时,这类运行时技术真正调用各类内核特性、实现容器在操作系统中的运行和管理。笔者个人认为后者更符合运行时的概念,毕竟真正让容器运行起来的正是这些底层实现技术。

    小结

    本文总结了笔者所了解的主要容器相关技术概念。可以看到容器技术是一项快速发展中的技术,不同的技术不断出现、演化和消亡。很多技术形态和标准都是历史演化和商业斗争的产物,小型技术创业公司如docker、CoreOS和技术巨头如Google、Redhat在容器生态的建设中起到了不同维度的作用。这篇文章介绍的概念可能很快会过时或不完整,需要持续的跟进容器和云原生技术的发展来保持相关知识的时效性。

    展开全文
  • 容器技术在分布式系统应用

    千次阅读 多人点赞 2020-05-29 16:14:30
    不止容器的封装特性所带来的天然对象化,在更高层对容器的编排技术也能体现这种思想。从火热的容器编排(k8s)中的各类 API 对象我们处处都能看到"对象"思想的落地。 基于容器的分布式系统三种设计模式: 用于管理...
  • 云计算技术:容器技术概述

    千次阅读 2021-12-16 10:26:48
    容器技术为基础,开放诸如CPU、内存这些基本资源而不是虚拟机。是对传统数据中心资源分配粒度的变革。 IT资源分配发展趋势: IT资源分配发展经历了从裸机时代到虚拟机时代到如今的容器时代。 容器与虚拟机 ...
  • @Container容器技术大会是由国内容器社区DockOne组织的专为一线开发者和运维工程师设计的顶级容器技术会议,会议强调实践和交流,话题设置围绕容器、运维、云计算等技术领域,力求全方位、多角度为参会者解读容器...
  • 每天5分钟玩转Docker容器技术 Docker容器技术 每天5分钟玩转Docker CloudMan
  • 容器技术的概念

    千次阅读 2019-11-18 16:58:04
    容器技术是英文单词Linux Container的汉译。Linux Container两个单词,第一个Linux表明了容器技术一般是应用在Linux操作系统上面;Container意思有:容器,集装箱,货柜的意思,为了方便理解,这里采用集装箱的汉译...
  • 嵌入式Linux容器技术

    千次阅读 2019-08-13 14:59:21
    嵌入式Linux容器技术 一、Linux容器技术 Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。 LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,...
  • 对虚拟化和容器技术的理解总结

    千次阅读 2020-06-09 17:19:58
    因为项目需求,最近在学习虚拟化和容器技术,在网上看到了很多关于这方面的知识,所以在这里写一篇博客简单总结一下这段时间学习的收获。 虚拟化 虚拟化技术其实是一种将计算机物理资源进行抽象、转换为虚拟的...
  • 文章目录资源隔离的两种主要方案虚拟机VS容器容器技术的资源隔离从容器到Docker 资源隔离的两种主要方案   在服务器或者大型计算机集群中,往往需要运行大量作业和应用,为保证这些作业和应用的进程之间互不干扰,...
  • docker容器技术

    千次阅读 2019-05-30 13:22:35
    容器技术是一种应用程序封装和交付的核心技术 容器技术的核心由以下几个内核技术组成: (1)Cgroups(Control Groups):资源管理 (2)NameSpace:进程隔离 a. 主机名称隔离 b. 网络隔离 c. 文件系统隔离 d. ...
  • 为什么需要容器技术

    千次阅读 2018-08-08 10:54:47
    1 前言 2 容器使用场景 3.对比容器和虚拟机 3.1 轻量的原因 3.2 容器局限性 3.3 容器优势 ...为什么容器技术这么受欢迎?它的使用场景到底在哪里?翻阅了一些资料之后,我得到了下面的结论。 ...
  • 技术盘点:容器技术的演进路线是什么?未来有哪些想象空间?
  • 十分钟明白什么是容器技术

    千次阅读 2018-07-06 14:40:51
    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由宝哥@devops运维 发表于云+社区专栏 一、什么是容器? ...容器这个词,当你第一眼看它...其实,IT里的容器技术是英文单词Linux Container的直...
  • 传统的云计算是基于虚拟机技术的,而容器技术解决了虚拟机原来解决不了的问题。 云计算主要解决的是资源弹性的问题,感兴趣的可以看历史文章《不懂技术也能看懂云计算,大数据,人工智能》。 所谓资源,主要是指...
  • 项目1Docker容器简介任务1.1 了解Docker历史1.1.1 什么是 DockerDocker 最初是dotCloud 公司创始人 Solomon Hykes在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于2013 年 ...
  • Docker、LXC、LXD、Multipass四项容器技术对比
  • 容器技术发展现状与展望

    千次阅读 2018-07-06 15:56:18
    一、容器技术发展现状容器技术主要可以分为容器运行技术和容器编排技术。其中:容器运行技术主要包括Docker和rkt等;容器编排技术主要包括Kubernetes、Meso...
  • 一、前言 说到容器,小编最先接触的容器还是tomcat这些... 这里小编就重点介绍一下容器技术的发展以及容器技术的黑马Docker。二、容器技术发展 小编觉得这张图非常棒,涵盖了容器技术的演变。 容器技术最早可以追溯

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 524,997
精华内容 209,998
关键字:

容器技术

友情链接: Document2.rar