K8S的核心概念
K8S的核心概念
Cluster
Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用。
Master
Master是Cluster的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master运行在Linux操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个Master。
Node
Node的指责是运行容器应用。Node由Master管理,Node负责监控并汇报容器的状态,并根据Master的要求管理容器的生命周期。Node运行在Linux操作系统,可以是物理机或者是虚拟机。
Pod
Pod是Kubernetes的最小工作单元。每个Pod包含一个或多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。Kubernetes引入Pod主要基于下面两个目的:
①可管理性。有些容器天生就是需要紧密联系,一起工作。Pod提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes以Pod为最小单位进行调度、扩展、共享资源、管理生命周期。
②通信和资源共享。Pod中的所有容器使用同一个网络namespaces,即相同的IP地址和Port空间。它们可以直接用localhost通信。同样的,这些容器可以共享存储,当Kubernetes挂载volume到Pod,本质上是将volume挂载到Pod中的每一个容器。
Pod有两种使用方式:
- 运行单一容器。
one-container-per-Pod是Kubernetes最常见的模型,这种情况下,只是将单个容器简单封装成Pod。即便是只有一个容器,Kubernetes管理的也是Pod而不是直接管理容器。 - 运行多个容器。
但问题在于:哪些容器应该放在一个Pod中?答案是:这些容器联系必须非常紧密,而且需要直接共享资源。举个例子。Pod包含两个容器,一个是File Puller,一个是Web Server。
File Puller会定期从外部的Content Manager中拉取最新的文件,将其存放在共享的volume中。Web Server从volume读取文件,响应Consumer的请求。
这两个容器是紧密协作的,它们一起作为Consumer提供最新的数据;同时它们也通过volume共享数据。所以放到一个Pod是合适的。
再看一个反例:是否需要将Tomcat和MySQL放到一个Pod中?Tomcat从MySQL读取数据,它们之间需要协作,但还不至于需要放到一个Pod中一起部署,一起启动,一起停止。同时它们是之间通过JDBC交换数据,并不是直接共享存储,所以放到各自的Pod中更合适。
Controller
Kubernetes通常不会直接创建Pod,而是通过Controller来管理Pod的。Controller中定义了Pod的部署特性,比如有几个副本,在什么样的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种Controller,包括Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等。Deployment是最常用的Controller,比如前面就是通过Deployment来部署应用的。Deployment可以管理Pod的多个副本,并确保Pod按照期望的状态运行。ReplicaSet实现了Pod的多副本管理。使用Deployment时会自动创建ReplicaSet,也就是说Deployment是通过ReplicaSet来管理Pod的多个副本,我们通常不需要直接使用ReplicaSet。DaemonSet用于每个Node最多只运行一个Pod副本的场景。正如其名称所揭示的,DaemonSet通常用于运行daemon。StatefuleSet能够保证Pod的每个副本在整个生命周期中名称是不变的。而其他Controller不提供这个功能,当某个Pod发生故障需要删除并重新启动时,Pod的名称会发生变化。同时StatefuleSet会保证副本按照固定的顺序启动、更新或者删除。Job用于运行结束就删除的应用。而其他Controller中的Pod通常是长期持续运行。
复制控制器(Replication Controller,RC)
RC是K8s集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。RC是K8s较早期的技术概念,只适用于长期伺服型的业务类型,比如控制小机器人提供高可用的Web服务。
副本集(Replica Set,RS)
RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。
部署(Deployment)
部署表示用户对K8s集群的一次更新操作。部署是一个比RS应用模式更广的API对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作;这样一个复合操作用一个RS是不太好描述的,所以用一个更通用的Deployment来描述。以K8s的发展方向,未来对所有长期伺服型的的业务的管理,都会通过Deployment来管理。
服务(Service)
Deployment可以部署多个副本,每个Pod都有自己的IP,外界如何访问这些副本呢?通过Pod的IP吗? 要知道Pod很可能会被频繁地销毁和重启,它们的 IP 会发生变化,用IP来访问不太现实。 答案是Service。Kubernetes Service定义了外界访问一组特定Pod的方式。Service有自己的IP和端口,Service为Pod提供了负载均衡。Kubernetes运行容器(Pod)与访问容器(Pod)这两项任务分别由Controller和Service执行。RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。在K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由Kube-proxy实现的。Kube-proxy是K8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的Kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。
Namespace
如果有多个用户或项目组使用同一个 Kubernetes Cluster,如何将他们创建的 Controller、Pod 等资源分开呢?
答案就是 Namespace。
Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。
Kubernetes 默认创建了两个 Namespace。
·default – 创建资源时如果不指定,将被放到这个 Namespace 中。
·kube-system – Kubernetes 自己创建的系统资源将放到这个 Namespace 中