了解Kubernetes

了解Linux中的六种namespace

linux实现了mount、UTS、IPC、network、pid、user这六种namespace。

一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境

从这个结构中不难看出,一个正在运行的 Linux 容器,其实可以被“一分为二”地看待:
1
一组联合挂载在 /var/lib/docker/aufs/mnt 上的 rootfs,这一部分称为“容器镜像”(Container Image),是容器的静态视图;
2
一个由 Namespace+Cgroups 构成的隔离环境,这一部分称为“容器运行时”(Container Runtime),是容器的动态视图。

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

这个重要假设,正是容器技术圈在 Docker 项目成功后不久,就迅速走向了“容器编排”这个“上层建筑”的主要原因:作为一家云服务商或者基础设施提供商,我只要能够将用户提交的 Docker 镜像以容器的方式运行起来,就能成为这个非常热闹的容器生态图上的一个承载点,从而将整个容器技术栈上的价值,沉淀在我的这个节点上。

更重要的是,只要从我这个承载点向 Docker 镜像制作者和使用者方向回溯,整条路径上的各个服务节点,比如 CI/CD、监控、安全、网络、存储等等,都有我可以发挥和盈利的余地。这个逻辑,正是所有云计算提供商如此热衷于容器技术的重要原因:通过容器镜像,它们可以和潜在用户(即,开发者)直接关联起来。

从一个开发者和单一的容器镜像,到无数开发者和庞大的容器集群,容器技术实现了从“容器”到“容器云”的飞跃,标志着它真正得到了市场和生态的认可。

这样,容器就从一个开发者手里的小工具,一跃成为了云计算领域的绝对主角;而能够定义容器组织和管理规范的“容器编排”技术,则当仁不让地坐上了容器技术领域的“头把交椅”。

这其中,最具代表性的容器编排工具,当属 Docker 公司的 Compose+Swarm 组合,以及 Google 与 RedHat 公司共同主导的 Kubernetes 项目

首先,Kubernetes 项目要解决的问题是什么?

编排?调度?容器云?还是集群管理?
实际上,这个问题到目前为止都没有固定的答案。因为在不同的发展阶段,Kubernetes 需要着重解决的问题是不同的。

但是,对于大多数用户来说,他们希望 Kubernetes 项目带来的体验是确定的:现在我有了应用的容器镜像,请帮我在一个给定的集群上把这个应用运行起来。
更进一步地说,我还希望 Kubernetes 能给我提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。等一下,这些功能听起来好像有些耳熟?这不就是经典 PaaS(比如,Cloud Foundry)项目的能力吗?

而且,有了 Docker 之后,我根本不需要什么 Kubernetes、PaaS,只要使用 Docker 公司的 Compose+Swarm 项目,就完全可以很方便地 DIY 出这些功能了!
所以说,如果 Kubernetes 项目只是停留在拉取用户镜像、运行容器,以及提供常见的运维功能的话,那么别说跟“原生”的 Docker Swarm 项目竞争了,哪怕跟经典的 PaaS 项目相比也难有什么优势可言。

而实际上,在定义核心功能的过程中,Kubernetes 项目正是依托着 Borg 项目的理论优势,才在短短几个月内迅速站稳了脚跟,进而确定了一个如下图所示的全局架构:

image

apiserver :各个组件的沟通
调度器 : 用于选择node
控制器: 用于编排pods

node包含

  • pod
  • kubelet
  • kube-proxy
    Server
    固定IP

我们可以看到,Kubernetes 项目的架构,跟它的原型项目 Borg 非常类似,都由 Master 和 Node 两种节点组成,而这两种角色分别对应着控制节点和计算节点。
其中,控制节点,即 Master 节点,由三个紧密协作的独立组件组合而成,它们分别是负责 API 服务的 kube-apiserver、负责调度的 kube-scheduler,以及负责容器编排的 kube-controller-manager。整个集群的持久化数据,则由 kube-apiserver 处理后保存在 Etcd 中。

而计算节点上最核心的部分,则是一个叫作 kubelet 的组件。

在 Kubernetes 项目中,kubelet 主要负责同容器运行时(比如 Docker 项目)打交道。而这个交互所依赖的,是一个称作 CRI(Container Runtime Interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作,比如:启动一个容器需要的所有参数。

这也是为何,Kubernetes 项目并不关心你部署的是什么容器运行时、使用的什么技术实现,只要你的这个容器运行时能够运行标准的容器镜像,它就可以通过实现 CRI 接入到 Kubernetes 项目当中。

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

此外,kubelet 还通过 gRPC 协议同一个叫作 Device Plugin 的插件进行交互。这个插件,是 Kubernetes 项目用来管理 GPU 等宿主机物理设备的主要组件,也是基于 Kubernetes 项目进行机器学习训练、高性能作业支持等工作必须关注的功能。
而 kubelet 的另一个重要功能,则是调用网络插件和存储插件为容器配置网络和持久化存储。这两个插件与 kubelet 进行交互的接口,分别是 CNI(Container Networking Interface)和 CSI(Container Storage Interface)。

实际上,kubelet 这个奇怪的名字,来自于 Borg 项目里的同源组件 Borglet。不过,如果你浏览过 Borg 论文的话,就会发现,这个命名方式可能是 kubelet 组件与 Borglet 组件的唯一相似之处。因为 Borg 项目,并不支持我们这里所讲的容器技术,而只是简单地使用了 Linux Cgroups 对进程进行限制。

这就意味着,像 Docker 这样的“容器镜像”在 Borg 中是不存在的,Borglet 组件也自然不需要像 kubelet 这样考虑如何同 Docker 进行交互、如何对容器镜像进行管理的问题,也不需要支持 CRI、CNI、CSI 等诸多容器技术接口。

可以说,kubelet 完全就是为了实现 Kubernetes 项目对容器的管理能力而重新实现的一个组件,与 Borg 之间并没有直接的传承关系。

Kubernetes 项目核心功能的“全景图”

image.png

总结

首先,我和你一起回顾了容器的核心知识,说明了容器其实可以分为两个部分:容器运行时和容器镜像。

然后,我重点介绍了 Kubernetes 项目的架构,详细讲解了它如何使用“声明式 API”来描述容器化业务和容器间关系的设计思想。

实际上,过去很多的集群管理项目(比如 Yarn、Mesos,以及 Swarm)所擅长的,都是把一个容器,按照某种规则,放置在某个最佳节点上运行起来。这种功能,我们称为“调度”。

而 Kubernetes 项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。这种功能,就是我们经常听到的一个概念:编排。
所以说,Kubernetes 项目的本质,是为用户提供一个具有普遍意义的容器编排工具。

不过,更重要的是,Kubernetes 项目为用户提供的不仅限于一个工具。它真正的价值,乃在于提供了一套基于容器构建分布式系统的基础依赖。关于这一点,相信你会在今后的学习中,体会的越来越深。

Master组件


Master 组件对集群进行全局决策(例如,调度),并检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

1、kube-apiserver

master节点上提供k8sapi服务的组件,

2、etcd

保存了k8s集群的一些数据,比如pod的副本数,pod的期望状态与现在的状态

3、scheduler

master节点上的调度器,负责选择节点让pod在节点上运行

kube-scheduler 给一个 pod 做调度选择包含两个步骤:
1、过滤
2、打分

过滤阶段会将所有满足 Pod 调度需求的 Node 选出来。例如,PodFitsResources 过滤函数会检查候选 Node 的可用资源能否满足 Pod 的资源请求。在过滤之后,得出一个 Node 列表,里面包含了所有可调度节点;通常情况下,这个 Node 列表包含不止一个 Node。如果这个列表是空的,代表这个 Pod 不可调度。

在打分阶段,调度器会为 Pod 从所有可调度节点中选取一个最合适的 Node。根据当前启用的打分规则,调度器会给每一个可调度节点进行打分。

最后,kube-scheduler 会将 Pod 调度到得分最高的 Node 上。如果存在多个得分最高的 Node,kube-scheduler 会从中随机选取一个。

4、controller

master节点的控制器,负责在节点出现故障时进行通知和响应,负责对节点的pod状态进行监控

Node组件

1、kubelet

一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
他负责管理在该节点上的属于k8s集群的容器

2、kube-proxy

一个代理,可以通过代理创建一个虚拟ip,通过这个ip来与pod进行交流

3、Container Runtime

容器运行环境是负责在节点上运行容器的软件

附加组件

1、DNS

负责对k8s集群进行域名解析

2、Dashboard

Dashboard是k8s集群的一个web界面,

3、集群层面日志

集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。

4、容器资源监控

容器资源监控将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。

k8s流程

以下是我自己对k8s工作流程的理解,只供参考

1、准备好对应的yanl文件,通过kubectl发送到Api Server中
2、Api Server接收到客户端的请求将请求内容保存到etcd中
3、Scheduler会监测etcd,发现没有分配节点的pod对象通过过滤和打分筛选出最适合的节点运行pod
4、节点会通过conteiner runntime 运行对应pod的容器以及创建对应的副本数
5、节点上的kubelet会对自己节点上的容器进行管理
6、controler会监测集群中的每个节点,发现期望状态和实际状态不符合的话,就会通知对应的节点
7、节点收到通知,会通过container runtime来对pod内的容器进行收缩或者扩张

对于容器来说,管理的单位是容器
对于k8s来说,管理的是一个pod应用
一个pod上可以运行多个容器,可以将pod理解为一个虚拟机,一个虚拟机上运行了多个容器

你可能感兴趣的:(了解Kubernetes)