云原生系列二【Kubernetes】Kubernetes是如何运行的?

一、概述

随着系统可部署组件的数量增长,把它们都管理起来会变得越来越困难。需要一个更好的方式来部署和管理这些组件, 并支持基础设施的全球性伸缩,谷歌可能是第一个意识到这一点的公司。谷歌等全球少数几个公司运行着成千上万的服务器,而且在如此海量规模下,不得不处理部署管理的问题。这推动着他们找出解决方案使成千上万组件的管理变得有效且成本低廉。

初衷

  • 这些年来,谷歌开发出了一个叫Borg的内部系统(后来还有一个新 系统叫Omega),应用开发者和系统管理员管理那些数以千计的应用程序和服务都受益于它的帮助。除了简化开发和管理,它也帮助他们获得了更高的基础设施利用率,在你的组织如此庞大时,这很重要。当你运行成千上万台机器时,哪怕一丁点的利用率提升也意味着节约了数百万美元,所以,开发这个系统的动机是显而易见的
    在保守Borg和Omega秘密数十年之后,2014年,谷歌开放了Kubernetes,一个基于Borg、Omega及其他谷歌内部系统实践的开源系统。
  • Kubernetes是一个软件系统,它允许你在其上很容易地部署和管理容器化的应用。它依赖于Linux容器的特性来运行异构应用,而无须知道这些应用的内部详情,也不需要手动将这些应用部署到每台机器。因为这些应用运行在容器里,它们不会影响运行在同一台服务器上的其他应用,当你是为完全不同的组织机构运行应用时,这就很关键了。这对于云供应商来说是至关重要的,因为它们在追求高硬件可用率的同时也必须保障所承载应用的完全隔离。Kubernetes使你在数以千计的电脑节点上运行软件时就像所有这些节点是单个大节点一样。它将底层基础设施抽象,这样做同时简化了应用的开发、部署,以及对开发和运维团队的管理
    通过Kubernetes部署应用程序时,你的集群包含多少节点都是一样的。集群规模不会造成什么差异性,额外的集群节点只是代表一些额外的可用来部署应用的资源

Kubernetes的核心功能:

下图展示了一幅最简单的Kubernetes系统图。整个系统由一个主节点和若干个工作节点组成。开发者把一个应用列表提交到主节点, Kubernetes会将它们部署到集群的工作节点。组件被部署在哪个节点对 于开发者和系统管理员来说都不用关心
开发者能指定一些应用必须一起运行,Kubernetes将会在一个工作节点上部署它们。其他的将被分散部署到集群中,但是不管部署在哪 儿,它们都能以相同的方式互相通信。
在这里插入图片描述

  • 帮助开发者聚焦核心应用功能:Kubernetes可以被当作集群的一个操作系统来看待。它降低了开发者不得不在他们的应用里实现一些和基础设施相关服务的心智负担。他们现在依赖于Kubernetes来提供这些服务,包括服务发现、扩容、负载均衡、自恢复,甚至领导者的选举。应用程序开发者因此能集中精力实现应用本身的功能而不用浪费时间思索怎样集成应用与基础设施。​​​​​
    -帮助运维团队获取更高的资源利用率:Kubernetes将你的容器化应用运行在集群的某个地方,并提供信息给应用组件来发现彼此并保证它们的运行。因为你的应用程序不关心它 运行在哪个节点上,Kubernetes能在任何时间迁移应用并通过混合和匹 配应用来获得比手动调度高很多的资源利用率

二、核心组件

在硬件级别,一个Kubernetes集群由很多节点Node组成,Node是Kubernetes中的工作机器,可以是实体机可以是虚拟机,这些节点被分成以下两种类型:
1、主节点(master Node),它承载着Kubernetes控制和管理整个集群系统的控制面板;

  • etcd 保存了整个集群的状态,是一个分布式的,一致的 key-value 存储,主要用途是共享配置和服务发现,保存集群状态数据,比如 Pod、Service 等对象信息;
  • apiserver 是集群的统一入口,各组件协调者,以 HTTP Rest 提供接口服务,所有对象资源的增、删、改、查和监听操作都交给 apiserver 处理后再提交给 Etcd 存储;
  • controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等,是 K8S 里所有资源对象的自动化控制中心,处理集群中常规后台任务,一个资源对应一个控制器,而 controller-manager 就是负责管理这些控制器的;
  • scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上,根据调度算法为新创建的 Pod 选择一个 Node 节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上;

2、工作节点(worker Node),它们运行用户实际部署的应用;

除了 Master,K8S 集群中的其它机器被称为 Node 节点,Node 节点是 K8S 集群中的工作负载节点,每个 Node 都会被 Master 分配一些工作负载,当某个 Node 宕机时,其上的工作负载会被 Master 自动转移到其它节点上去。

  • kubelet 负责与api server通信,并维护容器的生命周期,负责 Pod 对应的容器的创建、启停等任务,实现集群管理的基本功能,同时也负责 Volume(CVI)和网络(CNI)的管理。类似Master大王派我来巡山
  • Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
  • kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡,在 Node 节点上实现 Pod 网络代理,实现 Kubernetes Service 的通信,维护网络规则和四层负载均衡工作。
  • docker engine:Docker 引擎,负责本机的容器创建和管理工作。Node 节点可以在运行期间动态增加到 K8S 集群中,前提是这个节点上已经正确安装、配置和启动了上述关键组件。在默认情况下 kubelet 会向 Master 注册自己,一旦 Node 被纳入集群管理范围,kubelet 就会定时向 Master 节点汇报自身的情况,例如操作系统、Docker 版本、机器的 CPU 和内存情况,以及之前有哪些 Pod 在运行等,这样 Master 可以获知每个 Node 的资源使用情况,并实现高效均衡的资源调度策略。而某个 Node 超过指定时间不上报信息时,会被 Master 判定为“失联”,Node 的状态被标记为不可用(Not Ready),随后 Master 会触发“工作负载大转移”的自动流程。

在这里插入图片描述
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/956be9f538da423a8a52be255b575c1c.png
在这里插入图片描述

Kubernetes基本概念

Container Runtime

Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容器可以很方便的在任何地方运行。
由于容器体积小且启动快,因此可以在每个容器镜像中打包一个应用程序。这种一对一的应用镜像关系拥有很多好处。使用容器,不需要与外部的基础架构环境绑定, 因为每一个应用程序都不需要外部依赖,更不需要与外部的基础架构环境依赖。完美解决了从开发到生产环境的一致性问题。容器同样比虚拟机更加透明,这有助于监测和管理。尤其是容器进程的生命周期由基础设施管理,而不是被进程管理器隐藏在容器内部。最后,每个应用程序用容器封装,管理容器部署就等同于管理应用程序部署。
Kubernetes 支持多个容器运行环境:Docker、containerd、cri-o、rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口) 的软件

Pod

Kubernetes 使用 Pod 来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。

  • Pod 是一组紧密关联的容器集合,它们共享 IPC 和 Network namespace,是 Kubernetes 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
  • 在创建新部署时,Kubernetes会建立一个Pod来寄存你的应用实例,Pod是一个抽象的概念,但是每个pod在k8s网络内有属于它自己的ip,这个ip是由k8s创建的网络统一分配的。Pod是Kuberlnetes平台中的原子单位。在部署创建时,部署并不直接创建容器,而是创建包含了容器的Pod。Pod被分配绑定在指定的Node上,除非被停止或者删除它会一直在该Node上工作。万一出现Node宕机的情况,集群中另外一个可用的Node会马上启动运行一个完全一样的Pod。其生命周期是短暂的(服务器重启后,就找不到了)
  • 每个 Pod 都由一个特殊的根容器 Pause 容器,以及一个或多个紧密相关的用户业务容器组成。Pause 容器作为 Pod 的根容器,以它的状态代表整个容器组的状态。K8S 为每个 Pod 都分配了唯一的 IP 地址,称之为 Pod IP。Pod 里的多个业务容器共享 Pause 容器的IP,共享 Pause 容器挂载的 Volume。 在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中,同一个Pod里的容器之间仅需通过localhost就能互相通信
    请添加图片描述

Label

标签,附加到某个资源上,用于关联对象、查询和筛选。一个 Label 是一个 key=value 的键值对,key 与 value 由用户自己指定。Label 可以附加到各种资源上,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源上。

我们可以通过给指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等工作。

K8S 通过 Label Selector(标签选择器)来查询和筛选拥有某些 Label 的资源对象。Label Selector 有基于等式( name=label1 )和基于集合( name in (label1, label2) )的两种方式。

ReplicaSet(RC)

ReplicaSet 用来确保预期的 Pod 副本数量,如果有过多的 Pod 副本在运行,系统就会停掉一些 Pod,否则系统就会再自动创建一些 Pod。

我们很少单独使用 ReplicaSet,它主要被 Deployment 这个更高层的资源对象使用,从而形成一整套 Pod 创建、删除、更新的编排机制。

Deployment

Deployment通常用来部署无状态应用,如Web服务, 该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。在内部使用ReplicaSet来实现Pod副本的创建。Deployment确保指定数量的Pod“副本”在运行,并且支持回滚和滚动升级。创建Deployment时,需要指定 Pod模板和Label标签。

Horizontal Pod Autoscaler(HPA)

HPA 为 Pod 横向自动扩容,也是 K8S 的一种资源对象。HPA 通过追踪分析 RC 的所有目标 Pod 的负载变化情况,来确定是否需要针对性调整目标 Pod 的副本数量。

Service

Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。
Service 定义了一个服务的访问入口,通过 Label Selector 与 Pod 副本集群之间“无缝对接”,定义了一组 Pod 的访问策略,防止 Pod 失联。
创建 Service 时,K8S会自动为它分配一个全局唯一的虚拟 IP 地址,即 Cluster IP。服务发现就是通过 Service 的 Name 和 Service 的 ClusterIP 地址做一个 DNS 域名映射来解决的。
Service能够提供负载均衡的能力,但是在使用上有以下限制:

  • 默认只提供 4 层负载均衡能力(IP+端口),而没有 7 层功能(主机名和域名),但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的

  • 后续可以通过Ingress方案,添加7层的能力
    在这里插入图片描述
    Service 在 K8s 中有以下四种类型(这部分看不懂可以先跳过,说的service如何对外暴露服务,后面使用ingress简单很多)

  • Clusterlp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP
    在这里插入图片描述

  • NodePort:在ClusterlP基础上为Service在每台机器上绑定一个端口,这样就可以通过:NodePort 来访问该服务。访问node01的30001相当于访问定义的SVC后端的80的三个不pod同服务(RR)
    client——》nginx(负载接收器,反向代理)——》node1,node2
    在这里插入图片描述

  • LoadBalancer:在NodePort的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到
    :NodePort
    在这里插入图片描述

  • ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有kubernetes1.7或更高版本的kube-dns才支持
    在这里插入图片描述

其它

StatefulSet

StatefulSet通常用来部署有状态应用,如Mysql服务,服务运行的实例需要在本地存储持久化数据,多个实例之间有依赖拓扑关系,比如:主从关系、主备关系。如果停止掉依赖中的一个Pod,就会导致数据丢失或者集群崩溃。他的核心功能就是通过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。它包含Deployment控制器ReplicaSet的所有功能,增加可以处理Pod的启动顺序,为保留每个Pod的状态设置唯一标识,同时具有以下功能:

稳定的、唯一的网络标识符

稳定的、持久化的存储

有序的、优雅的部署和缩放

DaemonSet

DaemonSet:服务守护进程,它的主要作用是在Kubernetes集群的所有节点中运行我们部署的守护进程,相当于在集群节点上分别部署Pod副本,如果有新节点加入集群,Daemonset会自动的在该节点上运行我们需要部署的Pod副本,相反如果有节点退出集群,Daemonset也会移除掉部署在旧节点的Pod副本。

DaemonSet的主要特征:

这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上;

每个节点上只会运行一个这样的 Pod 实例;

如果新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;

而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉。

DaemonSet常用场景:

网络插件的 Agent 组件,如(Flannel,Calico)需要运行在每一个节点上,用来处理这个节点上的容器网络;

存储插件的 Agent 组件,如(Ceph,Glusterfs)需要运行在每一个节点上,用来在这个节点上挂载F远程存储目录;

监控系统的数据收集组件,如(Prometheus Node Exporter,Cadvisor)需要运行在每一个节点上,负责这个节点上的监控信息搜集。

日志系统的数据收集组件,如(Fluent,Logstash)需要运行在每一个节点上,负责这个节点上的日志信息搜集。

Job/CronJob

Job负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束,解决一些需要进行批量数据处理和分析的需求,,比如Jenkins Slave,发布完代码后任务结束,Pod自动销毁;

CronJob则就是在Job上加上了时间调度,用来执行一些周期性的任务。

ConfigMap

ConfigMap:就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性,因为一个configMap其实就是一系列配置信息的集合,将来可直接注入到Pod中的容器使用,而注入方式有两种,一种将configMap做为存储卷,一种是将configMap通过env中configMapKeyRef注入到容器中;

RBAC

RBAC:基于角色的访问控制,可以用来给用户授予对集群操作不同的权限。

Secret

Secret:用来保存敏感信息,例如密码、OAuth 令牌和 ssh key等等,将这些信息放在Secret中比放在Pod的定义中或者docker镜像中来说更加安全和灵活。

网络

在实际的业务场景中,业务组件之间的关系十分复杂,特别是随着微服务理念逐步深入人心,应用部署的粒度更加细小和灵活。为了支持业务应用组件的通信,Kubernetes网络的设计主要致力于解决以下问题。
(1)容器到容器之间的直接通信。
(2)抽象的Pod到Pod之间的通信。
(3)Pod到Service之间的通信。
(4)集群外部与内部组件之间的通信。

Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中(都可以通过IP直接到达,其实底层有很多转换机制),这在GCE(Google Compute Engine) 里面是现成的网络模型,K8S假定这个网络已存在。而在私有云搭建K8S集群,就不能假定这个网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的Docker容器之间互相访问先打通,然后再运行K8S。

1.容器到容器的通信

在上节讲过了: docker 在bridge模式下,Docker Daemon第1次启动时会创建一个虚拟的网桥,默认的名称是docker0,然后按照RPC1918的模型在私有网络空间中给这个网桥分配一个子网。针对由Docker创建的每一个容器,都会创建一个虚拟的以太网设备(Veth设备对),其中一端关联到网桥上,另一端使用Linux的网络命名空间技术,映射到容器内的eth0设备,然后从网桥的地址段内给eth0接口分配一个IP地址。
在这里插入图片描述

如上图中的阴影部分所示,在Node上运行着一个Pod实例。在我们的例子中,容器就是图中的容器1和容器2。容器1和容器2共享一个网络的命名空间,共享一个命名空间的结果就是它们好像在一台机器上运行,它们打开的端口不会有冲突,可以直接使用Linux的本地IPC进行通信(例如消息队列或者管道)。其实,这和传统的一组普通程序运行的环境是完全一样的,传统程序不需要针对网络做特别的修改就可以移植了,它们之间的互相访问只需要使用localhost就可以。例如,如果容器2运行的是MySQL,那么容器1使用localhost:3306就能直接访问这个运行在容器2上的MySQL了。

  • 同一个主机的容器,都可以通过doker0网桥和物理机网卡交互。我们这里讲的还是同一个物理机或者虚拟机中的容器互相通信,不同的主机中的容器现在还交互不了,需要搭载pod网络的顺风车。

Pod之间的通信

我们看了同一个Pod内的容器之间的通信情况,再看看Pod之间的通信情况。
每一个Pod都有一个真实的全局IP地址,同一个Node内的不同Pod之间可以直接采用对方Pod的IP地址通信,而且不需要采用其他发现机制,例如DNS、Consul或者etcd。
Pod容器既有可能在同一个Node上运行,也有可能在不同的Node上运行,所以通信也分为两类:同一个Node内Pod之间的通信和不同Node上的Pod之间的通信。

同一个Node内Pod之间的通信

我们看一下同一个Node内两个Pod之间的关系,如下图所示:
在这里插入图片描述

可以看出,Pod1和Pod2都是通过Veth连接到同一个docker0网桥上的,它们的IP地址IP1、IP2都是从docker0的网段上动态获取的,它们和网桥本身的IP3是同一个网段的。
另外,在Pod1、Pod2的Linux协议栈上,默认路由都是docker0的地址,也就是说所有非本地地址的网络数据,都会被默认发送到docker0网桥上,由docker0网桥直接中转。
综上所述,由于它们都关联在同一个docker0网桥上,地址段相同,所以它们之间是能直接通信的。

不同Node上Pod之间的通信

Pod的地址是与docker0在同一个网段的,我们知道docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行,因此要想实现不同Node上Pod容器之间的通信,就必须想办法通过主机的这个IP地址进行寻址和通信。
另一方面,这些动态分配且藏在docker0之后的所谓“私有”IP地址也是可以找到的。Kubernetes会记录所有正在运行的Pod的IP分配信息,并将这些信息保存在etcd中(作为Service的Endpoint)。这些私有IP信息对于Pod到Pod的通信也是十分重要的,因为我们的网络模型要求Pod到Pod使用私有IP进行通信。所以首先要知道这些IP是什么。
之前提到,Kubernetes的网络对Pod的地址是平面的和直达的,所以这些Pod的IP规划也很重要,不能有冲突。只要没有冲突,我们就可以想办法在整个Kubernetes的集群中找到它。
综上所述,要想支持不同Node上Pod之间的通信,就要满足两个条件:

  • (1)在整个Kubernetes集群中对Pod的IP分配进行规划,不能有冲突;
    (2)找到一种办法,将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。
  • 根据条件1的要求,我们需要在部署Kubernetes时对docker0的IP地址进行规划,保证每个Node上的docker0地址都没有冲突。我们可以在规划后手工配置到每个Node上,或者做一个分配规则,由安装的程序自己去分配占用。例如,Kubernetes的网络增强开源软件Flannel就能够管理资源池的分配。
    根据条件2的要求,Pod中的数据在发出时,需要有一个机制能够知道对方Pod的IP地址挂在哪个具体的Node上。也就是说先要找到Node对应宿主机的IP地址,将数据发送到这个宿主机的网卡,然后在宿主机上将相应的数据转发到具体的docker0上。一旦数据到达宿主机Node,则那个Node内部的docker0便知道如何将数据发送到Pod。如下图所示:
    在这里插入图片描述

网络解决方案K8S+Flannel

ETCD之Flannel提供说明:

>存储管理Flannel可分配的IP地址段资源

>监控ETCD中每个Pod的实际地址,并在内存中建立维护Pod节点路由表

(RealServer可以理解为物理机或者虚拟机,黄色部分代表我们部署的一个真实应用,这个应用部署一个一个pod中。app1=pod1,app2=pod2,app3=pod3,backend=pod4)

  • 同一个 Pod 内部通讯:同一个 Pod 共享同一个网络命名空间,共享同一个 Linux 协议栈,apache和mysql可以直接localhost访问。
  • Pod1 与 Pod2 在同一台机器,由 Docker0 网桥直接转发请求至 Pod2,不需要经过 Flannel
  • Pod1 与 Pod3不在同一台主机,Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。docker0转发到flannel,flannel从etcd查到要访问pod主机的物理ip地址,封装成udp报文转发出去。
    ​​ 请添加图片描述
    图片来自网络

Pod到Service

直接访问Pod资源,存在的缺陷

  • 1.Pod会随时被Deployment这样的控制器删除重建,访问Pod的结果就会变得不可预知
  • 2.Pod的地址是在Pod启动后才被分配,在启动之前并不知道Pod的IP地址
  • 3.应用往往都是由多个运行相同镜像的一组Pod组成,一个个Pod的访问变得不现实
    k8s中Service对象是用来解决上述Pod访问的问题
    Service有一个固定IP地址,Service将访问该地址的流量转发给Pod,pod会将自身的ip上报到api server,然后建立service和pod到Iptables,具体转发给那些Pod通过Label来选择,而且Service可以给这些Pod做负载均衡。各节点的Iptables规则,新版本支持LVS 转发上限、效率更高。
    我们来看看这个pod建立的过程:
    在这里插入图片描述
    etcd键值库只对API server开放,API server就是k8s集群中的控制中心,一般对API server所在的Master做集群,避免因单点故障影响k8s集群中业务的访问。
创建pod
  • 通过kubectl命令输入create pod命令
  • 创建命令到达API server后,API server把创建pod的信息写入到etcd键值库中
  • API server把创建新pod的需求传给scheduler,scheduler通过算法计算分配到合适的Node节点,分配绑定到后端Node上的信息传回至API - server,API server在把此信息写入到etcd键值库中
  • API server传递新建pod信息至Scheduler指定node节点的kubelet程序,kubelet接管后,创建出本地指定的container后,完成信息返回至API server
  • API server把新建好的pod信息写入到etcd键值库中
    至此,一个简单的kubectl create POD_NAME ***就新建完成。这里就建立来pod ip到物理主机到ip映射规则

创建pod节点的service

  • 通过kubectl提交一个pod的service创建请求
  • Controller Manager会通过对应的Label标签查询到相关的pod实例,生-- 成Serveice的Endpoints信息,并通过API server写入到etcd键值库中
  • Worker Node节点上的kube proxy通过API server查询并监听service对象与其对应的Endpoints信息(服务发现),创建一个类似负载均衡器实现- - Service访问到后端Pod的流量转发功能(负载均衡)。
    这就建立来service 别名到pod ip地址之间的映射规则

集群外部与内部组件之间的通信

前面讲到的都是k8s的内部网络,公网是看不见到,要想与外部访问,k8s必须讲服务暴露出去。Kubernetes 暴露服务的有三种方式,分别为 LoadBlancer Service、NodePort Service、Ingress。官网对 Ingress 的定义为管理对外服务到集群内服务之间规则的集合,通俗点讲就是它定义规则来允许进入集群的请求被转发到集群中对应服务上,从来实现服务暴露。 Ingress 能把集群内 Service 配置成外网能够访问的 URL,流量负载均衡,终止SSL,提供基于域名访问的虚拟主机等等。

LoadBlancer Service

LoadBlancer Service 是 Kubernetes 结合云平台的组件,如国外 GCE、AWS、国内阿里云等等,使用它向使用的底层云平台申请创建负载均衡器来实现,有局限性,对于使用云平台的集群比较方便。

NodePort Service

NodePort Service 是通过在节点上暴露端口,然后通过将端口映射到具体某个服务上来实现服务暴露,比较直观方便,但是对于集群来说,随着 Service 的不断增加,需要的端口越来越多,很容易出现端口冲突,而且不容易管理。当然对于小规模的集群服务,还是比较不错的。

Ingress网关

Ingress 使用开源的反向代理负载均衡器来实现对外暴露服务,其实就相当于 nginx、haproxy 等负载均衡代理服务器,目前选择有很多: traefik、nginx-controller、Kubernetes Ingress Controller for Kong、HAProxy Ingress controller等。Nginx Ingress 一般有三个组件组成:

1)ingress是kubernetes的一个资源对象,用于编写定义规则。指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。

2)反向代理负载均衡器,通常以Service的Port方式运行,接收并按照ingress定义的规则进行转发,通常为nginx,haproxy,traefik等,本文使用nginx。
3)ingress-controller,监听apiserver,获取服务新增,删除等变化,并结合ingress规则动态更新到反向代理负载均衡器上,并重载配置使其生效。简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等
以上三者有机的协调配合起来,就可以完成 Kubernetes 集群服务的暴露。
在这里插入图片描述

  • externalLB : 外部的4层负载均衡器
  • ingress-nginx : nodePort 类型的 service 为 ingress-nginx 的 pod 接入外部流量
  • ingress-nginx : ingress-nginx pod, 负责创建负载均衡(一个安装了nginx 的 pod)
  • : Ingress 根据后端 Service 实时识别分类及 IP 把结果生成配置文件注入到 ingress-nginx pod 中
  • site1 : Service 对后端的pod 进行分类(只起分类作用)

总结:到现在我们已经了解完了:

  • 同主机容器到容器间的通信,docker0网桥
  • 同主机pod之间的通信,通过pause的docker0网桥
  • pod和自身物理主机的访问,docker0和物理网卡
  • 不同主机容器间访问,通过pod 网络访问
  • 不同主机的pod访问,通过etcd的pod和物理网卡ip地址映射表访问
  • pod和service,通过service-label-podip
  • 外部和service访问,通过svc机制,暴露服务,通过代理访问。
    以及k8s中各个关键组件之间如何协同工作的。

集群搭建 —— 平台规划

1、生产环境 K8S 平台规划

K8S 环境有两种架构方式,单 Master 集群和多 Master 集群,将先搭建起单 Master 集群,再扩展为多 Master 集群。开发、测试环境可以部署单 Master 集群,生产环境为了保证高可用需部署多 Master 集群。

① 单 Master 集群架构

单 Master 集群架构相比于多 Master 集群架构无法保证集群的高可用,因为 master 节点一旦宕机就无法进行集群的管理工作了。单 master 集群主要包含一台 Master 节点,及多个 Node 工作节点、多个 Etcd 数据库节点。

Etcd 是 K8S 集群的数据库,可以安装在任何地方,也可以与 Master 节点在同一台机器上,只要 K8S 能连通 Etcd。

在这里插入图片描述

② 多 Master 集群架构

多 Master 集群能保证集群的高可用,相比单 Master 架构,需要一个额外的负载均衡器来负载多个 Master 节点,Node 节点从连接 Master 改成连接 LB 负载均衡器。
在这里插入图片描述

参考文献:
1、https://www.e-learn.cn/topic/3880559
2、https://www.pianshen.com/article/54812149204/
3、https://www.cnblogs.com/chiangchou/p/k8s-1.html
4、https://www.cnblogs.com/klvchen/p/9903480.html
5、https://blog.csdn.net/qq_39578545/article/details/108893076?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-108893076-blog-109775528.pc_relevant_antiscanv3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-108893076-blog-109775528.pc_relevant_antiscanv3&utm_relevant_index=2

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值