☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython
一、Kubernetes介绍
Kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写。
Kubernetes是一个开源的用于管理云平台中多个主机上的容器化(不一定是Docker)的管理编排引擎。
传统的应用部署方式是通过插件或脚本来安装应用,这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,不利于应用的升级更新/回滚等操作。Kubernetes让部署容器化的应用简单并且高效,它提供了应用部署、规划、更新、维护的一种机制。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦,所以它能在不同云、不同版本操作系统间进行迁移。
Kubernetes提供了完善的管理工具,这些工具覆盖了包括开发、测试部署、运维监控在内的各个环节。因此Kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。
与基于单机的容器化技术对比,K8S可以说是一种集群化的容器化技术。
二、主要功能
- 自动部署(Deployment):Kubernetes基于Docker对应用程序进行包装、实例化和运行,实现应用自动部署到K8S容器集群中,并确保容器在部署后自动重新启动;
- 高可用、高可扩展性:以集群的方式运行、管理跨节点的容器, 通过网络插件解决跨节点容器之间的通信问题, 自我修复机制使得容器集群总是运行在用户期望的状态;
- 水平扩展(Horizontal Pod Autoscaler):Kubernetes可以根据需要自动扩展Pod副本数,以保证服务的高可用性和性能
- 自动服务发现(Service Discovery):Kubernetes可以通过环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址,实现服务的自动发现
- 负载均衡(Load Balancing):Kubernetes可以为多个Pod副本分配一个私有的ClusterIP地址,并使用负载均衡器转发请求到后端容器,实现负载均衡
- 滚动更新(Rolling Update):Kubernetes可以逐步更新服务,而不是同时删除整个服务,从而不中断服务
- 服务编排(Service Orchestration):Kubernetes可以通过文件描述部署服务,使得应用程序部署变得更高效
二、Kubernetes架构
2.1、架构
Kubernetes的整体架构是一个主从分布式架构,由集中式管理节点(Master Node)和分布式的工作节点(Node)组成。
Master Node负责集群的调度管理,包括API Server、Scheduler、ETCD和Controller Manager等组件,计算节点运行一个容器运行环境,如Docker或rkt,同时运行一个K8S的代理用于同主节点通信。
计算节点是K8S集群中真正工作的节点,计算节点也会运行一些额外的组件,像记录日志,节点监控,服务发现等。
- 主节点的API Server是集群的网关,实现统一认证鉴权对外服务,同时也是管理Node/Pod资源代理通道,API Server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。
- 主节点的Scheduler负责资源调度
- 主节点的ETCD是集群状态统一存储,与Zookeeper类似的key–value存储
- 主节点的Controller Manager实现自愈、扩容、应用生命周期管理、服务发现、路由、服务绑定等能力,并提供多种控制器,如Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等
- 每个工作节点(Node)上运行着Kubelet和Kube-Proxy两个组件。Kubelet是负责管理Pod和容器生命周期的代理;Kube-Proxy是一个网络代理,负责为Service提供网络路由
2.2、重要概念介绍
2.2.1、Pod
2.2.1.1、Pod的概念
Pod是在Kubernetes集群中运行的应用单位,是最基本和最小的可部署单元,可以看作是一个单独的逻辑单元,一个Pod可以包含一个或多个相关的容器,这些容器通常需要一起部署、升级和扩展。
Pod封装的对象包括存储资源、网络资源、容器运行配置、一个或多个应用程序容器,因此同一个Pod的容器之间共享存储、网络和运行配置和同一个网络命名空间,可以互相访问网络端口。
通过Kubernetes提供的各种控制器(如Deployment、StatefulSet、Job等)可以方便地管理和维护Pod的运行。
在Pod中运行的容器可以在同一台机器上一起运行,也可以分布在不同节点上。
Pod具有自我修复能力,如果节点挂掉了,那么该节点的Pod会转移到其他节点中。同时,Pod也支持滚动更新和水平扩展等特性。
2.2.1.2、Pod的生命周期
在Kubernetes中,Pod阶段(Pod phase)是Pod在其生命周期中的宏观概述,主要包含以下五种状态:
- Pending(挂起):API Server已经创建了pod资源对象并加入了etcd配置库中,但它尚未被调度完成或者仍处于下载镜像的过程中
- Running(运行):Pod已经被调度至某Node节点,并且所有容器都已经被kubelet创建完成,处于正常运行状态
- Succeed(成功):pod中的所有容器都已经成功终止并且不会被重启
- Failed(失败):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态。
- Unknown(未知):无法获取某个Pod的状态,一般是apiserver与主机通信失败。
总的来说,Pod在其生命周期中会经历不同的状态,下面是这些状态的变迁示意图:
2.2.2、Controller
K8s虽然可以直接管理Pod,但是一般情况下K8S并不直接管理Pod,而是使用Controller来对Pod进行创建和管理。
在Kubernetes中,存在许多不同类型的Controller:
- Deployment :是最常用的控制器,负责Pod的创建、滚动更新、回滚以及支持副本的水平扩容等,创建Deployment时会自动创建ReplicaSet控制器,Deployment通过ReplicaSet实现Pod的多副本管理
- ReplicaSet:用于管理无状态的Pod资源(如web服务器),主要用来代用户创建指定数量的Pod副本,并确保副本数量一直等于设置的数量
- StatefulSet:用于部署有状态应用(如数据库),确保Pod具备唯一的网络标识符和持久存储,并保持Pod的启动顺序和唯一性
- DaemonSet:用于每个Pod只运行一个副本的场景,常用于在Node上运行守护进程类应用
- Job:用于运行结束即刻删除的应用,完成后容器即刻退出
2.2.3、Label
在Kubernetes中,标签(Labels)是附加到各种资源对象(如Pod)上的K-V键值对。标签在K8S中没有实际含义,用于表示资源的标识属性,这些属性对于用户是有意义的,可以通过Label对资源实现多维度的分组管理,进而方便实现资源的分配、调度和部署工作。
标签可以用于组织和选择资源的子集。例如使用标签来将具有相似功能的Pod组合在一起,即使它们在集群中的位置不同,当要管理这些Pod时,只需指定拥有指定标签的Pod即可。
标签还可以用于服务发现和负载均衡。通过使用标签,可以定义一个一个服务的访问点,该访问点将客户端与Pod绑定在一起。即使Pod的IP发生变化,客户端仍然可以通过标签访问它们。因此,标签在服务发现和负载均衡方面扮演着重要角色。
2.2.4、Label Selector
标签选择器(Label Selector)是Kubernetes中的一种分组机制,用于根据标签从集群中来选择和管理一组用相关标签标识的具有共同特征或属性的资源对象。
标签选择器是一种查询语言,标签选择器的查询条件可以是基于等值的标签选择器(使用=、==、!=三个运算符)、基于集合的标签选择器(使用in、notin、exists运算符),也可组合使用。
标签选择器与Pod控制器和服务资源一起使用,用于实现更灵活和可扩展的资源管理。
标签选择器可以与Pod控制器(如Deployment、StatefulSet等)一起使用,以选择和管理Pod的集合。例如,可以使用标签选择器来选择具有特定标签的Pod,并将它们绑定到控制器中。这样,当控制器管理Pod时,它将仅影响具有该标签的Pod。
2.2.5、Service
2.2.5.1、Service概念
Service是Kubernetes(K8s)的核心概念,可以理解为对一组Pod的抽象,为这组Pod提供一个统一的人口地址,并将请求负荷分发到组内各Pod副本上,每个service类似微服务架构中的一个微服务。
下面是一个客户端访问Service的请求,通过标签选择器(Label Selector)分发到对应的Pod过程示意图。
通过标签选择器(Label Selector)与对应的Pod绑定,实现对应的一组Pod的管理,这组Pod统一对外提供服务,就是一个Servcie。
Service就像一个路由器,客户端通过Service访问Pod,即使Pod的IP发生变化,也不会影响客户端的访问。因此,Service肩负着服务发现与负载均衡等职能。
2.2.5.2、Service原理
Service一旦创建,K8S就为其分配一个全局唯一的虚拟IP地址,该地址也称为Cluster IP,Service就成为具备唯一IP地址的通信节点,这种机制下,可以将Service的Name和Service的Cluster IP做个DNS的域名映射,就可实现K8S架构内的服务发现。
Service支持TCP和UDP协议,默认是TCP;
Service支持两种服务发现方法:环境变量和 DNS。
2.2.5.3、Service类型
在Kubernetes中,Service的主要类型包括ClusterIP、NodePort、LoadBalancer和ExternalName。
- ClusterIP:这是默认的类型。当创建一个Service时,如果没有指定类型,那么默认创建的就是ClusterIP类型的Service。这种类型的Service用于在集群内部(同一节点或不同节点)通过ClusterIP互访
- NodePort:用于从集群外部访问的场景,通过节点上的端口访问Service,格式为:
- LoadBalancer:用于从集群外部访问的场景,是NodePort的扩展,通过一个特定的LoadBalance访问Service,外部只需要访问LoadBalancer,再由LoadBalancer将请求转发到节点的NodePort,使用案例如公有云的ELB服务
- None:这种类型的Service用于Pod’间的相互发现,又称为Headless Servcie。Headless Service是一种特殊的Service类型,它直接将请求转发给后端Pod,适用于有状态应用的服务发现和负载均衡等场景。由于直接将请求路由到Pod的IP地址,因此可以避免通过Service层进行负载均衡和代理,从而实现更高效的服务发现和访问。
三、Kubernetes网络
3.1、网络设计原则
3.1.1、设计原则
Kubernetes网络设计原则主要包括以下几点:
- 每个Pod都拥有一个独立的IP地址(IP-per-Pod),且假定所有的Pod都在一个可以直接连通的、扁平的网络空间中,无论它们是否运行在同一个Node中,Pod都可以通过IP地址直接访问。这种设计是为了让用户不需要额外考虑如何建立Pod之间的连接,以及将容器端口映射到主机端口等问题
- 在Kubernetes中,一个Pod内的所有容器共享同一个网络命名空间(network namespace),Pod内容器间可通过localhost相互访问,且Pod内的不同容器间的端口也是共享的。这种设计使得Pod内的容器可以方便地相互通信,而无需使用私有端口。如果一个容器监听了一个端口,其他容器可以通过localhost访问该端口。这种设计简化了容器间的通信过程,并使得在Pod内轻松地实现服务发现和负载均衡变得更加容易。
需要注意的是,虽然Pod内的容器共享网络命名空间和端口,但它们仍然具有各自的PID(进程ID)命名空间和文件系统命名空间。这意味着每个容器都有自己的进程和文件系统空间,以确保它们之间的隔离性。 - Service clusterIP尽可在集群内部访问,外部请求需要通过NodePort、LoadBalance或者Ingress来访问。Service可以为Pod定义一个公共入口点,这个入口点是一个IP地址和端口号,其他Pod可以通过这个IP地址和端口号直接访问该Service所对应的Pod。这样,无论Pod是否运行在同一个Node中,只要它们都在同一个Service网络中,就可以直接通过Service的IP地址和端口号进行通信;
- Kubernetes还通过NetworkPolicy来控制Pod之间的网络通信。NetworkPolicy可以定义规则来控制哪些Pod之间可以通信,从而增强了网络安全性。
这些原则确保了Kubernetes网络设计的灵活性和可扩展性,以支持容器化和云原生应用程序的部署和运行。
3.1.2、Pod限定在同一网络空间的实现
Kubernetes通过一些网络设计和实现来保证所有的Pod都在一个可以直接连通的、扁平的网络空间中:
- 每个Pod都拥有一个独立的IP地址,这个IP地址是分配给Pod的,而不是分配给节点的。这个IP地址是Pod在集群内部的唯一标识,这意味着无论Pod运行在哪个节点上,它都将使用相同的IP地址。这样每个Pod都可以通过其IP地址直接访问其他Pod和Service,这种设计简化了容器间的通信过程,并使得在Pod内轻松地实现服务发现和负载均衡;
- Kubernetes使用了扁平的网络拓扑结构,这意味着所有的Pod都位于同一个网络平面中,可以直接相互通信,而无需进行网络地址转换(NAT)或其他网络代理。Kubernetes的扁平网络拓扑结构是通过使用各种网络插件和策略实现的,但它并不能直接解决跨路由器之间的通信问题。要实现跨路由器的通信,需要在路由器之间手动配置网络路由。
3.2、K8S中的网络接口CNI
CNI(Container Network Interface)是Kubernetes中的一种标准网络接口,它定义了容器网络插件的接口规范,以及具体的网络插件实现。CNI仅仅是一个接口,具体的功能由各个网络插件自己去实现,如创建容器网络空间、将网络接口放到对应的网络空间、为网络接口分配IP等。当kubelet选择使用CNI类型的网络插件时,它会通过CNI接口调用不同的网络插件以实现不同的网络配置方式。
CNI网络插件是一个可执行文件,常见的CNI网络插件包括Calico、Flannel、Terway、Weave Net等。在Kubernetes中,CNI是标准的调用网络实现的接口,Kubelet通过这个标准的接口来调用不同的网络插件以实现不同的网络配置方式。当kubelet创建或删除Pod时,它会调用CRI(Container Runtime Interface),然后CRI会调用CNI来进行Pod的网络构建或删除。
3.3、veth pair虚拟以太网对
3.3.1、概述
veth pair是Linux内核网络子系统中的一种虚拟设备,它由两个veth设备组成,分别被连入两个网络命名空间中。veth pair的一端位于容器内部,另一端则位于容器外部的网络中,用于连接Pod内部的容器和Pod外部的网络。这种设备可以使容器与其所在的网络进行通信。
当一个Pod被创建时,Kubernetes会为该Pod创建一个veth pair。其中一个veth设备被放置在Pod的命名空间中,而另一个veth设备则被放置在宿主机或其他命名空间中。通过这种方式,Pod内部的容器可以通过veth pair与Pod外部的网络进行通信。
当Pod内部的容器需要与外部网络进行通信时,它可以通过localhost访问veth pair的另一端,从而实现了与外部网络的通信。这种设计简化了容器间的通信过程,并提高了应用程序的可伸缩性和灵活性。
最终同一个节点上的Pod通过网桥通信,对于不同节点上的容器,需要通过跨节点路由或网络代理等方式来实现跨节点的通信。
下图是虚拟以太网对通过网桥进行Node内Pod间通信、通过网桥连接Node的以太网实现跨节点访问的示意:
3.3.2、Pod和Service之间的通信
Kubernetes会在创建Service时分配一个全局唯一的虚拟IP地址,这个地址称为Cluster IP,这样Service演变成为具备唯一甲地址的“通信节点”。Kubernetes使用负载均衡为这组pod副本开启一个特定的对外服务端口,并将这组pod副本的Endpoint加入对外服务端口的转发列
表。将service的Name和ClusterlP做一个DNS域名映射即可实现Kubernetes架构内服务发现。
3.3.3、集群外部与内部组件之间的通信
·Kubernetes提供了两种方式实现集群外部与内部pod通信:
- NodePort:service通过Cluster节点的静态端囗对外提供服务。Cluster外部客户端可以通过<Node|P>:访问Service
- LoadBalancer::service利用外部的LoadBalancer服务对外提供服务。LoadBalance的前端是用户的客户端,后端监听则是Cluster内NodeIP和NodePort
四、小结
本文介绍了Kubernetes(K8S)的基本概念、主要功能、架构以及网络通信相关的基础知识,在K8S中Pod是最小的管理单元,Pod内的容器间处于同一个网络空间内可以相互通过localhost+端口直接访问,同一个Node的Pod通过虚拟以太网桥接进行相互访问,跨Node的Pod间通过虚拟以太网对桥接到节点的以太网卡实现跨节点访问。K8S中Service是对外提供服务的虚拟IP加端口映射到集群节点的静态端囗,集群外部可以通过<Node|P>:访问Service。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
更多云计算相关方面的介绍请参考《云计算与公有云服务》专栏的介绍。
关于老猿的付费专栏
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录》;
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录》;
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集》为《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录 》
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬虫入门 》站在一个互联网前端开发小白的角度介绍爬虫开发应知应会内容,包括爬虫入门的基础知识,以及爬取CSDN文章信息、博主信息、给文章点赞、评论等实战内容。
前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。
老猿Python,跟老猿学Python!
☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython ░
原文地址:https://blog.csdn.net/LaoYuanPython/article/details/134797625
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_43078.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!