k8s组件结构、创建流程和Service服务

K8S是管理业务程序的,所以可推出K8S自身肯定有管理端。相应的,K8S负责管理的节点可以叫做Master节点,K8S中负责业务程序的节点,可以叫做Worker节点。

Worker组件结构

基本物理结构如下:

其中,Node就对应于一台实际的服务器,也叫做节点。一个Node上可以有多个Pod,Pod就是K8S调度的最小单位。每个Pod中又可以有多个容器,这里的容器就是Docker或者其他容器实现。

如果将容器看做是一般意义上的进程,那么每个Pod又可以看做是一个进程组。

这样,整个K8S内部结构可以看成:

由于Pod是最小的调度单位,当一个Pod异常时,K8S会重新拉起Pod,此时新的Pod有可能部署到其他Node上。对于外部应用来说,不可能直接去寻址Pod,所以要引入一个中间抽象层,这个抽象层就是Service。

所以加入Service后,就可以表现为:注意,其中的Service是抽象层,就是对Pod的或者Service的进一步封装。

一个服务器对应一个Node,每个Node又包含几个关键组件,Node内部整体结构如下:

  1. kubelet:就是管理这个Node,负责Pod的管理并和Master通信

  2. kube-proxy:类似反向代理,将外部流量代理到Pod中。也是实现Service抽象机制的关键

  3. Container Runtime:就是容器运行时,如果是Docker容器,那么就是Docker Engine。

Master组件结构

  1. 客户端:指的是比如我们通过命令行控制K8S的行为,命令行工具为 kubectl,那么它就是客户端。

  2. kube-apiserver:因为Master节点提供了一些可以控制K8S行为的API接口,如果要调用这些接口,就需要通过 kube-apiserver来执行。

  3. kube-controller-manager:维持K8S各资源处于正常状态

  4. kube-scheduler:调度Pod到最合适的Node上

  5. Etcd:持久化存储,用来存储K8S集群内部正常运转需要的数据信息

根据声明式API启动创建pod流程

理清流程的目的,是对网络流量走向做到心中有数。

首先,什么是声明式API,见下图:

也是就是一个yaml文件,里面的字段就是K8S规定的描述字段。然后只需要通过客户端kubectl 来执行这个yaml即可,等执行完成后,我们需要的Pod或者service就已经启动好了。这一切都是自动实现的,所以这就是声明式API。

整理流程如下:

经过流程图我们就可以看出来,图中没有体现 Service和kube-proxy这两个关键概念。所以接下来我们要看下K8S网络,否则无法真正在线上进行部署。

K8S网络和Service

K8S网络

实际生产中,一个完整的流程为:外部流量导入K8S集群,集群内流量导入对应的Service。因为Service是抽象概念,所以是流量导入到Node,最后导入到具体的Pod中。

上述过程就体现了四种网络层次,分别是:

  1. 物理层的Node网络:就是服务器之间的实际ping通的网络

  2. 构建在Node之上的Pod网络:也就是pod之间通信的网络。因为pod才是真正的实体

  3. 实现抽象Service功能的网络:因为有Serviec抽象层,所以Service肯定通过某种机制对流量做了转发控制,才能够实现代理的功能。

  4. 沟通K8S集群和外部环境的网络

对于K8S网络的流量路由,目前还不是重点。需要单独来看。现在只要清楚实际生产中,需要导入外部流量,而且我们直接关注是Service。所以只要理清Service如何处理外部流量和内部流量。

K8S的Service

K8S提供了多种Service,如下:

  • NodePort:顾名思义,就是在Node节点上,开了一个port。所以NodePort是节点之间,或者说是节点外部流量的关键入口。也就是NodePort Service是最基础的Service,所以上文才提到了Service嵌套。

  • ClusterIp:就是集群内部的反向代理。用于集群的Pod之间通信

  • LoadBalancer:就是接入外部流量

前文提到,Service具有负载均衡的功能。所以Service有一种标签label机制,就和域名一样,根据label来寻址,所以又会配合kube-dns实现DNS的效果。

这样,Service就可以实现服务发现并转发流量。转发流量就是通过 kube-proxy执行的,但是和一般的反向代理不一样,流量并不会经过kube-proxy内部。因为kube-proxy是直接修改Node的iptables转发规则,所以没有性能损耗。

K8S接入外部网络的实现

  • 通过NodePort对外映射端口

  • 通过LoadBalancer对接外部流量

  • 通过Ingress实现

NodePort通过kube-proxy可以对外提供流量入口。每个Node都可以像这样对外提供入口,所以如何进行负载均衡呢?这就是 LoadBalancer需要解决的问题。虽然LoadBalancer可以解决,但是一个LoadBalancer只能代理一种我们的服务,因为他只是转发全部的流量到对应的kube-proxy。

所以,Ingress就是解决这个问题的方案。Ingress一侧对接负载均衡,接入外部流量。一侧对接内部的Service,根据请求域名等实现流量转发。

所以,真正生产环境可用,ingress或者说类似ingress的实现必不可少。

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