4.0.1 从容器到容器云

一个正在运行的Linux容器,可以被一分为二地看待:

1.一组联合挂载在/var/lib/docker/aufs/mnt上的rootfs,这一部分我们称为容器镜像(Container Image)是容器的静态视图。

2.一个由Namespace+Cgroups构成的隔离环境,这一部分我们称为“容器运行时”(Container Runtime)是容器的动态视图

作为开发者,我们并不关心容器运行时的差异,因为,在整个"开发-测试-发布"的流程中,真正承载着容器信息进行传递的,是容器镜像,而不是容器运行时。

作为一个云服务商或者基础设施提供商,我只要能够将用户提交的Docker镜像以容器的方式运行起来,便可以将整个容器技术栈上的价值,汇聚在自己的节点上。

另外,从这个节点向Docker镜像制作者和使用者方向回溯,整个路径上的各个服务节点: 如CI/CD, 监控,安全,网络,存储,都可以有服务商发挥和盈利的地方。(通过容器镜像,和潜在用户,直接关联)

而容器编排技术,就是当前容器领域最核心的部分。当今的主流就是Google和Redhat公司所主导的Kubernetes项目。

Kubernetes项目的理论基础来自于Google的Borg系统。
Kubernete项目2014年立项,2015年Borg才对外公开发表

相比于Spanner,BigTable等相对上层的项目,Borg要承担的责任,是居于整个基础设施技术栈的最底层

c7ed0043465bccff2efc1a1257e970bd.png

图片来源http://malteschwarzkopf.de/research/assets/google-stack.pdf
这个图来自于Google Omega论文作者的博士论文,描绘了当时Google已经公开发表的整个基础设施栈,

8ee9f2fa987eccb490cfaa91c6484f67.png

Kubernetes项目的架构,跟它的原型项目Borg非常类似,都由Master和Node两种节点组成,而且这两种角色分别对应着控制节点和计算节点。

控制节点,(Master节点) 有三个紧密协作的独立组件组合而成,分别是负责API服务的kube-apiserver,负责调度的kube-scheduler, 负责容器编排的kube-controller-manager。整个集群的持久化数据,则有kube-apiserver处理后保存在Etcd中。

计算节点(Node节点),最核心的部分是一个叫做kubelet的组件。

在Kubernetes项目中,kubelet主要负责同容器运行时,(比如Docker项目)打交道,
这个交互所依赖的是一个称作CRI的远程调用接口(Container Runtime Interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作。
这也是Kubernetes并不关心你部署的是什么容器运行时,使用的什么技术实现,只要你的这个容器运行时能够运行标准的容器镜像,它就可以通过实现CRI接入到Kubernetes项目当中。

具体的容器运行时,一般通过OCI这个容器运行时规范同底层的Linux操作系统进行交互,即把CRI请求翻译成对Linux操作系统的调用(操作Linux Namespace和Cgroups等 )

此外Kubernetes还通过gRPC协议同一个协议叫做Device Plugin的插件进行交互。这个插件,是Kubernetes项目用来管理GPU等宿主机物理设备的主要组件,也是基于Kubernetes项目进行机器学习训练,高性能作业支持等工作必须关注的功能。

而kubelet的另一个重要功能,则是调用网路插件和存储插件为容器配置网络和持久化存储。这两个插件,分别是CNI(Container Networking Interface)和CSI(Container Storage Interface)

尽管像Docker这样的容器镜像在Borg中是不存在的,自然Borg也不需要考虑同Docker交互,容器镜像进行管理,也不需要支持CRI,CNI,CSI等多容器技术。

但对于Kubernetes项目来说,Borg的指导意义在于master节点 : 即如何编排,管理,调度用户提交的作业。

Borg项目完全可以把Docker镜像看做是一种新的应用打包方式。这样,Borg团队过去在大规模作业管理与编排的经验就可以直接套用了。

在Borg项目中,运行在大规模集群中的各种任务之间,实际上存在着各种各样的关系。这些关系的处理,才是作业编排和管理最困难的地方。

举例来说,一个Web应用和数据库之间的访问关系,一个负载均衡器和它的后端服务之间的代理关系,一个门户应用与授权组件之间的调用关系。

在Compose项目中,可以为两个容器定义一个link,而Docker项目会负责维护这个link关系。具体做法是Docker会在Web容器中,将DB容器的IP地址,端口等信息以环境变量的方式注入进去,供应用进程使用。

    DB_NAME=/web/db
    DB_PORT=tcp://172.17.0.5:5432
    DB_PORT_5432_TCP=tcp://172.17.0.5:5432
    DB_PORT_5432_TCP_PROTO=tcp
    DB_PORT_5432_TCP_PORT=5432
    DB_PORT_5432_TCP_ADDR=172.17.0.5

Kubernetes项目最主要的设计思想是,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持各种种类的关系留有余地。

Kubernetes对容器间的访问进行了分类:

第一种是 紧密交互关系:应用之间需要非常频繁的交互和访问,或者双方需要通过本地文件进行信息交互。

常规情况下,这些应用会直接部署在同一台机器上,通过localhost通信,通过本地磁盘交换文件。而在Kubernetes项目中,这些容器会被划分到一个Pod,Pod里的容器共享一个Network Namespace,同一个数据卷,从而达到高效率交换信息的目的。

Pod是Kubernetes项目中最基础的一个对象,源自于Google Borg论文中一个名叫ALLOC的设计

另一种需求,如Web应用与数据库之间的访问关系,Kubernetes项目则提供一种叫做“Service”的服务.

一般像这样两个应用,往往不部署在同一台机器上,这样即使Web应用宕机,数据库也完全不受影响。

Kubernetes的做法就是给Pod绑定一个Service服务,而service服务声明的IP地址信息是不变的。这个service服务的主要作用,就是作为Pod的代理入口(Portal),从而代替Pod对外暴露一个固定的网络地址。

如果两个不同pod之间不仅有访问关系,还要求在发起时加上授权信息。最典型的例子就是Web应用对数据库访问时需要Credential(用户名和密码)信息。Kubernetes项目提供一种叫做Secret的对象,以键值对的形式保存在Etcd里

除了应用与应用之间的关系外,应用运行的形态也是影响“如何容器化这个应用”的重要因素。

为此,Kubernetes定义了新的,基于Pod改进后的对象。比如job,用来描述一次性运行的Pod(比如,大数据任务);再比如DaemonSet,用来描述每个宿主机上必须只能运行一个副本的守护进程服务,有比如CronJob,用于描述定时任务等等。

Kubernetes并没有像其他项目那样,为每一个管理功能创建一个指令,然后在项目中实现其中的逻辑。
而是:

  1. 首先,通过编排对象,比如Pod, Job, CronJob等, 来描述你试图管理的应用;
  2. 然后,在为它定义一些服务对象,比如Service,Secret,Horizontal Pod AutoScaler(自动水平扩展器)等。来负责具体的平台级业务

这种使用方法,就是所谓的“声明式API”。这种API对于的编排对象和服务对象,都是Kubernetes项目中的API对象(API Object)。

例如声明两台Nginx服务器,编写如下代码在YAML文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

在上面的YAML文件中,我们定义了一个Deployment对象,主体是(spec.template包含内容)是一个使用Nginx镜像的Pod,而这个Pod的副本数是2.

然后执行

kubectl create -f nginx-deployment.yaml

这样两个完全相同的Nginx容器就被启动了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 一、Kubernetes整体架构 Kubernetes属于主从分布式架构,主要由Master Node和Worke...
    粥一样温柔阅读 1,379评论 0 1
  • 不要太相信普通人的建议 建议通常是无效的 如果有效,他就不会是普通人 向有结果的人学习 因为结果不会说谎
    眉目流转做扇窗阅读 182评论 0 0
  • 01 17岁的时候,看过一些青春小说,那时候觉得如果有一个自己很喜欢的人,特别酷。 18岁的时候,开始面对高考的压...
    迟一木阅读 443评论 4 4
  • 誓言空空,摘下业果 寻一片自在 离去 一边说教一边卸下包裹 婆娑的树影 无实有名 造一只木筏吧 渡过虚无 夜掩映 ...
    林木人阅读 291评论 1 1
  • 安排云媚,安排霞媚,安排云绻霞光醉,安排星月,映祥瑞。 秋至叶碎,秋至雨碎,秋至眉叶闪晶泪,秋至眷恋,容憔悴。
    文采乐阅读 1,037评论 13 19