Kubernetes现已成为在私有云,公共云以及混合云环境中大规模部署容器化应用程序的事实标准。业内最大的几家公有云平台AWS,Google Cloud,Azure,IBM Cloud以及Oracle Cloud现已提供Kubernetes托管服务。几年前,RedHat完全重写了他们的Openshift实现以适配Kubernetes,并且和Kubernetes社区一起合作实现了下一代容器平台。在Kubernetes变得受欢迎后不久,Mesosphere便将Kubernetes的主要功能(如容器分组,覆盖网络,4层路由,secret管理等)整合到他们的容器平台DC/OS中。DC/OS还将Kubernetes作为一个和Marathon相似的容器调度器集成进来。Pivotal最近推出了基于Kubernetes的Pivotal Container Service(PKS),用于在Pivotal Cloud Foundry上部署第三方服务,直到目前为止,还有很多其他组织和技术厂商处在一个加速适配它的阶段。
Kubernetes项目创立于2014年,它的背后是拥有在谷歌运行生产工作负载超过十年经验的谷歌内部容器集群管理平台Borg和Omega。在我看来,它让用户更加方便去适配一些新兴的软件架构模式(如微服务,无服务器功能,服务网格和事件驱动应用程序),并且为整个云原生系统生态铺平了道路。最重要的是,它的云不相关性的设计使得容器化的应用程序无需经过任何修改便可以跑在任何平台上。如今,大型企业的部署可以使用Kubernetes的生态系统,而从长远来看,任何中小型企业也可以通过使用Kubernetes节省大量的基础设施和维护成本。在这篇文章里,我将会介绍到Kubernetes整体上的架构,其应用程序的部署模型,服务发现和负载平衡,内部/外部路由分离,持久卷的使用,在节点上部署守护进程,部署有状态的分布式系统,运行后台作业,部署数据库,配置管理,凭据管理,滚动更新,自动伸缩以及包管理。

这个接近完美的集群管理器采取的基本设计决策之一是能够部署在虚拟机上运行的现有应用程序,而无需对应用程序代码做出任何修改。从整体上来说,任何在虚拟机上运行的应用程序都可以通过简单地容器化其组件的方式部署在Kubernetes上。这是通过其核心功能实现的:容器分组,容器编排,覆盖网络,基于4层虚拟IP路由系统的容器间路由,服务发现,对运行守护程序的支持,部署有状态的应用程序组件,而且最重要的是,它还能够通过扩展容器编排器以支持复杂的编排要求。
从一个相对宏观的层面来讲,Kubernetes提供了一组动态可扩展的主机,用于承载运行工作负载的容器,并使用一组称为master的管理主机,提供用于管理整个容器基础设施的API。工作负载可能包括长期运行的服务,批处理作业和运行在特定容器主机上的守护程序。所有容器主机使用覆盖网络连接在一起以提供容器间的路由。部署在Kubernetes上的应用程序在集群网络是可以动态发现的,而且可以通过传统的负载均衡器暴露到外部网络。集群管理器的状态存放在高度分布式组织的k/v存储里,该存储运行在master实例上。
Kubernetes scheduler将始终确保每个应用程序组件都是经过健康检查的,提供高可用的服务,当副本数量设置为多个时,每个实例在多个主机上进行调度,并且如果其中一个主机变为不可用时,所有在该台主机上运行的容器都会被调度到剩余的其他主机。Kubernetes提供的一项迷人功能是两级自动扩缩。首先,通过使用一个叫做Horizontal Pod Autoscaler(Pod自动水平扩缩器)的资源,它可以为用户提供容器的自动扩缩功能,该资源将会监视资源的消耗并相应地扩展所需的容器数量。其次,它可以根据资源需求添加或删除主机来扩展容器集群本身。 此外,随着集群联盟(cluster federation)功能的引入,它甚至可以使用单个API端点管理一组Kubernetes集群,这些集群甚至可能跨越多个数据中心。
以上只是Kubernetes所提供的开箱即用的功能的概览。在接下来的几节里,本人将为你介绍Kubernetes的核心功能,并说明用户该如何设计自己的软件应用,以便能够立即部署在上面。

上图展示的是Kubernetes宏观层面的应用程序部署模型。它使用一个叫做ReplicaSet的资源来编排容器。我们不妨将ReplicaSet视为基于YAML或基于JSON的一个元数据文件,该文件里定义了容器镜像,端口,副本数,激活运行状况检查(health check),存活状况检查(liveness health check),环境变量,挂载卷以及创建和管理容器所需的一些安全规则。在Kubernetes上,容器总是以所谓Pods的形式成组创建,它是Kubernetes的一个元数据定义或者说是一个资源。每个pod允许在使用了Linux namespace,cgroup和其他内核功能的容器之间共享文件系统,网络接口和操作系统用户。ReplicaSet可以由另外一个名为Deployments的高级资源管理,它被设计用于提供滚动更新和处理回滚等功能。
通过执行下面这样一条简单的CLI命令,用户便可以通过定义一个deployment,在Kubernetes上部署一个容器化的应用程序:
kubectl run <application-name> --image=<container-image> --port=<port-no>
执行上述CLI命令后,它将使用给定的容器镜像创建一个Deployment声明,一个副本集以及一个采用了指定容器镜像的Pod;添加一个应用名的选择器标签。根据当前的设计,由此创建的每个pod将会拥有两个容器,一个用于指定的应用程序组件,另外一个即所谓的pause容器,用于连接网络接口。
服务发现 & 负载均衡

Kubernetes的一个关键特性便是由SkyDNS和4层虚拟IP路由系统提