如果我们的系统设计遵循了 Kubernetes 的设计思想,那么传统系统架构中那些和业务没有多大关系的底层代码或功能模块,都可以立刻从我们的视线中消失,我们不必再费心于负载均衡器的选型和部署实施问题,不必再考虑引入或自己开发一个复杂的服务治理框架,不必再头疼于服务监控和故障处理模块的开发。总之,使用 Kubernetes 提供的解决方案,我们不仅节省了不少于30%的开发成本,同时可以将精力更加集中于业务本身,而且由于Kubernetes
提供了强大的自动化机制,所以系统后期的运维难度和运维成本大幅度降低。
Kubernetes 是一个开放的开发平台。与 J2EE 不同,它不局限于任何一种语言,没有限定任何编程接口,所以不论是用 Java、 Go、 C++还是用 Python 编写的服务,都可以毫无困难地映射为 Kubernetes 的 Service, 并通过标准的 TCP 通信协议进行交互。此外,由于 Kubernetes 平台对现有的编程语言、编程框架、中间件没有任何侵入性,因此现有的系统也很容易改造升级并迁移到Kubernetes平台上。
最后,Kubernetes 是一个完备的分布式系统支撑平台。 Kubernetes 具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时, Kubernetes 提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。因此,Kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。
在 Kubernetes 中, Service (服务)是分布式集群架构的核心,一个 Service对象拥有如下关键特征。
mysql-server
)。ClusterIP
、ServiceIP
或VIP
)和端口号。 一组容器应用
上。Service
的服务进程目前都基于Socket
通信方式对外提供服务,比如 Redis、 Memcache、 MySQL、 Web Server,或者是实现了某个具体业务的一个特定的TCP Server
进程 。虽然一个 Service 通常由多个相关的服务进程
来提供服务,每个服务进程都有一个独立的Endpoint (IP+Port)
访问点,但 Kubernetes 能够让我们通过 Service (虚拟 Cluster IP + Service Port〉连接到指定的 Service 上。有了 Kubernetes
内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响到我们对服务的正常调用。更重要的是这个Service本身一旦创建就不再变化,这意味着在 Kubernetes 集群中,我们再也不用为了服务的 IP 地址变来变去的问题而头疼了 。
容器提供了强大的隔离功能,所以有必要把为 Service 提供服务的这组进程放入容器中进行隔离。为此,Kubernetes 设计了Pod
对象,将每个服务进程包装到相应的Pod
中,使其成为Pod
中运行的一个容器(Container)。为了建立Service
和Pod
间的关联关系, Kubernetes 给每个Pod贴上一个标签(Label)
,给运行MySQL
的Pod贴上name=mysql
标签,给运行PHP的Pod
贴上name=php
标签,然后给相应的 Service 定义标签选择器( Label Selector),比如MySQL Service
的标签选择器的选择条件为name=mysql
,意为该Service要作用于所有包含name=mysql
Label的Pod上。这样一来,就巧妙地解决了Service与Pod的关联问题。
说到 Pod,我们这里先简单介绍其概念。首先,Pod
运行在一个我们称之为节点(Node)的环境中,这个节点既可以是物理机,也可以是私有云或者公有云中的一个虚拟机,通常在一个节点上运行几百个Pod,其次,每个 Pod 里运行着一个特殊的被称之为Pause
的容器,其他容器则为业务容器,这些业务容器共享Pause
容器的网络栈和Volume
挂载卷,因此它们之间的通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod 中;最后,需要注意的是,并不是每个 Pod 和它里面运行的容器都能“映射”到一个Service上,只有那些提供服务(无论是对内还是对外)的一组Pod才会被“映射”成一个服务
。
在集群管理方面,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点(Node)。其中,在Master
节点上运行着集群管理相关的一组进程kube-apiserver
、kube-controller-manager
和kube-scheduler
,这些进程实现了整个集群的资源管理、 Pod 调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。 Node作为集群中的工作节点,运行真正的应用程序,在 Node 上 Kubernetes 管理的最小运行单元是 Pod。 Node 上运行着 Kubernetes 的 kubelet、kube-proxy 服务进程,这些服务进程负责 Pod 的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。
最后,我们再来看看传统的 IT 系统中服务扩容和服务升级这两个难题,以及 Kubernetes 所提供的全新解决思路。服务的扩容涉及资源分配(选择哪个节点进行扩容)、实例部署和启动等环节,在一个复杂的业务系统中,这两个问题基本上靠人工一步步操作才得以完成,费时费力又难以保证实施质量 。
在 Kubernetes 集群中,你只需为需要扩容的 Service 关联的 Pod 创建一个 RC (Replication Controller)
,则该 Service 的扩容以至于后来的 Service 升级等头疼问题都迎刃而解。在一个 RC 定义文件中包括以下3个关键信息。
在创建好 RC(系统将自动创建好 Pod)后,Kubernetes 会通过 RC 中定义的 Label 筛选出对应的 Pod 实例并实时监控其状态和数量,如果实例数量少于定义的副本数量(Replicas),则会根据 RC 中定义的 Pod 模板来创建一个新的Pod,然后将此 Pod调度到合适的 Node 上启动运行,直到 Pod 实例的数量达到预定目标。这个过程完全是自动化的,无须人工干预。有了RC,服务的扩容就变成了一个纯粹的简单数字游戏了,只要修改 RC 中的副本数量即可。后续的Service
升级也将通过修改RC
来自动完成。