当前位置: 首页 > 科技观察

不懂Kubernetes,被老板请去爬山!

时间:2023-03-15 00:49:56 科技观察

Kubernetes已经成为容器编排领域的王者。是一个基于容器的集群编排引擎,具有集群扩容、滚动升级回滚、弹性伸缩、自动修复、服务发现等多种特性。图片来自Pexels本文将带你快速了解Kubernetes,理解当我们谈论Kubernetes时我们在谈论什么。Kubernetes架构从宏观上看Kubernetes的整体架构,包括Master、Node、Etcd。Master是主节点,负责控制整个Kubernetes集群。它包括APIServer、Scheduler、Controller等组件。直接与Etcd交互。功能包括安全性、注册和发现等。Scheduler:负责按照一定的调度规则将Pod调度到Nodes上。Controller:资源控制中心,确保资源处于预期的工作状态。Node是工作节点,为整个集群提供计算能力,是容器真正运行的地方,包括运行容器、kubelet、kube-proxy:kubelet:主要工作包括管理容器的生命周期,监控与cAdvisor,健康检查,定期上报Node状态。kube-proxy:主要使用service提供集群内的服务发现和负载均衡,同时监控service/endpoints的变化和刷新负载均衡。从创建Deployment开始Deployment是用于编排Pod的控制器资源,我们将在后面介绍。这里我们以Deployment为例,看看架构中的各个组件在创建Deployment资源的过程中做了什么。步骤如下:首先,kubectl发起创建deployment的请求。apiserver接收到创建deployment的请求,将相关资源写入etcd;之后所有组件和apiserver/etcd的交互都是类似的。Deploymentcontrollerlist/watch资源变化并发起创建replicaSet的请求。replicaSetcontrollerlist/watch资源变化,发起创建pod的请求。调度器检测未绑定的pod资源,通过一系列的匹配和过滤选择合适的节点进行绑定。kubelet发现需要在自己的节点上创建新的pod,负责pod的创建和后续的生命周期管理。kube-proxy负责初始化服务相关的资源,包括服务发现、负载均衡等网络规则。至此,经过Kubenetes各个组件的分工协调,完成了从创建Deployment请求到各个具体Pod正常运行的整个过程。Pod在Kubernetes的众多API资源中,Pod是最重要和最基础的,也是最小的部署单元。我们首先要考虑的问题是为什么我们需要Pod?Pod可以说是一种容器设计模式,是为那些“超密”的容器而设计的。我们可以想象一下为Servelet容器部署War包、日志收集等场景。这些容器往往需要共享网络、共享存储、共享配置,所以才有了Pod的概念。对于Pod来说,不同的Container通过InfraContainers统一标识外部网络空间,挂载同一个Volume,存储自然就可以共享,比如对应宿主机上的一个目录。容器编排容器编排是Kubernetes的看家本领,我们需要了解一下。Kubernetes中有很多编排相关的控制资源,比如无状态应用的Deployment,有状态应用的Statefulset,编排守护进程的Daemonset,离线服务的job/cronjob等,我们还是以使用最广泛的Deployment为例。Deployment、Replicatset、Pod之间的关系是层层控制的关系。简单来说,Replicaset控制着Pod的数量,Deployment控制着Replicaset的版本属性。这种设计模式还为两个最基本的编排动作提供了基础,即具有数量控制的水平缩放和具有版本属性控制的更新/回滚。水平缩放水平缩放非常容易理解。我们只需要修改Replicaset控制的Pod副本数,比如从2??修改为3,那么水平缩放的动作就完成了,反之就是水平收缩。Update/rollbackUpdate/rollback反映了Replicaset对象的必要性。例如,我们需要将3个实例的版本从v1更改为v2。然后Replicasetv1控制的Pod副本数会逐渐从3变成0,而Replicasetv2控制的Pod数量会从0变成3。当Deployment下只存在Replicasetv2时,更新完成.回滚的动作则相反。可以找到滚动更新。在上面的例子中,当我们更新应用程序时,Pod总是一个接一个地升级,最少有2个Pod可用,最多有4个Pod提供服务。这种“滚动更新”的好处是显而易见的。一旦新版本出现BUG,剩下的两个Pod依然可以提供服务,同时方便快速回滚。在实际应用中,我们可以通过配置RollingUpdateStrategy来控制滚动更新策略。maxSurge表示Deploymentcontroller可以创建多少个新的Pod;maxUnavailable是指Deployment控制器可以删除多少个旧Pod。Kubernetes中的网络我们了解了容器编排是如何完成的,那么容器是如何通信的呢?说到网络通信,Kubernetes首先要有一个“三通”的基础:NodetoPod可以和Node的Pod通信,不同Node之间的Pod是可以通信的。简单的说,不同的Pod通过cni0/docker0网桥进行通信,Nodes通过cni0/docker0网桥访问Pod。不同Node之间Pod通信的实现方案有很多,包括现在比较常见的Flannel的vxlan/hostgw方式。Flannel通过Etcd学习其他Node的网络信息,并为本Node创建路由表,最终实现不同Node之间的跨主机通信。Microservice—Service在了解接下来的内容之前,我们首先要了解一个非常重要的资源对象:Service。为什么我们需要服务?在微服务中,Pod可以对应一个实例,所以Service对应一个微服务。在服务调用的过程中,Service的出现解决了两个问题:PodIP不固定,使用不固定的IP进行网络调用是不现实的。服务调用需要不同Pod的负载均衡。Service通过Labelselector选择合适的Pod,构建一个Endpoints,也就是Pod的负载均衡列表。在实践中,一般我们会给同一个微服务的Pod实例打上app=xxx这样的标签,并为该微服务创建标签选择器app=xxx的Service。Kubernetes中的服务发现和网络调用有了上述的“三通”网络基础之后,我们就可以开始在Kubernetes中如何实现微服务架构中的网络调用了。这部分内容其实是在讲Kubernetes是如何实现服务发现的。已经解释清楚了。更多详细信息,您可以参考上述文章。这里简单介绍一下。服务间调用首先是东西向流量调用,即服务间调用。这部分主要包括两种调用方式,分别是ClusterIp方式和DNS方式。ClusterIp是一种服务。在这种模式下,kube-proxy通过iptables/ipvs为Service实现了一种VIP(virtualIP)的形式。只需要访问VIP就可以负载均衡的方式访问Service后面的Pod。上图是ClusterIp的一个实现,还包括userSpace代理模式(基本不用),ipvs模式(性能更好)。DNS模式很容易理解。对于ClusterIp方式的Service,它有一条A记录service-name.namespace-name.svc.cluster.local,指向ClusterIp地址。所以在一般的使用中,我们可以直接调用service-name。服务外访问南北向流量,即外部请求访问Kubernetes集群,主要包括三种方式:通过IPtables能力在主机上端口。Loadbalancer是另外一种Service,通过公有云提供的负载均衡器实现。我们可能需要创建100个nodePort/Loadbalancers来访问100个服务。我们希望通过一个统一的外部访问层来访问内部的Kubernetes集群,这就是Ingress的作用。Ingress提供统一的接入层,通过不同的路由规则匹配不同的后端服务。Ingress可以看作是“ServiceofService”。Ingress往往结合nodePort和Loadbalancer来实现,以完成功能。至此,我们已经简单了解了Kubernetes的相关概念,大致是如何工作的,以及微服务在Kubernetes中是如何运行的。所以当我们听到人们讨论Kubernetes时,我们可以知道他们在说什么。作者:fredalxin编辑:陶佳龙来源:https://fredal.xin/what-is-kubernetes