写点什么

5 分钟让你理解 K8S 必备架构概念,以及网络模型(上)

用户头像
云流
关注
发布于: 2021 年 02 月 05 日

前言

很多小伙伴学习 K8S 的时候,会被 K8S 里面的概念搞乱了,望而生畏;而且很多文章里面介绍的时候讲的太专业了。今天来帮小伙伴们梳理一下,讲的不深入,目的是帮忙小伙伴更好的理解,各个概念的由来。

架构图



上图中,有两种 Node 节点,一个是 Master、一个是 Work。

从字面上来看 Work Node 就是用来工作的,也就是真正承担服务的机器节点。如服务 A 部署到 K8S 后,它的运行环境就在 WorkNode 节点。

那么 Master Node 是干嘛用的?小伙伴可以认为是用来分配服务到哪一台 work node 节点的;可以理解为大管家,它会知道现有 work node 的资源运行情况,决定服务安排到哪些 work nodes 上。

在 Work Node 节点上面有 2 个重要的组件,一个是 Pod、一个是 Container;

Pod 是 K8S 的最小单元,它里面可以有多个 Container。Container 就是服务/组件运行的环境。

一般情况下一个 Pod 只有一个业务服务 Container,而其他的 Container 是系统所需要的容器(其实就是一些进程组件,如网络组件、Volume 组件等)。所以一般可以理解为我们的服务就在 Pod 里面。

上面只是简单的介绍了 K8S 基本的架构,以及核心点。

小伙伴们基本使用,理解到这里也就可以了

当然需要深入了解具体 Master 和 Work 节点有哪些组件,以及组件之间的发布流程是什么?继续往下看哦。

Master Node 组件



上面中,用户一般采用 kubectl 命令,以及 dashboard 控制台去操作 k8s。所有的操作都是通过 API Server 组件,需要持久化的就存储到 etcd。Scheduler、Controller Manager 组件一直订阅 API Server 的变化。

整体流程

如用户需要创建服务 A 的 3 个 pod,那整体流程:

1)通过 Kubectl 提交一个创建 RC 的请求,该请求通过 API Server 被写入 etcd 中。

2)此时 Controller Manager 通过 API Server 的监听资源变化的接口监听到这个 RC 事件,分析之后,发现当前集群中还没有它所对应的 Pod 实例,于是根据 RC 里的 Pod 模板定义生成一个 Pod 对象,通过 API Server 写入 etcd。

3)接下来,此事件被 Scheduler 发现,它立即执行一个复杂的调度流程,为这个新 Pod 选定一个落户的 Work Node,然后通过 API Server 讲这一结果写入到 etcd 中。

4)随后,目标 Work Node 上运行的 Kubelet 进程通过 API Server 监测到这个“新生的”Pod,并按照它的定义,启动该 Pod。

5)用户的需求是 3 个 pod;那到底有没有启动了 3 个;是由 Controller Manager 监控管理的,它会保证资源达到用户的需求。

etcd

用于持久化存储集群中所有的资源对象,如 Node、Service、Pod、RC、Namespace 等;API Server 提供了操作 etcd 的封装接口 API,这些 API 基本上都是集群中资源对象的增删改查及监听资源变化的接口。

API Server

提供了资源对象的唯一操作入口,其他所有组件都必须通过它提供的 API 来操作资源数据,通过对相关的资源数据“全量查询”+“变化监听”,这些组件可以很“实时”地完成相关的业务功能。

Controller Manager

集群内部的管理控制中心,其主要目的是实现 Kubernetes 集群的故障检测和恢复的自动化工作,比如根据 RC 的定义完成 Pod 的复制或移除,以确保 Pod 实例数符合 RC 副本的定义;根据 Service 与 Pod 的管理关系,完成服务的 Endpoints 对象的创建和更新;其他诸如 Node 的发现、管理和状态监控、死亡容器所占磁盘空间及本地缓存的镜像文件的清理等工作也是由 Controller Manager 完成的。

Scheduler

集群中的调度器,负责 Pod 在集群节点中的调度分配。

Work Node 组件



上图右侧是 Work Node 的组件,整体流程

1)kubelet 监听到 Api Server 的变化后,如果有本 work node 节点需要创建 pod;则会通知 Container Runtime 组件

2)Container Runtime 是管理节点 Pod 组件,在启动 pod 时,如果本地没有镜像,则会从 docker hub 里面拉取镜像,启动容器 pod

3)kubelet 会把相关信息再传给 Api Server

Kubelet

负责本 Node 节点上的 Pod 的创建、修改、监控、删除等全生命周期管理,同时 Kubelet 定时“上报”本 Node 的状态信息到 API Server 里。本质 Pod 的管理是 Container Runtime 组件负责的

kube-proxy

实现了 Service 的代理与软件模式的负载均衡器,这个是因为 pod 的网络 ip 是经常变化的。这个网络知识,下一篇文章会介绍

Pod 发布

上面介绍了 K8S 整体架构流程,现在先从 pod 开始,一步步引出 K8S 的其他概念。

我们先编辑 yaml,定义一个 pod 对象

apiVersion: v1  #指定api版本,此值必须在kubectl apiversion中kind: Pod       #指定创建资源的角色/类型metadata:       #资源的元数据/属性    name: mc-user #资源的名字,在同一个namespace中必须唯一 spec:           #specification of the resource content 指定该资源的内容  containers:    #容器定义    - name: mc-user   #容器的名字        image: rainbow/mc-user:1.0.RELEASE    #容器镜像复制代码
复制代码

我们通过 kubectl 命令,来创建这个 pod

kubectl apply -f mc-user-pod.yaml复制代码
复制代码

我们 mc-user:1.0.RELEASE 的镜像就是一个 web 应用,8080 端口;但是我们发现 pod 启动后,我们无法通过 pod 的 ip 地址访问此 web 服务



那怎么才能访问 pod 呢?

反向代理

在要解决访问 pod 的问题前,我们先来看看我们之前是如何部署网站的?



外网访问我们内部的网站,一般我们会在中间部署一个 nginx,反向代理我们的 web 服务。根据这个思路,K8S 体系中也有反向代理这个概念

NodePort Service



K8S 中我们可以采用类型为 NodePort 的 Service 实现反向代理

K8S 的 Service 很多,其中 NodePort Service 是提供反向代理的实现

这样外网就可以访问内部的 pod 了。实现流程:

1)pod需要打上一个Label标签2)外部流量请求到NodePort Service,通过Selector 进行路由,3)NodePort Service根据Label标签进行路由转发到后端的Pod复制代码
复制代码

从上面的流程中,其实 Service 也起到了负载均衡的作用;后端 Pod 可以有多个,同时打上相同的 Label 标签,Service 会路由转发到其中一个 Pod。

Service Type 还可以为 LoadBalancer、ClusterIP LoadBalancer:这个是部署到云端(如阿里云)的时候需要用的,也是反向代理+负载均衡的作用,用作外部访问 K8S 内部。ClusterIP:这个 Service 是 K8S 集群内部做反向代理用的

Label 与 Selector



上图中有 2 个 pod 定义了 Label 为 app:nginx;1 个 pod 定义了 app:apache;

那么 Service 的 Selector 筛选 app:nginx,只会路由到 nginx 的 pod。

Service 发布

我们来编写一个 NodePort Service 发布文件

apiVersion: v1kind: Servicemetadata:   name: mc-userspec:   ports:    - name: http     #通讯协议      port: 8080     #这里的端口和clusterIP对应,即ip:8080,供内部访问。      targetPort: 8080   #端口一定要和container暴露出来的端口对应      nodePort: 31001  #节点都会开放此端口,此端口供外部调用  selector:    app: mc-user  #这里选择器一定要选择容器的标签  type: NodePort         #这里代表是NodePort类型的
复制代码
复制代码

nodePort 的端口范围:30000~32767

上面是 NodePort Service 的 yaml 文件,我们还要修改一个之前的 Pod 的 yaml 文件

apiVersion: v1  #指定api版本,此值必须在kubectl apiversion中kind: Pod       #指定创建资源的角色/类型metadata:       #资源的元数据/属性    name: mc-user #资源的名字,在同一个namespace中必须唯一   labels:       #标签定义    app: mc-user  #标签值spec:           #specification of the resource content 指定该资源的内容  containers:    #容器定义    - name: mc-user   #容器的名字        image: rainbow/mc-user:1.0.RELEASE    #容器镜像复制代码
复制代码

我们可以利用 kubectl 命令去分别执行 pod 和 service 的 yaml 文件;这样就可以通过外网直接访问了。http://localhost:31001 端口不要忘了是 nodePort 定义的端口哦。

总结

今天介绍了 K8S 的基本概念,以及架构流程;核心的是小伙伴们需要理解 Pod、Service、Labels、Selector 的这个组件为什么会产生?他们的解决了是什么问题?后续会继续介绍 K8S 其他的组件概念,希望能够帮助小伙伴们理解,减少 K8S 的学习难度;谢谢!!!

作者:码农清风

链接:https://juejin.cn/post/6925310467984343047


用户头像

云流

关注

还未添加个人签名 2020.09.02 加入

还未添加个人简介

评论

发布
暂无评论
5分钟让你理解K8S必备架构概念,以及网络模型(上)