kubernetes学习笔记二(k8s结构说明)

kubernetes学习笔记二(k8s结构说明)

Scroll Down

一、Kubernetes架构组件

    Kubernetes是由google开源的容器集群管理系统,为容器化的集群管理提供运行、资源调度、服务发现、动态伸缩等一些列功能。Kubernetes被称为现代化的数据中心操作系统

 ( 平常的操作系统是对cpu、内存、磁盘、输入输出等硬件设备进行管理,并完成对这些设备的调度;而Kubernetes是以数据中心的物理节点作为对象,并对物理节点上的资源进行调度完成编排任务,且Kubernetes极其容易进行扩展

Kubernetes架构由Google的Borg架构而来,所以先了解一下Borg架构:

Google的Borg架构

image.png

    Brog架构由两部分组成,BrogMaster主要负责请求的分发,其为集群的大脑,真正的工作节点是Borglet,由拓扑可知,为了防止Master单节点故障,其存在很多的副本,且其数量是有一定限制的( 最好是单数,3,5,7,9,因为为了防止有一天master节点出现故障的时候,投票产生主master节点的时候,双数投票可能会产生平票,而单节点则不会产生这种情况 ),所以其数量最好维持在3个以上的基数。

    从架构可以看出来,Borg有多种访问方式,命令行方式,web浏览器方式,以及文件读取方式

    所有的任务到达调度器之后会被分发到不同的节点运行( 并不是调度器scheduler和节点Borglet直接进行交互,而是将数据写入Paxos,Paxos为键值对的一个数据库 ),节点Borglet会实时对数据库Paxos进行监听,如果发现有与自身相关的请求,就会把这个请求取出来处理这个任务。

K8s架构

image.png

Kubernetes从宏观层面来说分为两个层面,即控制节点和计算节点。

  控制层面又称为Master节点,Master节点是整个集群的大脑,负责控制调度集群资源。

  计算层面又称为Node节点,Node节点负责运行工作负载,是Master节点调度的对象。

  kubectl作为Kubernetes客户端,通过和Master节点进行通信来控制Kubernetes集群。

像Borg的副本机制一样,K8S高可用集群副本数据最好是 >= 3 的奇数个

1.1  控制节点Controller Master

Master总体概览图

k8sMaster.png

①  scheduler调度器,负责整个Kubernetes集群的调度工作,接受来自Controller Manager的调度请求,将任务分散到不同的节点node里,用kubelet组件执行。但与Borg不同的是,scheduler不会直接与数据库etcd进行交互,而是将任务交给api server,api server负责将任务写入到etcd,也就是说scheduler不会与数据库etcd直接进行交互

#### <font color=green> ②</font> replication(rc),其就是维护副本的数目(或者叫做期望值),举个例子,想要运行几个副本,就是rc进行控制的,一旦副本数目没有达到期望值,rc就要负责将副本改写到期望值(也就是删除pod或者创建pod)
②  Controller Manager负责管理Cluster各种资源,保证资源处于预期的状态。Controller Manager有多种controller组成,包括replication controller,endpoints controller,namespace controller,serviceaccounts controller等。其中replication controller( 副本控制器 )保证集群的资源处于期望状态( 也就是维护用户定义的副本数目 ),举个例子,想要运行几个副本,就是其进行控制的,一旦副本数目没有达到期望值,其就要负责将副本改写到期望值( 也就是如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收 )

新版本Kubernetes中,建议使用ReplicaSet来取代ReclicationController:

    ReplicaSetReclicationController没有本质的不同,只是名字不一样,但是ReplicaSet支持集合式的selector

    集合式的selector意思就是:集群创建pod的时候,会为其添加许多的标签,当需要对pod进行操作(删除、修改等)的时候,rs(ReplicaSet)就支持通过其标签来操作的集合方案,而rc就不支持。所以在大型项目管理中,rs比rc更简单、更有效。

    selector:标签选择器。不加标签,就会在所有PV找最佳匹配

image.png

③  api server就是一切服务访问的入口

( 调度器scheduler需要与api server进行交互,rc( 副本控制器 )需要与api server进行交互,客户端管理工具kubectl需要与api server进行交互,数据库etc需要与api server进行交互)。这样看其实api server很繁忙,为了减轻api server的压力,与其进行交互的组件还可以在本地生成一个缓存,并不需要每一件事情都到api server进行申请。

1.2  计算节点Node

Node总体概览图

k8sNode.png

1.2.1 service介绍

    Service(简称svc)定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解后台Pod是如何运行。Service通过Label找到Pod组。因为Service是抽象的,所以在图表里通常看不到它们的存在,这也就让这一概念更难以理解。

    svc在整个集群中负责网络服务(并不是底层容器网络实现),因为pod实际上是不可靠的,可能会被停止或者重启,一旦重启就会导致IP地址发生变化,SVC的功能就是使用kube-proxy进行网络的控制,pod的IP发生变化上层业务并不会中断,kube-proxy采用负载均衡等策略实现网络服务。

    例如通过定义一个RC启动了4个pod(即pod副本数量为4),如何让外部能优雅的调用到这几个pod提供的服务?

    由于pod的IP地址可能随时发生变化(pod不健康或期间被重启或被重建等),在pod的外层使用nginx等进行负载也就不太方便了,而Service 就是解决这个问题而存在的:可以根据pod的标签将对应的所有pod纳入一个负载均衡组的形式,通过kube-proxy 进行数据转发,提供一个外部到pod的唯一入口而不用关心pod的变动,进而实现和外部的调用通信。

1.2.2 service的网络服务模式(会在k8s学习笔记三详讲)

qq_pic_merged_1574482425857.jpg

    Service 创建网络服务一般分为集群内部访问(clusterIP )集群外部访问(NodePort)模式

    clusterIP 的方式会创建一个虚拟IP地址,该地址没有基于某个实际网卡创建,所以在宿主机上是无法访问的,仅能在集群内部访问,也就是在容器内部访问;

    NodePort 是通过映射端口到宿主机的方式,访问地址为宿主机IP地址加上端口的方式,和hostPort 类似,但是NodePort 会在kubernetes集群的所有node上监听,也就是说如果创建了一个Service ,配置一个NodePort 监听30000端口,那么集群内所有的node都会监听30000端口,不管用户所访问的那个node上有没有对应的那个pod,该请求都可以被转发到正确的后端那个pod中。也就是说随意访问任何一个node的30000端口的请求都可以被转发到正确的后端pod中

Node节点需要安装三个软件:kubelet、kube-proxy、docker(当然可以是其他容器引擎,主流是docker)

Kubernetes Node主要有两个组件组成:kubelet 和 KubeProxy

①  kubelet是Kubernetes Node上的核心节点,负责与CRI( Container、Running Environment、Interface)进行交互,配置网络和数据卷,监控并上报节点资源的使用情况等,维持Pod的生命周期

②  Kube-Proxy主要负责Service(svc)和Pod实例的请求转发以及负载均衡的规则管理( Kube-Proxy默认操作是操作防火墙实现Pod的映射)

1.3  数据库etcd:

    相当于Borg中的paxos键值对数据库,用来存储持久性数据。提供了kubenetes的持久化方案。( etcd被官方定位为一个可信赖的分布式键值存储服务,它能够为整个分布式集群存储一些关键数据,协助分布式集群的正常运转 )。

     解释可信赖:etcd官方为了使etcd能够持久化,避免其发生单节点故障,所以其天生支持集群化,并不需要其他的组件参与进来就能实现自身集群化。在k8s中,所有数据的存储以及操作记录都在etcd中进行存储,所以对于k8s集群来说,etcd是相当重要的,一旦故障,可能导致整个集群的瘫痪或者数据丢失。

     解释分布式键值存储服务:分布式也就是说扩容时非常方便,键值存储key-value结构。协助分布式的集群的正常运转,也就是说存储整个分布式集群得需要持久化配置文件、配置信息。一旦集群down掉之后,就可以借助etcd中的配置信息进行数据恢复。

    以上就是etcd在kubenetes中的定位

    对于etcd来说,其存储存在两个版本,一个是v2版,一个是v3版。v2会将所有的数据写入到内存中,v3版会引入一个本地的卷的持久化操作,也就意味着关机之后不会造成数据损坏,会从本地进行数据恢复。

image.png

①  etcd架构

etcd内部架构图

image.png

    从图中可以看出来,etcd采用的是http Server的形式,也就意味着采用了http协议构建C/S服务( 除此之外,k8s也是采用http协议进行C/S的开发 )

那为什么要使用Http这种协议呢?因为http协议天生支持put、get、change、授权认证等操作,所以没有必要采用TCP协议开发一系列的认证流程。

  etcd的存储分为内部(内存)存储和持久化(硬盘)存储两部分。内存中的存储除了顺序化地记录所有用户对节点数据变更的记录外,还会对用户数据进行索引、建堆等方便查询的操作。而持久化则使用WAL进行记录存储。

③  Raft:

    用来存储所有的读写信息,会实时的将日志和数据写入到本地磁盘Store进行持久化设置

④  WAL体系

WAL:存储所有事务的变化记录

Snapshot:用于存放某一时刻etcd所有目录的数据

Raft中存储的读写信息如果需要进行修改更新删除,都会进行日志记录存在WAL中。在WAL体系中,持久化存储的目录分为两个:snapshort和wal。snapshot相当于数据压缩,默认会将10000条wal操作记录merge成snapshot,节省存储,又保证数据不会丢失。

备份流程:

    etcd会进行一个完整大版本的备份,然后是一个个小的子版本的备份,当到达规定的时限之后,则会进行一次大版本的备份。一定时限的大版本备份是因为,一方面我们不可能随时进行一次完整大版本的备份,太消耗数据量,另一方面如果子版本的数量过多进行完整版本的备份太过于费事。

数据卷Volume:

数据卷用于实现容器持久化数据,kubernetes对于数据卷重新定义,提供了丰富强大的功能。

k8s有两种类型的数据卷:

一种是本地数据卷,只能作用于本地文件系统。本地数据卷中的数据只会存在于一台机器上,所以当Pod发生迁移的时候,数据便会丢失,无法满足真正的数据持久化要求。但本地数据卷提供了其他用途,比如Pod中容器的文件共享,或者共享宿主机的文件系统。

第二种是网络数据卷。网络数据卷能够满足数据的持久化需求,Pod通过配置使用网络数据卷,每次Pod创建的时候都会将存储系统的远端文件目录挂载到容器中,数据卷中的数据将被永久保存,即使Pod被删除的时候,只是除去挂载数据卷,数据卷中的数据仍然保存在存储系统中,并且当新的Pod被创建的时候,仍是挂载同样的数据卷。

Kubernetes的Volume(数据卷)主要解决了如下两方面问题:

• 数据持久性:通常情况下,容器运行起来之后,写入到其文件系统的文件暂时性的。当容器崩溃后,kubelet 将会重启该容器,此时原容器运行后写入的文件将丢失,因为容器将重新从镜像创建。
• 数据共享:同一个 Pod(容器组)中运行的容器之间,经常会存在共享文件/文件夹的需求

因为k8s中的Pod是随时可以消亡的(节点故障、容器内应用程序错误等原因),那pod消亡后其所依赖的数据又该何去何从呢?
k8s采用pv和pvc 的办法巧妙的解决了这个问题(大多数情况,持久化Volume的实现,依赖于远程存储服务,如远程文件存储(NFS、GlusterFS)、远程块存储(公有云提供的远程磁盘)等)
PersistentVolume(PV):是集群中由管理员配置的一段网络存储。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。
PV描述一个具体的Volume属性,比如Volume的类型、挂载目录、远程存储服务器地址等
PersistentVolumeClaim(PVC)是由用户进行存储的请求。 它类似于pod。 Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。PVC声明可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)。
PVC描述 Pod想要使用的持久化属性,比如存储大小、读写权限等

在Pod的Volumes中,只要声明类型是PVC,指定PVC的名字,当创建这个PVC对象时,k8s就自动为它绑定一个符合条件的Volume,这个Volume,从PV来。(PVC和PV的设计,类似“接口”和“实现”的思想,开发者只知道使用“接口”PVC,运维人员负责给“接口”绑定具体的实现PV,说白了PVC就是一种特殊的Volume)
image.png

① PVC和PV相当于面向对象的接口和实现
② 用户创建的Pod声明了PVC,K8S会找一个PV配对,如果没有PV,就去找对应的StorageClass,帮它创建一个PV,然后和PVC完成绑定
③ 新创建的PV,要经过Master节点Attach为宿主机创建远程磁盘,再经过每个节点kubelet组件把Attach的远程磁盘Mount到宿主机目录

二、其他插件说明

①  CoreDNS:可以为集群中的SVC创建一个域名IP的对应关系解析( 是集群中的一项重要组件,也是一个实现负载均衡的重要组件 )

②  DashBoard:给K8S集群提供一个B/S结构访问体系

③  Ingress Controller:官方只能实现四层代理,Ingress 可以实现七层代理( 也就是可以根据组件名、域名进行负载均衡 )

④  Fedetation:提供一个可以跨集群中心多k8s统一管理功能

⑤  Prometheus(中文:普罗米修斯):提供k8s集群的监控能力

⑥  ELK:提供K8s集群日志统一分析介入平台

三、Kubernetes解决了什么问题?

    Kubernetes项目最主要的设计思想是从更宏观的设计角度以统一的方式来定义任务之间的各种关系。

1、我们可以利用Kubernetes的扩展性灵活的定义任务之间的关系,比如Kubernetes对于容器间的交互关系进行了分类。如果应用之间需要本地文件之间的交互,在常规环境下,这些任务往往会被直接部署到同一台机器上,通过localhost进行通信,通过本地磁盘上的文件进行交互;而在Kubernetes项目中,这些容器则会被划分为一个pod,pod中的容器共享同一个namespace,同一组数据卷,从而达到高效交换信息的目的。pod则是Kubernetes中最基本的一个对象。

2、而对于另外一种更为常见的需求,比如web应用与数据库之间的访问关系,像这样的两个应用往往是不放在一台机器上,这样即使web应用的机器宕机了,数据库也是完全不受影响的。可是我们知道容器的ip是不固定的,那么web容器是如何找到数据库容器的pod的呢?Kubernetes则提供了一种叫做service的服务,Kubernetes的做法是给pod绑定一个service服务,而service服务声明的ip地址等信息是终身不变的,所以service的作用是作为pod的代理入口,代替pod对外暴露一个固定的网络地址

kubnetesSolveProblem.png

学习笔记部分内容来源:
1、尚硅谷汪洋老师学习视频
2、https://www.cnblogs.com/chenqionghe/p/11609008.html
3、https://www.cnblogs.com/web424/p/8042602.html