如何快速了解Kubernetes架构
Last updated
Last updated
本篇文章我们将会探讨Kubernetes的整体架构。
Kubernetes起源自Google内部系统Borg,它是容器应用集群部署和管理的系统。Kubernetes核心功能是为了减轻物理机或者虚拟机集群编排、网络以及存储等的管理负担,使开发者只需要关注应用的业务逻辑。通过Kubernetes开发者可以自定义工作流甚至自动化的任务流。
Kubernetes拥有全面的集群管理能力,主要包括:多级的授权机制、多租户应用、透明的服务注册和发现机制、内置的负载均衡、错误发现和自修复能力、服务升级回滚和自动扩容等。Kubernetes拥有完善的管理工具,主要包括:部署、部署测试、集群的运行和资源状态的监控等。
Borg是Google内部大规模集群管理系统,主要工作是对Google内部服务的调度和管理。Borg的主要目标是将开发者从硬件资源管理中解放出来,将精力集中在业务逻辑上、最大化多数据中心的资源利用。
如下如所示:Borg系统主要由以下组件构成:BorgMaster、BorgLet、Borgcfg和Scheduler。
BorgMaster 整个集群的大脑:负责管理集群的状态、保证集群存储的数据具有高度容错性
Scheduler 负责任务的调度工作:按照应用的特点将它们调度到适当的机器上
BorgLet 负责任务的运行工作
Borgcfg 是Borg系统的命令行交互工具,事实上是通过配置文件向集群系统提交任务
Kubernetes中的Pod、Service、Label以及一个Pod一个IP地址等的设计依托于Borg,因此整体上看,Kubernetes与Borg的架构非常相似。
Kubernetes中提供灵活和松耦合的机制用于服务发现,像大多数分布式集群平台,Kubernetes集群中至少包含一个主节点和多个工作节点。
主节点负责暴露应用程序的API、调度deployments和管理整个集群。每个工作节点都运行着容器运行时,(如Docker或者rkt)通过代理与主节点通信。
工作节点同时运行着其它组件,如:日志、监控、服务发现和其它可选组件。工作节点是Kubernetes集群中真正运行应用的地方。工作节点可以是云服务商提供的虚拟机或者是运行着的服务器。
Pod是一个或多个容器的集合并扮演着Kuberntes集群中最核心的管理单元,Pod同时也充当着容器共享的上下文和资源的逻辑边界。Pod的分组机制弥补了容器化与虚拟化的差异从而实现在Pod中执行多个子进程。在运行时,Pod可以通过创建replica sets实现集群的扩容,同时Replica set保证集群内需要的Pod数量与真正运行的Pod数量的一致。
Replica sets声明需要挂起Pod的数量和监控预定的Pod中有效的数量。单个Pod或者Replica Set可以通过Service向内部或外部用户暴露服务,Service通过筛选满足条件的Pod实现服务发现。Pod通过定义键值对的Label,Service通过Seletor筛选合法的Pod。任何新Pod打上满足Seletor筛选器的Label后将会自动被Service服务发现。这种设计架构提供了灵活、松耦合的服务发现机制。
Kubernetes中的资源对象(如:Pods、Replica setsje和Service)提交到master节点后,Master节点根据Pod的需求和资源的可用性将Pod调度到适当的工作节点上。工作节点从镜像仓库中拉取镜像,然后在本地运行时环境中拉起容器。
etcd是CoreOS开源的、分布式、键值对数据库,它是集群所有组件单一数据源(SSOT)的保障。Master节点查询etcd获取工作节点、Pods和容器状态的各种参数。
Kubernetes主要由以下组件构成:
Apiserver是操作资源的入口并且提供认证、授权、权限控制、API注册和服务发现的机制
Controller Manager负责管理集群的状态,如异常发现、自动扩容和滚动更新等
Scheduler负责资源的调度以及根据预先设定的调度策略将pod调度到合适的节点上
Kubelet负责管理容器的生命周期、数据卷以及网络(CNI)
容器运行时负责镜像的管理
Kube-proxy负责服务发现和集群Service的负载均衡
除了以上核心内容,接下来我们将讨论
编排需要使用简单、功能复杂的容器架构
简要概述容器编排和Kubernetes
容器化环境下的网络
在容器化的架构中,编排层需要实现对容器的部署、扩容和管理。
将容器调度到物理或者虚拟机上,有时还需要维护千级别的容器主机
在容器宕机的时候重新拉起
设置容器网络
对容器进行扩容以及建立和解除资源间的关系
服务发现
开发者可以通过购买业界云服务商提供的IaaP和IaaS服务实现容器编排。根据业务分布式容器管理架构的需求,开发者可以在云服务商那里选择具备适当编排难度的服务。
你知道简单的node.js架构吗?如果你的程序只需要或者与下面相似的架构(很少的进程、一个或者两个数据库、一个负载均衡器、一个客户端和一个宿主机),docker内置的[编排工具就可以满足你的需求。
如果你的技术架构比上图复杂很多,我觉得Amazon ECS或者Kubenrnets更适合你的需求,接下来我们在谈谈K8s。
依托于Kubernets主从的设计架构,系统可以提供高效、水平扩容的分布式系统。网络特性促进大量组件间的高效通信。
下面是Kubernetes中的核心组件:
Pod:Kubernets中最小的管理和部署单位,一个Pod中可以有一个或多个容器。同一Pod中的容器共享IP地址、通过localhost相互通信、共享数据卷
Node:Kubernetes中工作节点,可以使物理机或者虚拟机、为Pods提供运行资源
Service:一组逻辑Pods和它们访问策略的抽象,为一组相同属性的Pods抽象出一个固定IP地址,允许Pod之间以及Pod与Service之间相互通信
ReplicaSet:保证集群在任何时间点上都有指定数量的Pod副本,除非你需要定制滚动更新的策略或者不需要滚动更新,K8s推荐使用Deployment而不是直接操作ReplicaSet
Deployment:提供Pods滚动更新和ReplicaSets的控制器
Namespace:将集群资源
下图通过虚拟的边界描述Kubernetes组件各自的作用范围:、
Kubernetes为区分用户和资源提供许多特性:
Labels: 附在资源对象(如Pod)的键值对,可以使如发布期限、环境和堆栈等具有辨识度的元数据
Selector:Kubernetes中的核心分组原语,标签筛选器可以通过标签分组管理资源对象
Labels、Selector和namespces在Kubernetes中实现灵活动态的配置能力发挥着至关重要的作用。需要明确一点相同namespace下的两个控制器的标签筛选器不能重合,不然会引发冲突。
Kubernetes的设计是以分布式框架的基础,它在构建和管理其它微服务以及分布式框架等方便表现的非常出色。深入探讨Kubernetes提供服务的详细信息不在本书探讨的范围内,下图是展示Kubernete上各组件间相互作用的更高级视图。
当我们研究Kubernetes如何处理容器网路时请记住上图的中的信息流。
容器间的网络问题是容器编排中最严苛的挑战之一,在这一部分我们将会探讨Docker处理容器连通的网络策略,这种策略是如何限制容器编排的规模以及Kubernetes是如何在上实现容器网络连通的基础上实现快速优雅的扩容。
默认情况下Docker容器使用host-private网络。为了实现容器间网络连通,Docker所在的宿主机提供默认名为docker0的虚拟网桥,宿主机并会为网桥上的容器预留足够的空间。容器和网桥是如何连接的?Docker为每个容器分配一个虚拟网络设备(veth),通过网络地址转换(NAT)将虚拟网桥的地址与容器的地址映射到一起。NAT方法是通过修改网络包的IP头信息将一个IP地址映射为其它的IP地址。
这种方案对自动化运维的挑战
首先这种通过网桥实现容器网络的连通需要容器在同一台宿主机或链接在相同的网桥上。这对于容器网络量有限,限制集群数量的情况下是可以满足的,但是对多宿主机的集群就会造成网络故障。另外完全依靠NAT实现网络的连通也会造成性能故障。
Kubernetes的网络方案比Docker默认的网络方案更加高效且更易扩容。为了实现这个目的,Kubernetes的网络实现必须满足以下需求。
所有容器在不使用NAT时可以与其他容器通信
所有子节点可以在不使用NAT时可以与其它容器通信
所有容器自己看到的IP地址与其它节点或者容器看到的IP地址是一样的
当满足这些条件后,在多个团队和开发人员之间协调移植变得更加容易。诸如Flannel、WeaveNet、Calico都可以实现Kubernetes容器网路的连通。
文章翻译自Kubernetes architecture Quick Introduction,行文时略有删减