k8s-Master&Node

前言

我们从前面可以知道容器可以简单地理解为 :
容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。
从这个结构中我们不难看出,一个正在运行的 Linux 容器,其实可以被“一分为二”地看待:

  • 容器镜像 (Container Image):容器的静态视图, 是一组联合挂载在 /var/lib/docker/aufs/mnt 上的 rootfs;
  • 容器运行时 (Container Runtime) : 一个由 Namespace+Cgroups 构成的隔离环境.

k8s 的全局架构

1297993-20210530124256594-1727848252.png

总的来说 , k8s架构中, 都由 MasterNode 两种节点组成,而这两种角色分别对应着控制节点计算节点
K8S

  • Master
    • Controller Manager : 控制器管理
    • API Server : API 服务
    • Scheduler : 调度相关
  • Node

然后我们再来仔细看一下 Pod 中的细节.

Kubelet --> Container Runtime

Kubelet 通过一个叫 CRI(Container Runtime Interface)的远程调用接口和容器进行交互 (比如 Docker) 进行交互

Kubelet --> Device Plugin

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

Kubelet --> Networking

Kubelet 通过CNI(Container Networking Interface)来控制网络连接

Kubelet --> Volume Plugin

Kubelet 通过 CSI(Container Storage Interface) 来控制存储相关的功能

Container Runtime --> OS

容器则是通过 OCI 同底层的操作系统进行交互,例如linux 操作系统, 即:是对 Linux 操作系统的调用(操作 Linux Namespace 和 Cgroups 等)。

我们编程的时候做上层设计一般都是做接口 , 而实现则是继承接口就可以了, 所以这个地方也可看出 k8s 的高度.

另外一张 K8s 简易架构图

img
(图片来自 : https://blog.csdn.net/fajing_feiyue/article/details/107732453)

可以看到 Master 管理着 Node , 而 Node 里面又有多个 Pod

Master 节点

Kubemetes 里的Master 指的是集群控制节点,每个Kubemetes 集群里需要有一个Master
节点来负责整个集群的管理和控制,基本上Kubemetes 所有的控制命令都是发给它,它来负责
具体的执行过程,我们后面所有执行的命令基本都是在Master 节点上运行的。Master 节点通常
会占据一个独立的X86 服务器(或者一个虚拟机),一个主要的原因是它太重要了,它是整个
集群的"首脑",如果它右机或者不可用,那么我们所有的控制命令部将失效。

Master 节点上运行着以下一组关键进程。

  • Kubemetes API Server (kube-apiserver) ,提供了HTTP Rest 接口的关键服务进程,是Kubemetes 里所有资源的增、删、改、查等操作的唯-入口,也是集群控制的入口进程。

  • Kubemetes Controller Manager ( kube-controller-manager ), Kubemetes 里所有资源对象的自动化控制中心,可以理解为资源对象的"大总管"。后面我们看到的哪些什么 RepeatSet 之类的对象

  • Kubemetes Scheduler Ckube-scheduler) ,负责资源调度CPod 调度)的进程,相当于公交公司的"调度室"。

其实Master 节点上往往还启动了→个etcd Server 进程,因为Kubemetes 里的所有资源对象
的数据全部是保存在etcd 中的。(试想一下假如没有持久化的工具, 那么只能放在内存中, 那么重启的时候就会都消失了, 所以)

Node 节点

除了Master , Kubemetes 集群中的其他机器被称为Node 节点,, Node 节点可以是一台物理主机,也可以是二台虚拟机。Node 节点才是Kubemetes 集群中的工作负载节点,每个Node 都会被Master 分配一些工作负载(工作负载指的是容器 ,例如 : docker ),当某个Node 岩机时,其上的工作负载会被Master 自动转移到其他节点上去。每个Node 节点上都运行着以下一组关键进程。

  • kubelet: 负责Pod 对应的容器的创建、启停等任务,同时与Master 节点密切协作,实现集群管理的基本功能。
  • kube-proxy: 实现Kubemetes Se凹lce 的通信与负载均衡机制的重要组件。
  • Docker Engine (docker ): Docker 引擎,负责本机的容器创建和管理工作。Node 节点可以在运行期间动态增加到Kubemetes 集群中,前提是这个节点上己经正确安装、配置和启动了上述关键进程,在默认情况下kubelet 会向Master 注册自己,这也是Kubemetes推荐的Node 管理方式。一旦Node 被纳入集群管理范围, kubelet 进程就会走时向Master 节点汇报自身的情报,例如操作系统、Docker 版本、机器的CPU 和内存情况,以及之前有哪些Pod在运行等,这样Master 可以获知每个Node 的资源使用情况,并实现高效均衡的资源调度策略。而某个Node 超过指定时间不上报信息时,会被Master 判定为"失联", Node 的状态被标记为不可用CNot Ready) ,随后Master 会触发"工作负载大转移"的自动流程。

Pod

开始觉得Pod 对应着一台虚拟机 ,但是,过段时间,你会发现 Pod 中的每个容器都有一个隔离的文件系统,并且从一个容器内部,你看不到在同一 Pod 的其他容器中运行的进程。好吧!也许 Pod 不是一个微型的服务器,而只是一组具有共享网络堆栈的容器。

这东西最搞笑 , Node 我是改变不了的, 要不就是一台物理机 ,要不就是一台虚拟机 ,都可认为是 Node , 而 Pod 作为基本单位, 是可以调度的. 比如某个 Pod 被调度到 NodeA 部署,但是部署失败了, 那么就有可能被调度到 NodeB 中去部署, 这也是为啥 Pod 是 k8s 中的最基本的调度单位 .

k8s 是如何编排的

1297993-20210530121817342-1507555731.png

下面这一段来自课程

按照这幅图的线索,我们从容器这个最基础的概念出发,首先遇到了容器间“紧密协作”关系的难题,于是就扩展到了 Pod;有了 Pod 之后,我们希望能一次启动多个应用的实例,这样就需要 Deployment 这个 Pod 的多实例管理器;而有了这样一组相同的 Pod 后,我们又需要通过一个固定的 IP 地址和端口以负载均衡的方式访问它,于是就有了 Service。

可是,如果现在两个不同 Pod 之间不仅有“访问关系”,还要求在发起时加上授权信息。最典型的例子就是 Web 应用对数据库访问时需要 Credential(数据库的用户名和密码)信息。那么,在 Kubernetes 中这样的关系又如何处理呢?

Kubernetes 项目提供了一种叫作 Secret 的对象,它其实是一个保存在 Etcd 里的键值对数据。这样,你把 Credential 信息以 Secret 的方式存在 Etcd 里,Kubernetes 就会在你指定的 Pod(比如,Web 应用的 Pod)启动时,自动把 Secret 里的数据以 Volume 的方式挂载到容器里。这样,这个 Web 应用就可以访问数据库了。

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

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

如此种种,正是 Kubernetes 项目定义容器间关系和形态的主要方法。

可以看到,Kubernetes 项目并没有像其他项目那样,为每一个管理功能创建一个指令,然后在项目中实现其中的逻辑。这种做法,的确可以解决当前的问题,但是在更多的问题来临之后,往往会力不从心。

相比之下,在 Kubernetes 项目中,我们所推崇的使用方法是:

  • 首先,通过一个“编排对象”,比如 Pod、Job、CronJob 等,来描述你试图管理的应用;
  • 然后,再为它定义一些“服务对象”,比如 Service、Secret、Horizontal Pod Autoscaler(自动水平扩展器)等。这些对象,会负责具体的平台级功能。

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

可以看到 servicedeployment实际上是一个逻辑概念 , 这里可以这么理解, 例如我们应用中有个推送模块--push 模块, 为了防单点故障,所以该模块部署有三份,,模块对外提供推送服务(service) , 那么 "推送服务"就可以作为一个 service ,而前面讲到的三份部署可以抽象成一个 deployment .

问题

Pod service Job 是个逻辑概念吗? Pod 里的容器是不是只能在同一台机器上(同一个集群节点上)

除了容器 , 其他都是逻辑概念 ,也就是不存在实物的 ,而镜像是真实存在 .
同一个Pod 中的容器需要共享同一组网络等其他NameSpec , 所以需要在同一个节点上 .

总结

k8s 的更像是一个集大成的工具 ,而 docker 则是容器的代表 ,从另外一个方面来说 k8s 中的工作负载不仅可以是 docker ,还可以是其他容器 .在我看来 K8S 主要编排的两个重要作用是 :

  • 处理好应用间的关系
  • 它对一些常用的共有应用变成了它的"API 对象" , 这大大地使得应用从基础框架解决出来 ,只专心负责业务就够了.

参考资料 :

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章