上篇文章记录了 kubeadm
工具搭建 kubernetes
集群的过程,本文记录 K8S
一些核心概念以及各个组件是如何协调工作的。
1. K8S 核心架构
K8S 采用了控制面 / 数据面(Control Plane / Data Plane)架构,集群中的 主机
被称为节点,主机可以是物理机也可以是虚拟机。其中控制节点叫做 master 节点
,数据节点叫做 worker 节点
。worker 节点
工作是靠 master 节点
进行管理和调度的,进入节点内部如下图所示。
2. mater 节点核心组件
-
apiserver 是
Master
节点中的一个组件,同时也是整个Kubernetes
系统的唯一入口,它对外公开了一系列的RESTful API
,并且加上了验证、授权等功能,所有其他组件都只能和它直接通信,可以说是Kubernetes
里的联络员,如下图所示。
-
etcd 是一个高可用的分布式
Key-Value
数据库,用来持久化存储系统里的各种资源对象和状态,相当于Kubernetes
里的配置管理员。它只与 apiserver 有直接联系,任何其他组件想要读写 etcd 里的数据都必须经过 apiserver。它存储了Kubernetes
对象的所有配置、状态和元数据,包括:pods
、secrets
、daemonsets
、deployment
、configmaps
、statfulsets
等对象。客户端可以通过watch API
订阅事件,kubernetes api-servier
通过该API
跟踪对象状态的变化。所有对象存储在/registry目录下。例如,一个在default
命名空间中,名字为nginx
的pod
,可以在/registry/pods/default/nginx
下找到,如下图所示。
-
scheduler 负责容器的编排工作,检查节点的资源状态,把
Pod
调度到最适合的节点上运行,scheduler
只负责找节点,具体执行还是通过kubelet
来执行的。因为节点状态和Pod
信息都存储在etcd
里,所以scheduler
必须通过api-server
才能获得。当api-server
接收到pod
创建请求,controller manager
会把pod
对象(资源配额是通过controller manager
来做的)存储到etcd
,scheduler
监听到etcd
中pod
信息的变化,使用调度算法选择合适的节点部署pod
,调度信息(pod-node
绑定关系)写入etcd
中,并告知controller manager
,kubelet
监听到pod
对象信息的变化,发起创建pod
请求,创建pod
,并将pod
状态上报api-server
。关于调度策略,
scheduler
采用预选和评分的方式来选择pod
部署的最佳节点。1.在过滤阶段,调度器会找到适合调度
Pod
的节点。根据待调度的Pod
需要的资源要求,筛选出满足资源要求的节点。假设有 5 节点可用资源满足Pod
的资源要求,那么这 5 个节点可以作为备选。如果没有节点能够满足资源要求,那么Pod
是不可调度的,并被移动到调度队列中。如果是一个大型集群,比如有 100 个工作节点,调度器不会遍历所有节点。通过调节参数percentageOfNodesToScore
可以指定大型集群调度器遍历的节点比例。默认情况percentageOfNodesToScore=50%
,调度器会尝试以round-robin
的方式迭代 50% 的节点。如果工作节点分布在多个zone
,那么调度器将遍历不同zone
中的节点。对于超大型集群,percentageOfNodesToScore
的默认值是 5%。
2. 在评分阶段,调度器给过滤后的工作节点打分,并根据分数对节点进行排序。调度程序通过调用多个调度插件进行评分。最后,将选择评分最高的工作节点来调度Pod
。如果所有节点的评分相同,则随机选择一个节点进行调度。
-
controller-manager 管理着所有的控制器,使得各个控制器工作在预期的状态下,如果与
etcd
中的状态不一致则对资源进行协调操作让实际状态和预期状态达到最终的一致,比如故障检测、自动扩展、滚动更新等。它也必须通过api-server
获得存储在etcd
里的信息,才能够实现对资源的各种操作。内置的
kubernetes controllers
包括:node controller
:负责在节点出现故障时发现和响应。replication controller
:负责保证集群中一个资源对象Replication Controller
所关联的pod
副本数始终保持预设值。可理解成确保集群中有且仅有 N 个pod
实例,N 是rc
中定义的pod
副本数量。endpoints controller
:填充端点对象(即连接services
和pods
),负责监听service
和对应的pod
副本的变化。 可以理解端点是一个服务暴露出来的访问点,如果需要访问一个服务,则必须知道它的endpoint
。service account & token controllers
:为新的命名空间创建默认帐户和 API 访问令牌。resourceQuota controller
:确保指定的资源对象在任何时候都不会超量占用系统物理资源。namespace controller
:管理namespace
的生命周期。service controller
:属于 K8S 集群与外部的云平台之间的一个接口控制器
以上组件都被容器化了,运行在集群的 pod
里,可以通过 kubectl
查看他们的状态。
kubectl get pod -n kube-system # -n kube-system 表示命名空间
3. worker 节点核心组件
-
kubelet 是
Node
的代理,负责管理pod
的创建(通过监听etcd
中pod
信息的变化实现),更新和删除,收集node
,pod
状态上报给api-server
。使用集群中配置的CNI
插件为pod
分配IP地址,并为pod
设置必要的网络路由和防火墙规则。
-
kube-proxy 是
node
的网络代理,负责管理容器的网络通信,简单来说就是为Pod
转发TCP/UDP
数据包。通过api-server
,获取有关service
和endpoints
的详细信息。并监视service
和endpoint
的变化。接着,kube-proxy
可以使用以下任何一种代理模式,将流量路由到service
绑定的pod
。kube-proxy
会根据不同配置以不同的模式启动:- iptables 模式
iptables
模式是kube-proxy
使用的第二代模式,该模式在kubernetes v1.1
版本开始支持,从v1.2
版本开始成为kube-proxy
的默认模式。iptables
模式的负载均衡模式是通过底层netfilter/iptables
规则来实现的,通过informer
机制watch
接口实时跟踪service
和endpoint
的变更事件,并触发对iptables
规则的同步更新(来自service
配置)。在
iptables
模式下,kube-proxy
只是作为controller
,而不是server
,真正服务的是内核的netfilter
,体现在用户态的是iptables
。所以整体的效率会比userspace
模式高,见下图。
- ipvs 模式
ipvs(IP Virtual Server)
实现了传输层负载均衡,也就是 4 层交换,作为 Linux
内核的一部分。ipvs
运行在主机上,在真实服务器前充当负载均衡器。ipvs
可以将基于 TCP
和 UDP
的服务请求转发到真实服务器上,并使真实服务器上的服务在单个 IP 地址上显示为虚拟服务。在 v1.11 版本中正式开始使用。
- ipvs 的优点(具体原因后面 controller 章节会解释)
-
ipvs 为大型集群提供了更好的可拓展性和性能
-
ipvs 支持比 iptables 更复杂的负载均衡算法(包括:最小负载、最少连接、加权等)
-
ipvs 支持服务器健康检查和连接重试等功能
-
可以动态修改 ipset 的集合,即使 iptables 的规则正在使用这个集合
-
**container-runtime **是容器和镜像的实际使用者,在
kubelet
的指挥下创建容器,管理Pod
的生命周期,是真正工作的程序。(这里的 container-rutime 是 docker,值得注意的是,并不要求一定是 docker,而且 K8S 1.24 开始彻底放弃了 docker 作为 container-runtime)。常见的容器运行时有,cri-o, containerd, docker,对比如下图所示。
以上三个组件只有 kube-proxy
被容器化了,kubelet
作为管理容器的组件容器化会限制它的能力,必须运行在 container-runtime
之外。
4. 组件之间的交互方式
- 每个
Node
上的kubelet
会定期向apiserver
上报节点状态,apiserver
再存到etcd
里。 - 每个
Node
上的kube-proxy
实现了TCP/UDP
反向代理,让容器对外提供稳定的服务。 -
scheduler
通过apiserver
得到当前的节点状态,调度Pod
,然后apiserver
下发命令给某个Node
的kubelet
,kubelet
调用container-runtime
启动容器。 -
controller-manager
也通过apiserver
得到实时的节点状态,监控可能的异常情况,再使用相应的手段去调节恢复。
5. 插件
除了上面的核心组件,kubernetes
集群要完全运行还需要一些其他的组件,比如 CNI 插件
,CoreDNS
,监控,kubernetes
面板等。文章来源:https://www.toymoban.com/news/detail-820397.html
-
CNI
插件,负责为pod
分配 IP 地址,并使这些pod
能在集群内部相互通信。常见的CNI插件包括calico
,flannel
等。 -
CoreDNS
,充当kubernetes
集群内部的DNS
服务,可基于该服务实现服务发现。 - 监控,收集集群性能参数和节点资源使用情况。
-
kubernetes
面板,通过面板实现集群管理。
6. CNI 插件在集群中是如何工作的
-
Kube-controller-manager
会给每个节点分配一个pod CIDR
, 每个pod
会从pod CIDR
拿到一个唯一的 IP 地址。 -
kubelet
与容器运行时交互以启动预定义的pod
,CRI
插件(容器运行时的一部分)和CNI
插件交互以配置pod
网络。 -
CNI
插件使得不同节点之间实现网络访问。
文章来源地址https://www.toymoban.com/news/detail-820397.html
参考资料
- https://blog.csdn.net/weixin_58544496/article/details/128205060
- https://zhuanlan.zhihu.com/p/669267473
- https://devopscube.com/kubernetes-architecture-explained/
- https://devopscube.com/kubernetes-tutorials-beginners/
- https://devopscube.com/learn-kubernetes-complete-roadmap/#Learn_Ingress_Ingress_Controllers
- https://mikechen.cc/26043.html
- https://blog.csdn.net/qq_45737042/article/details/122089698
- https://zhuanlan.zhihu.com/p/651560930
- https://cloud.tencent.com/developer/article/2363154
- https://blog.csdn.net/youzhouliu/article/details/124860773
- https://v1-28.docs.kubernetes.io/docs/concepts/architecture/
- https://blog.csdn.net/weixin_53072519/article/details/125228115
- https://zhuanlan.zhihu.com/p/490585683
- https://blog.csdn.net/justlpf/article/details/129203746
到了这里,关于K8S 入门实战(3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!