control plane (master)在分布式系统(尤其是容器编排和云原生架构)中,Control Plane(控制平面)是负责决策、管理和协调整个系统的核心组件集合,相当于系统的大脑,主要作用是维持系统的期望状态,而非直接处理用户业务流量

etcd:分布式、高可用的键值存储系统,用于共享配置、服务发现和协调分布式系统中的各种操作。etcd是分布式系统的分布式数据库为大规模集群提供可靠的信息存储和同步能力

API server(应用程序编程接口服务器)是一个处理API请求的核心组件 作为客户端与后端服务之间的中间层,负责接收、验证、处理请求并返回响应。它是现代分布式系统、微服务架构和云原生应用中的关键基础设施

Scheduler(调度器)是负责分配资源、安排任务执行的核心组件、广泛存在于操作系统、分布式系统、云计算平台等场景中,其核心目标是高效、合理地分配有限资源以完成任务,优化系统性能

controller manager(控制器管理器 )是分布式系统(尤其是kubernetes等容器编排平台)中负责维持系统期望状态的核心组件,通过持续监控集群状态并执行调整操作,确保系统实际状态与用户定义的期望状态一致

worker node工作节点

kubelet是kubernetes集群中运行在每个节点上的核心代理程序,负责管理节点上的容器和pod,是控制平面与节点之间的桥梁。它确保节点上的容器按照pod规范正确运行,并向控制平面报告节点和容器的状态

kube-proxy是kubernetes集群中运行在每个节点上的网络代理组件,主要负责实现kubernetes service(服务)的网络功能,包括服务发现、负载均衡和流量转发,确保pod之间及外部与pod之间的网络通信正常

container runtime(容器运行时)是负责管理容器生命周期的软件,是kubernetes等容器编排平台的基础组件,主要功能包括容器的创建、启动、停止、销毁以及镜像管理等,确保容器能够按照定义的规格(如资源限制、网络配置)运行

k8s内部的三种网络

service网络:pod的负载均衡,是一个集群内部虚拟的四层负载均衡器,也是k8s内部通信的基础

pod网络:pod实际的网络段,是实际的网络命名空间容器ip段

节点网络:就是实际的Nodeip,也就是底层基础设施的ip段

k8s网络插件的作用

k8s本身不包含网络解决方案,node与node之间可以通过节点网络,但是nodeA内部的pod ip和nodeB之间的pod ip应该如何通信

Flannel

使集群中的不同Node主机创建的docker容器都具有全集群唯一的虚拟ip地址

建立一个覆盖网络(overlay network)通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装

创建一个新的虚拟网卡flannel0接受docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)

路由信息一般存放到etcd:多个node上的Flanneld依赖一个etcd cluster来做集中配置服务,etcd保证了所有的node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化实时感知集群中node的变化

Flannel首先会在Node上创建一个名为flannel0的网桥(vxlan类型的设备)并且在每个node上运行一个名为flanneld的代理每个node上的flannel代理会从etcd上为当前node申请一个CIDR地址块用来给该node上的pod分配地址

不同节点上的pod通过flannel网络通信

Calico

calico包括如下重要组件:Felix,etcd,bgp client,bgpreflector

felix:主要负责路由配置以及ACLS规则的配置以及下发,它存在在每个node节点上

etcd:分布式键值存储,主要负责网络元数据一致性,确保calico网络状态的准确性,可以与kubernetes共用

BGPClient(BIRD)主要负责把Felix写入kernel的路由信息分发到当前calico网络确保workload间的通信的有效性

BGProute Reflector(BIRD)大规模部署时使用,摒弃所有节点互联的mesh模式,通过一个或者多个BGProute Reflector来完成集中式的路由分发

不同节点上的pod通过calico网络通信

client是客户端

BGProute reflector 路由反射器

get 列出某个类型的下属资源

describe /dɪˈskraɪb/ 查看某个资源的详细信息

logs 查看某个pod的日志

create 新建资源

explain 查看某个资源的配置项

delete 删除某个资源

edit 修改某个资源

B/S结构和C/S结构

C/S结构即client/server(客户机/服务器)结构,C/S结构在技能上非常成熟,它的重要特征就是交互性强、拥有安全的存取形式、网络通信数量低、响应速度快、利于处置大量数据

B/S结构即rower/server(浏览器/服务器)结构,就是只安装维护一个服务器,而客户端选用浏览器(Browse)运行软件。B/S结构应用程序相对于传统的C/S结构应用程序就是一个特别大的进步。B/S结构重要特征就是分布性强、维护方便、开发简单并且共享性强、总体拥有费用低

对象类型

工作负责型对象(workload):POD,Replicaset,Deployment,statefulset,daemonset,job,cronjob

服务发现及均衡资源对象:service。lngress

配置与存储资源对象:VOLUME(存储卷),CSI(容器存储借口,可以扩展各种各样的第三方存储卷)、configmmap、secret、downwardAPI

集群级资源:Namespace,node,role,clusterrole,rolebinding、clusterrolebinding

元数据型资源:HPA、Limitrange

NODE

node是pod真正运行的主机,可以是物理机,也可以是虚拟机

为了管理pod每个node节点上至少要运行container runtime、kubelet和kube-proxy服务

pod

pod可以由一个或多个容器组成

属于同一个pod的多个容器应用之间相互访问时仅需要localhost就可以通信,使得这一组容器被绑定在了一个环境中

pod是k8s最核心的资源可以理解为应用运行虚拟机

pod控制器

deployment负责无状态应用,能够通过它实现副本高可用,并且实施各种发布策略,滚动升级或者进行版本的回滚

statefulset负责有状态应用,结合无头服务和严格的pod命名机制,实现数据在容器环境中的持久化

daemonset负责代理端应用,例如各种软件的agent,每台机器只需要有一个,zabbix-agent和filebeat都可以用ds形式进行部署

job和cronjob负责离线跑批应用用的比较少

service

service是应用服务的抽象,通过labels(标签)为应用提供四层负载均衡和服务发现

匹配labels的pod ip和端口列表组成endpoints,由kube-proxy负责将服务ip负载均衡到这些endpoints上

每个service都会自动分配一个cluster ip(仅在集群内部可访问的虚拟地址)和DNS名,其他容器可以通过该地址或者DNS来访问服务,不需要了解后端容器的运行

namespace

namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组

常见的pod、service以及deployment等都是属于某一个namespace的(默认是default)

node、persistentvolumes等属于集群共享资源,不属于任何一个namespace

configmap

一种api对象用来将非加密数据保存到键值队

可以用作环境变量、命令行参数或者存储卷中的配置文件

将环境变量配置信息和容器镜像解耦,便于应用配置的修改

pv,pvc,sc

pv描述一个具体的volume属性,比如volume类型、挂载目录、远程存储服务器地址

pvc描述使用者想要使用的持久化属性、比如存储大小、读写权限

sc运维人员根据pv特征、可能是性能、质量级别、备份策略等进行定义的抽象存储通过接收pvc请求从而启动动态实列化pv的效果

ingress

帮助集群中的service能够有一个对外可达的url、即让集群外的客户端也可以访问到自己

专业的七层负载均衡、可以实现url访问和灰度发布、流量调度等多种功能

ssl/tls被基础设施化即便业务本身不具备https的访问

基于一套ip和端口、根据url创建多个虚拟路由,可以通过路径调度到不同的service上

POD创建过程中组件如何协调工作

用户提交创建pod的请求,可以通过apiserver的REST api

也可以用kubectl命令行工具,支持json和yaml两种格式

api处理用户请求存储pod数据到etcd

schedule通过apiserver的watch机制查看新的pod尝试为pod绑定node

过滤主机:调度器用一组规则过滤掉不符合要求的主机比如pod指定了所需要的资源那么就要过滤掉资源不够的主机

主机打分:对第一步筛选出的符合要求的主机进行打分,在主机打分阶段调度器会考虑一些整体优化策略比如把一个replicationcontroller的副本分不到不同的主机上使用最低负载的主机

选择主机选择打分最高的主机进行绑定操作结果存储到etcd中

kubelet根据调度结果执行pod创建操作绑定成功后会启动

container,docker,run,scheduler会调用apiserver的api在etcd中创建bound pod 对象描述在一个工作节点上绑定运行的所有pod信息运行在每个工作节点上的kubelet也会定期与etcd同步bound pod信息,一旦发现应该在该工作节点上运行的bound pod对象没有更新,则调用docker api创建并启动pod内的容器

k8s中的网络模式

k8s内部包含三种网络

serveice网络:即pod的负载均衡,是一个集群内部虚拟的四层负载均衡器,也是k8s内部通信的基本单位

pod网络:pod实际的网络段,是实际的网络命名空间容器ip段

节点网络:就是实际的nodeip,也就是底层基础的ip段

k8s的高可用架构设计选型

使用keepalived和lvs实现控制平面的高可用

集群有三个主节点,三个工作节点,两个用于负载均衡的节点,以及一个虚拟ip地址。在节点故障下,该ip地址可在节点之间漂移,从而实现高可用

内置haproxy创建高可用集群

每个node节点上分布部署了haproxy,kubelet可以反向代理到每个master上

由于apiserver是属于https通信的,所以简单的在任意一台机器上部署kubectl并不可以直接管理k8s这是就需要通过k8s的ca签署每个用户的私钥和证书,通过在k8s配置完成,才可以访问

kubectl只是个go编写的可执行程序,只要为kubectl配置合适的kubeconfig,就可以在集群中的任意节点使用

什么是pod

pod是k8s可以调度的最小工作单元

可以认为一个pod就是一台小型服务器(虚拟机)

一个pod中可以包含多个容器

pause容器划分了一个共享网络命名空间逻辑空间,然后其他容器加进来共享网络命名空间和卷组上述pause+其他容器=pod

yaml文件创建pod的流程

命令中的参数毕竟只能显示有限的几个功能,所以无论是在企业中还是教学中,我们优先选择命令导出pod的通用骨架,然后再手动添加自定义部分

命令创建的pod实际上也是一个yaml文件

命令被kubectl解析成yaml提交给apiserver

apiserver将这个yaml文件保存到etcd中,apiserver作为etcd的网关随时监控这个yaml的变动

k8s整体作为一个实时状态机来维持这个yaml文件描述的状态

在这个状态也就是k8s抽象资源pod的形态

yaml字段

每个podyaml顶格字段都有五个

apiserver:抽象资源的版本号(固定)

kind:抽象资源的类型(固定)

metadata:抽象资源的元数据(固定)

spec:抽象对象的详细信息(自定义修改)

status:抽象对象的实际状态(可以不写)

pod的五种最终状态

pending:这个状态意味着,pod的yaml文件已经提交给了kubernetes,api对象已经被创建并保存到etcd当中,但是这个pod还没有被调度成功。最常见的原因比如pod中某个容器启动不成功

running:这个状态下,pod已经调度成功。也就是它包含的容器都已经创建成功,并且至少有一个正在运行中

succeeded:这个状态意味着,pod里的所有容器都正常运行并退出了。这种情况在运行一次性任务时最为常见

failed:这个状态下,pod里至少有一个容器以不正常的状态退出。这个状态出现时,需要想办法debug这个容器比如查看pod的事件和日志

unknown:这是一个异常状态,意味着pod的状态不能集群检测到,这很有可能是主从节点(master和kubelet)间的通信出现了问题

容器的状态

invalidlmagename:无法解析镜像名称

errimageneverpull:策略禁止拉取镜像

imagepullbackoff:镜像正在重试拉取

errimagepull:通用的拉取镜像出错

createcontainerconfigerror:不能创建kubelet使用的容器配置

createcontainererror:容器创建失败

runcontainererror:启动容器失败

containersnotinitialized:容器没有初始化完毕

containersnotready:容器没有准备完毕

containercreating:容器创建中

podinitializing:pod初始化中

pod的资源限制

资源限制字段主要是:spec、containers、resources

真正占cpu和内存资源的是pod内的容器,所以资源限制要对每个容器做,资源限制有底线使用资源(最小下限)requests和最大使用资源(上限资源)limits

这样就不用担心pod过度占用宿主机资源导致宿主机资源失衡

资源限制衍生的服务优先级

根据k8s对资源设计的规则,如果出现了所有资源被耗尽,紧接着又出现了资源创建的事件,k8s会如何处理

k8s内部有一套机制是基于服务质量保证(qos)的,而最直接反映到的就是pod资源限制的字段设计,这套服务优先级没有一个明确字段说明,它是直接通过requests和limits两个字段的比值来判定优先级的

如果资源已经耗尽,优先级低的pod会优先被删除或者驱逐,给优先级高的后创建的pod腾地方

服务质量保证(qos)在k8s中有三种

guaranteed:pod中requests和limits的cpu和memory均被设置且数值完全一致,那么这个pod的qos就是guaranteed级别,该级别最高最稳固的

burstable:pod中只要有一个容器的requests和limits的设置不相同,或者多一项少一项都无所谓,gaipod的qos即为burstable该级别为二等公民低于guaranteed

best-effort:如果对于全部的resources来说requests与limits均为设置该pod的qos即为best-effort这种pod优先级最低出现资源紧缺情况下优先被清理

对于重要的业务核心业务的pod一定要设置为guaranteed模式

best-errort模式也不是一无是处最大的好处在于没有设置资源限制在资源充裕的情况下该模式可以最大限度使用系统资源

pod中容器的重启策略有三种

Always:总是重启

OnFailure:故障了就重启,exit 0 这种正常退出模式不算故障

Never:从不重启

pod中镜像拉取策略

Always:总是拉取,当镜像tag为latest时且imagepullpolicy未配置默认为Always

Never:不管是否存在都不会拉取

IfNotpresent:镜像不存在时拉取镜像如果tag为非latest且imagepullpolicy未配置默认未ifnotpresent这个也是我们最常用的

pod的健康检查

pod中一共存在三种探针都位于

spec.containers[].startupprobe:k8s在v1.16版本后新添加的阻塞探针,只有该探针成功返回结果后,才会将健康检查交给后面两个探针

spec.containers[].livenessprobe:存活性探针,如果探测失败,则执行pod故障后的重启策略

spec.containers[].readinessprobe:就绪性探针,如果探测失败则会在剔除service后端负载均衡的队列

三种探针的方法

exec:通过执行一个命令,如果命令执行返回值不是0那么就认定本次探测失败容器有问题

tcpsocker:通过对容器的端口进行探测如果端口相应失败那么就认定本次探测失败容器有问题

httpget:通过对容器的应用进行http访问如果访问值大于等于400那么就认定本次探测失败容器有问题

探针的字段三种都是一样一共五项

inittaldelayseconds:60 延后60秒进行第一次检测

periodseconds:10 每10秒进行一次探测

timeoutseconds:1 存活性探测超时时长一般设置一秒就行

successthreshold:1存活性探测连续几次成功才算是通过默认一次就可以

failurethreshold:3 存活性探测连续几次失败才算是pod失败给三次机会

更多推荐