Kubernetes容器集群管理系统调研与对比

  1.  Kubernetes简介

1.1 什么是Kubernetes

首先,Kubernetes是一个全新的基于容器技术的分布式架构领先方案。Kubernetes是Google开源的容器集群管理系统,其提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能如下:

  1. 使用Docker对应用程序进行包装(package)、实例化(instantiate)、运行(run)。
  2. 以集群的方式运行、管理跨机器的容器。
  3. 解决Docker跨机器容器之间的通讯问题。
  4. Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态。

1.2 Kubernetes的体系架构

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

Kubectl:Kubernetes的命令行工具,用于执行CRUD相关操作。

Kubelet:Kubelet负责管理pods和它们上面的容器,images镜像、volumes、etc。

Kube-proxy:每一个节点(node)也运行一个简单的网络代理和负载均衡,即Kube-proxy,正如Kubernetes API里面定义的这些服务也可以在各种终端中以轮询的方式做一些简单的TCP和UDP传输。服务端点目前是通过DNS或者环境变量。这些变量由服务代理所管理的端口来解析。

Kubernetes控制面板:Kubernetes控制面板可以分为多个部分。目前它们都运行在一个master 节点,然而为了达到高可用性,这需要改变。不同部分一起协作提供一个统一的关于集群的视图。

etcd:所有master节点的持续状态都存在etcd的一个实例中。这可以很好地存储配置数据。因为有watch(观察者)的支持,各部件协调中的改变可以很快被察觉。

Kubernetes API Server:API服务提供Kubernetes API的服务。这个服务试图通过把所有或者大部分的业务逻辑在单独的组件或插件中实现,从而使其具有CRUD特性。它主要处理REST操作,并在etcd中验证更新这些对象(最终存储)。

Scheduler:调度器把未调度的pod通过binding api绑定到节点上。调度器是可插拔的,并且我们期待支持多集群的调度,未来甚至希望可以支持用户自定义的调度器(已经支持)。

Kubernetes控制管理服务器:所有其它的集群级别的功能目前都是由控制管理器所负责。例如,端点对象是被端点控制器来创建和更新。这些最终可以被分隔成不同的部件来让它们独自的可插拔。

Replication Controller:它是建立于简单的 pod API之上的一种机制,可以维持集群环境中目标pod的副本数等。

1.3 Kubernetes可以做什么

如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成Kubernetes内部使用的低级别组件。Kubernetes不仅仅支持Docker,还支持Rocket,这是另一种容器技术。运用Kubernetes技术,我们可以实现:

  1. 全面拥抱微服务架构
  2. 使用Kubernetes的系统可以随时的整体迁移
  3. Kubernetes系统具备了超强的横向扩容能力
  4. Kubernetes提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节。
  1.  Kubernetes相比传统的应用部署方式

传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

Kubernetes采用容器化方式部署应用,容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势。使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚机轻量、更“透明”,这更便于监控和管理。

2.1 个体与整体

传统的应用部署流程主要是通过将应用打包(jar或war等)部署在tomcat等web应用容器中,通过启动一个进程来实现应用的运行。当应用越来越多,对于多个应用的管理显得力不从心,应用与应用之间的关系也变得甚为复杂,当一个服务出现问题,可能会引发整体服务的崩溃,却不知从何查起。

Kubernetes提供容器化部署的环境,将每个微服务都以容器化的方式部署在这个环境中,可以实时控制应用的副本数、管理应用的生命周期和资源分配、以及实现对应用的实时监控等。不仅能针对单个应用个体进行管理,还能从整体查看全部应用的运行状态以及单个应用对全部应用的影响。

2.2 负载均衡、服务发现

针对于传统应用部署场景,如果我们需要实现应用的多实例和负载均衡,我们需要针对单个应用启动多个不同的进程,并为每个进程分配不同的端口,再结合Nginx等负载均衡软件进行特定化配置来实现。该部署过程不仅复杂,而且由于引入了第三方的负载均衡软件,给后期的运维工作带来了诸多不确定性和额外的工作量。

Kubernetes自带的服务发现功能和Replication Controller模块可以轻松的通过参数修改实时进行应用的实例数控制,多个实例共用一个端口号避免端口资源的浪费。Kubernetes的Scheduler模块根据集群内每个节点(node)的资源状态,将实例分配到不同的节点上运行,实现资源的合理使用;同时Api Server根据每个实例的负载情况和运行状态进行服务请求调用的最优分配。即使某一个应用实例由于某种原因宕机,Kubernetes也会立即运行一个新的实例进行替换,时刻保持应用的实例维持在用户设置的数目,保证高可用。

2.3 资源分配控制

Kubernetes通过配置应用容器的启动文件(Kubernetes部署应用所需的主要文件),可以方便地手动实现该应用正常运行所能获得的最高和最低资源条件,包括CPU、内存、GPU等资源,也可以选择放弃手动配置让Kubernetes根据应用运行状态和资源情况自动为其分配合理的资源,并保证应用的正常运行。

2.4 迁移部署方便

传统应用的部署依赖所在主机的环境配置,对硬件或者软件有一定的要求,由于不同环境不同主机本身的差异化,导致传统应用的部署或者迁移经常出现意想不到的问题。而Kubernetes架构下,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间的进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。

  1.  Kubernetes与微服务架构的关系

微服务最早由Martin Fowler与James Lewis于2014年共同提出,微服务架构风格是一种使用一套小服务来开发单个应用的方式途径,每个服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API,这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些服务使用不同的编程语言实现,以及不同数据存储技术,并保持最低限度的集中式管理。

目前比较流行的微服务架构主要是Spring Cloud。

3.1 Kubernetes与Spring Cloud的功能对比

Spring Cloud和Kubernetes有很大的不同,并没有直接可比的特性,如果对照微服务架构的要点,可以得出如下的技术对比图表:

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

从上表我们可以得知:

Spring Cloud有一套丰富且集成良好的JAVA库,作为应用栈的一部分解决所有运行时问题。因此,微服务本身可以通过库和运行时代理解决客户端服务发现、负载均衡、配置更新、统计跟踪等。工作模式就像单实例服务集群并且一批工作也是在JVM中被管理。

Kubernetes是多语言的,不仅仅针对Java平台,而是以通用的方式为所有语言解决分布式计算问题。Kubernetes提供了配置管理、服务发现、负载均衡、跟踪、统计、单实例、平台级和应用栈之外的调度工作。该应用不需要任何客户端逻辑的库或代理程序,可以用任何语言编写。

两个平台依靠相似的第三方工具,如ELK和EFK stacks, tracing libraries等。Hystrix和Spring Boot等库,在两个环境中都表现良好。很多情况下,Spring Cloud和Kubernetes可以形成互补,组建出更强大的解决方案(例如KubeFlix和Spring Cloud Kubernetes)。

3.2 二者的优缺点

有些需求,Spring Cloud表现更好,有些需求则是Kubernetes更优,也有些需求,两者可以用不同的方式满足。Spring Cloud和Kubernetes在使用上并不冲突。例如,Spring Cloud提供Maven插件来创建单独Jar应用程序包。结合Docker、Kubernetes的声明式部署和调度能力,轻松运行微服务。同样,Spring Cloud以应用程序内的包装库的形式来支持弹性伸缩,微服务容错使用Hystrix(bulkhead和断路器模式)与Ribbon(负载均衡)。但这些是不够的,当组合Kubernetes健康检查、程序重启和自动伸缩能力,微服务才真正变成一个强壮的系统。

3.2.1 Spring Cloud优缺点

Spring Cloud为开发者提供了快速构建分布式系统中的一些常见模式的工具,例如配置管理,服务发现,断路器,路由等。它是为Java开发人员使用,构建在Netflix OSS库之上的。

优点:

  1. Spring Platform提供的统一编程模型和Spring Boot的快速应用程序创建能力,为开发人员提供了很好的微服务开发体验。使用很少的注解,就可以创建一个配置服务器或获得客户端库来配置服务。
  2. 丰富的库支持,覆盖大多数运行时需求。Spring Cloud的所有库均由Java编写,具有多特性、高控制和易配置等特点。
  3. 不同的Spring Cloud库彼此完全兼容。例如,Feign客户端还将使用Hystrix用于断路器、Ribbon用于负载均衡请求。一切都是注解驱动的,易于Java开发者开发。

缺点:

  1. 仅使用Java,既是Spring Cloud的优点,也是一大缺陷。微服务架构之所以吸引人,在于按需交换各种技术栈、库,甚至语言的能力。这一点,Spring Cloud做不到。如果你想使用Spring Cloud/Netflix OSS基础设置服务,例如配置管理、服务发现或者负载均衡,解决方案是不优雅的。虽然Netflix Prana项目实现了sidecar模式,显示基于Java客户类库越过HTTP,使得用non-JVM语言编写的应用程序存在于NetflixOSS生态系统变得可能,但它仍然不是很优雅。
  2. 除了Jvava应用程序,还有太多与开发无关的事情需要Java开发人员处理。每个微服务需要运行各种客户端以进行配置检索、服务发现和负载均衡。虽然很容易设置,但这并不会降低对环境的构建时间和运行的依赖性。例如,开发人员可以使用@EnableConfigServer创建一个配置服务器,但这只是开心的假象。每当开发人员想要运行单个微服务时,他们需要启动并运行Config Server。对于受控环境,开发人员必须考虑使Config Server高度可用,并且由于它可以由Git或SVN支持,因此它们需要一个共享文件系统。同样,对于服务发现,开发人员也是需要首先启动Eureka服务器。为了创建一个受控的环境,他们需要在每个AZ上使用多个实例实现集群。可以说,开发人员除了实现所有功能外,还需要额外管理一个复杂的微服务平台。
  3. Spring Cloud目前在微服务方面覆盖的面相对有限,开发人员还需要考虑自动化部署、调度、资源管理、过程隔离、自我修复、构建流水线等,以获得完整的微服务体验。对于这点,我认为拿Spring Cloud和Kubernetes比较是不公平的,应该比较Spring Cloud + Cloud Foundry (or Docker Swarm)和Kubernetes。但这也意味着对于一个完整的端到端微服务体验,Spring Cloud必须补充一个像Kubernetes这样的应用程序平台。

3.2.2 Kubernetes的优缺点

Kubernetes是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。支持多种语言并且提供用于支持、运行、扩展和管理分布式系统的操作系统。

优点:

  1. Kubernetes是多语言且语言不敏感的容器管理平台,能够运行云原生和传统的容器化应用程序。Kubernetes提供的服务(如配置管理、服务发现、负载均衡、测试指标收集和日志聚合)可供各种语言使用。这意味着一个平台可以被多个团队(包括使用Spring的Java开发人员)使用,并提供多种用途:应用程序开发、测试环境、构建环境(源码运行、构建服务、依赖仓库)等。
  2. 与Spring Cloud相比,Kubernetes解决了更广的微服务架构问题。除了提供运行时服务,Kubernetes也可以让你制定环境、设置资源限制、RBAC、管理应用程序生命周期、允许自动扩容和自我修复(几乎表现得像一个抗脆弱平台)。
  3. Kubernetes技术基于Google十五年的研发和容器管理经验。此外,Kubernetes有近1000个贡献者,是Github上最活跃的开源社区之一。

缺点:

  1. Kubernetes是多语言的,因此它的服务是通用的,并不针对不同的平台(如Spring Cloud for JVM)进行优化。例如,配置会作为环境变量传递给应用程序或挂载的文件系统。它没有像Spring Cloud Config提供的配置更新功能。
  2. Kubernetes不是一个以开发者为中心的平台,更偏向于DevOps的IT人员使用。因此,Java开发人员需要学习一些新的概念,需要学习解决问题的新方法。尽管通过MiniKuber开始一个Kubernetes开发实例很简单,但手动安装一个高可用的Kubernetes集群仍显得有些复杂。
  3. Kubernetes是一个相对较新的平台,仍然在发展和成长,每个版本都添加了很多新功能,可能很难跟上(这一点已经被官方考虑到了,Kubernetes的API将是可扩展和向后兼容的)。

3.2.3 Spring Cloud和Kubernetes的最佳实践

Spring Cloud和Kubernetes在核心领域都很强,并且在其他领域正努力改进。Spring Cloud可以快速使用,对开发者比较友好;而Kubernetes是DevOps的绝配,虽然学起来可能有点难,但是覆盖了更广泛的微服务技术要点。

Kubernetes容器集群管理系统调研与对比_第1张图片

Spring Cloud和Kubernetes处理了不同范围内的微服务架构技术点,而且使用了不同的方法。Spring Cloud方法是试图解决在JVM中的微服务架构要点,而Kubernetes方法是试图让问题消失,为开发者在平台层解决。Spring Cloud在JVM中非常强大,Kubernetes管理那些JVM很强大。

 

Kubernetes容器集群管理系统调研与对比_第2张图片

各取所长,充分利用这两者的优势是当下及未来的趋势。结合使用Spring Cloud和Kubernetes,用Spring Cloud提供应用程序打包,Docker和Kubernetes负责部署和调度;Spring通过Hystrix线程池提供应用程序内隔离,Kubernetes通过资源、进程和命名空间隔离;Spring为每个微服务提供健康终端,Kubernetes执行健康检查并且为健康服务的通信提供路由等服务。

  1.  Kubernetes部署应用的流程

4.1 环境准备

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

  1. 搭建Kubernetes集群环境
  2. 搭建Docker环境以及私有镜像仓库环境

4.2 应用部署

  1. 基于该应用制作的能够正常运行的Docker镜像并推送到私有镜像仓库。
  2. 准备与应用本身运行相关的配置文件,如application.yaml文件。
  3. 制作该应用在Kubernetes环境部署所需的配置文件,主要包括两个以.yaml后

缀的文件:一个是和服务发现和端口映射相关的service文件;一个是和所需资源、 副本数、文件挂载配置等相关的RS、DS或Deployment等类型文件。

  1. 执行kubectl命令运行上述yaml文件。
  2. 执行kubectl命令(或者通过部署dashboard可视化界面)监视应用部署状态、

排错。

  1. 测试部署的应用。

4.3 部署示例

基于Spring Boot开发的Java微服务为例:

 

  1. 该微服务的名称为:test-pressure。
  2. 搭建的私有镜像仓库名称为:registry.guoyuan.com。
  3. 基于该微服务制作的Docker镜像在私有镜像仓库中的名字为:

registry.guoyuan.com/test-pressure:1.0。

  1. 基于该微服务制作的yaml文件分别为:

     test-pressure-service.yaml、test-pressure-deployment.yaml

二者之间通过selector字段进行关联。

 

test-pressure-service.yaml

 

 
 

apiVersion: v1

kind: Service

metadata:

  name: test-pressure-svc

  labels:

    name: test-pressure-svc

spec:

  type: NodePort

  ports:

  - port: 22035

    protocol: TCP

    targetPort: 22035

    name: http

    nodePort: 30035

  selector:

    name: test-pressure-pod

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

test-pressure-deployment.yaml

 

 
 

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: test-pressure

  labels:

    name: test-pressure

spec:

  replicas: 1

  selector:

    matchLabels:

      name: test-pressure-pod

  template:

    metadata:

      labels:

        name: test-pressure-pod

    spec:

      containers:

      - name: pressure

        image: registry.guoyuan.com/test-pressure:1.0

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 22035

      imagePullSecrets:

      - name: guoyuan

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

注:(本文中图片均来自于网络)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(kubernetes)