Kubernetes
简介
Kubernetes 是谷歌开源的容器集群管理系统,是Google多年大规模容器管理技术borg的开源版本,主要功能包括:
- 基于容器的应用部署、维护和滚动升级
- 负载均衡和服务发现
- 扩机器和跨地区的集群调度
- 自动伸缩
- 无状态服务和有状态服务
- 广泛的Volume支持
- 插件机制保证扩展性
Kubernetes 发展非常迅速,已经成为容器编排领域的领导者。
Kubernetes 是什么
Kubernetes 提供了很多的功能,它可以简化应用程序的工作流,加快开发速度。通常,一个成功的应用编排系统需要有较强的自动化能力,这也是为什么 Kubernetes 被设计作为构建组件和工具的生态系统平台,以便更轻松地部署、扩展和管理应用程序。
用户可以使用 Label 以自己的方式组织管理资源,还可以使用 Annotation 来自定义资源的描述信息,比如为管理工具提供状态检查等。
此外,Kubernetes 控制器也是构建在跟开发人员和用户使用的相同的 API 之上。用户可以编写自己的控制器和调度器,也可以通过各种插件机制扩展系统的功能。这种设计使得用户可以方便地在 Kubernetes 之上构建各种应用系统。
Kubernetes不是什么
Kubernetes不是一个传统意义上,包罗万象的Paas(平台即服务)系统。它给用户预留了选择的自由:
- 不限制支持的应用程序类型,它不插手应用程序框架,也不限制支持的语言,Kubernetes旨在支持极其多样化的工作负载,包括无状态、有状态和数据处理工作负载。只要应用可以在容器中运行的,它就可以在Kubernetes上运行。
- 不提供内置的中间件(如消息中间件)、数据处理框架(如Spark)、数据库(如mysql)或者集群存储系统(如Ceph)等。这些应用直接运行在Kubernetes之上。
- 不提供点击即部署的服务市场。
- 不直接部署代码,也不回构建用户的应用程序,但用户可以在Kubernetes之上构建需要的持续集成(CI)工作流。
- 允许用户选择自己的日志、监控和告警系统。
- 不提供应用程序配置语言或系统 (如 jsonnet)。
- 不提供机器配置、维护、管理或自愈系统。
另外,已经有很多 PaaS 系统运行在 Kubernetes 之上,如 Openshift, Deis 和 Eldarion 等。 你也可以构建自己的 PaaS 系统,或者只使用 Kubernetes 管理你的容器应用。
当然了,Kubernetes 不仅仅是一个 “编排系统”,它消除了编排的需要。Kubernetes 通过声明式的 API 和一系列独立、可组合的控制器保证了应用总是在期望的状态,而用户并不需要关心中间状态是如何转换的。这使得整个系统更容易使用,而且更强大、更可靠、更具弹性和可扩展性。
基础组件
核心组件
Kubernetes 主要由以下几个核心组件
组成:
- etcd:保存了整个集群的状态;
- apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
- controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
- kubelet:负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
- Container runtime:负责镜像管理以及 Pod 和容器的真正运行(CRI);
- kube-proxy:负责为 Service 提供 cluster 内部的服务发现和负载均衡
组件详情介绍
Etcd
Etcd是CoreOS基于Raft开发的分布式key-value存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。
Etcd主要功能:
- 基本的key-value存储
- 监听机制
- key的过期及续约机制,用于监控和服务发现
- 原子CAS和CAD,用于分布式锁和leader选举
kube-apiserver
kube-apiserver 是 Kubernetes 最重要的核心组件之一,主要提供以下的功能:
- 提供集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更等
- 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)
Kube-controller-manager
Controller Manager由kube-controller-manager和cloud-controller-manager组成,是Kubernetes的大脑,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态。
kube-controller-manager由一系列的控制器组成
- Replication Controller
- Node Controller
- CronJob Controller
- Daemon Controller
- Deployment Controller
- Endpoint Controller
- Garbage Collector
- Namespace Controller
- Job Controller
- Pod AutoScaler
- RelicaSet
- Service Controller
- ServiceAccount Controller
- StatefulSet Controller
- Volume Controller
- Resource quota Controller
cloud-controller-manager
在Kubernetes启用Cloud Provider的时候才需要,用来配合云服务提供商的控制,也包括一系列的控制器,如:
- Node Controller
- Route Controller
- Service Controller
kube-scheduler
kube-scheduler 负责分配调度 Pod 到集群内的节点上,它监听 kube-apiserver,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配节点(更新 Pod的 NodeName 字段)。
调度器需要充分考虑诸多的因素:
- 公平调度
- 资源高效利用
- QoS
- affinity 和 anti-affinity
- 数据本地化(data locality)
- 内部负载干扰(inter-workload interference)
- deadlines
Kubelet
每个节点上都运行一个 kubelet 服务进程,默认监听 10250 端口,接收并执行 master 发来的指令,管理 Pod 及 Pod 中的容器。每个 kubelet 进程会在 API Server 上注册节点自身信息,定期向 master 节点汇报节点的资源使用情况,并通过 cAdvisor 监控节点和容器的资源。
Container runtime
容器运行时(Container Runtime)是 Kubernetes 最重要的组件之一,负责真正管理镜像和容器的生命周期。Kubelet 通过 Container Runtime Interface (CRI) 与容器运行时交互,以管理镜像和容器。
kube-proxy
每台机器上都运行一个 kube-proxy 服务,它监听 API server 中 service 和 endpoint 的变化情况,并通过 iptables 等来为服务配置负载均衡(仅支持 TCP 和 UDP)。
kube-proxy 可以直接运行在物理机上,也可以以 static pod 或者 daemonset 的方式运行。
kube-proxy 当前支持一下几种实现:
- userspace:最早的负载均衡方案,它在用户空间监听一个端口,所有服务通过 iptables 转发到这个端口,然后在其内部负载均衡到实际的 Pod。该方式最主要的问题是效率低,有明显的性能瓶颈。
- iptables:目前推荐的方案,完全以 iptables 规则的方式来实现 service 负载均衡。该方式最主要的问题是在服务多的时候产生太多的 iptables 规则,非增量式更新会引入一定的时延,大规模情况下有明显的性能问题
- ipvs:为解决 iptables 模式的性能问题,v1.8 新增了 ipvs 模式,采用增量式更新,并可以保证 service 更新期间连接保持不断开。
- winuserspace:同 userspace,但仅工作在 windows 上。
Kubernetes架构
K8s设置由几个部分组成,其中一些是可选的,一些是整个系统运行所必需的。下面是k8s的全局架构图
Kubernetes有两个不同的部分构成,一个是Master,一个是Node。Master负责调度资源和为客户端提供API,客户端可以是UI界面或者CLI工具,在Kubernetes中CLI工具通常为kubectl。 Kubernetes Master接受使用YAML定义的配置文件,根据配置文件中相关信息将容器分配到其中一个Node上。另外,镜像库在Kubernetes中也起到一个很重要的角色,Kubernetes需要从镜像库中拉取镜像基于这个镜像的容器才能成功启动。常用的镜像库有dockerhub、阿里云镜像库等。下面图片为Master的架构图:
Master有三个组件:API Server、Scheduler、Controller。API Server提供了友好易用的API供外部调用,同时有很多强大的工具使得API调用更加简单,如kubectl封装了大量API调用,使得部署、配置更加简单。Kubernetes-dashboard可以让用户在界面上操作Kubernetes,而无需手动输入各个API的调用地址参数等信息。
当API Server收到部署请求后,Scheduler会根据所需的资源,判断各节点的资源占用情况分配合适的Node给新的容器。判断依据包括内存、CPU、磁盘等。
Controller负责整个集群的整体协调和健康,保证每个组件以正确的方式运行。
在图的最下边是ETCD数据库。如前文所述ETCD是分布式存储数据库,其作为Kubernetes的中央数据库,存储了集群的状态,组件可以通过查询ETCD了解集群的状态。
Kubernetes Master分配容器到Node执行,Node将会承受压力,通常情况下新容器不会运行在Master上。或者说Master是不可调度的,但是你也可以选择把Master同时也作为Node,但是这并不是地道的用法。下面的为Node的架构图:
Kube-proxy在Node中管理网络,其左右至关重要。Kube-proxy通过管理iptables等方式使得pod到pod之间,和pod到node之间网络能够互通。实质上在跨主机的pod之间网络也能够互通。
Kubelet负责向api server报告信息,并把健康状态、指标和节点状态信息存入Etcd中。
Supervisord保证Docker和kubelet一直在运行中,supervisord并不是必须组件,可以使用其他类似组件替换。
Pod是可以在Kubernetes中创建和管理的最小可部署计算单元。一个POD中可以包含多个容器,但Kubernetes仅管理pod。如果多个容器运行在一个POD中,就相当于这些容器运行在同一台主机中,需要注意端口占用问题。