云原生(三):Kubernetes概述
在前文,我介绍了应用部署方式的更新迭代:
随着容器化部署的盛行,Kubernetes应运而生。
Kubernetes 是什么?
Kubernetes 这个单词是希腊语,它的中文翻译是“舵手”或者“飞行员”。Container 这个英文单词也有另外的一个意思就是“集装箱”。Kubernetes 也就借着这个寓意,希望成为运送集装箱的一个轮船,来帮助我们管理这些集装箱,也就是管理这些容器。
在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。Kubernetes为你提供了管理这些容器的能力。它为你提供了一个可弹性运行分布式系统的框架,满足你的扩展要求、故障转移你的应用、提供部署模式等。
Kubernetes 能力
- 服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。 - 存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、分布式存储和云存储等。 - 自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。 - 自动完成装箱计算
你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。 - 自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。 - 密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。 - 批处理执行
除了服务外,Kubernetes 还可以管理你的批处理和 CI(持续集成)工作负载,如有需要,可以替换失败的容器。 - 水平扩缩
使用简单的命令、用户界面或根据 CPU 使用率自动对你的应用进行扩缩。 - IPv4/IPv6 双栈
为 Pod(容器组)和 Service(服务)分配 IPv4 和 IPv6 地址。 - 为可扩展性设计
在不改变上游源代码的情况下为你的 Kubernetes 集群添加功能。
Kubernetes 核心概念
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的规约。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的 “逻辑主机”,其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。
Volume
Volume 是一种存储抽象,它可以被挂载到容器内部的文件系统中,用于存储数据。
同时它用来声明在 Pod 中的容器可以的访问文件目录。可以把它想象成一个外部存储设备,容器可以访问并使用这个设备来进行数据的读写操作。
Deployment
Deployment 管理一组 Pod 来运行应用程序工作负载,通常不维护状态。
Deployment 提供声明式更新 Pod 和副本集。
在部署中描述所需状态,部署控制器以可控的速率将实际状态更改为所需状态。
例如说:可以定义一个 Deployment,这个 Deployment 里面需要两个 Pod,当一个 Pod 失败的时候,控制器就会监测到,它重新把 Deployment 中的 Pod 数目从一个恢复到两个,通过再去新生成一个 Pod。通过控制器,我们也会帮助完成发布的策略。比如更新部署,回滚部署,动态扩缩容等。
Service
Service 是一种抽象概念,用于为一组 Pod 提供稳定的网络访问。它定义了一组规则,使得其他应用(可以是在 Kubernetes 集群内部,也可以是外部)能够访问这些 Pod。
在我看来,Service 提供给了访问者对于 Pod 组的一个统一访问路径,使得访问者不需要关心到底是哪个 Pod在向他提供服务。
Namespace
Namespace 提供一种机制,将同一集群中划分为逻辑上相互隔离的组,它包括鉴权、资源管理等。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。
Kubernetes 架构
Kubernetes 架构是一个比较典型的二层架构,集群由一个控制平面和一组用于运行容器化应用的工作机器组成, 这些工作机器称作节点(Node)。每个集群至少需要一个工作节点来运行 Pod。
工作节点托管着组成应用负载的 Pod。控制平面管理集群中的工作节点和 Pod。
Control Plane 控制平面
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件。控制平面会包含四个核心组件,以及一些其他的可选组件。
kube-apiserver
kube-apiserver 验证并配置 API 对象的数据, 这些对象包括 pods、services、replicationcontrollers 等。 API 服务器为 REST 操作提供服务,并为集群的共享状态提供前端, 所有其他组件都通过该前端进行交互。
etcd
一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。
kube-scheduler
kube-scheduler 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
kube-controller-manager
kube-controller-manager 用来完成对集群状态的一些管理,通过监控集群的公共状态,并致力于将当前状态转变为期望的状态。
Node 工作节点
kubelet
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpec,确保这些 PodSpec 中描述的容器处于运行状态且健康。
同时,kubelet不会管理不是由Kubernetes创建的容器。
kube-proxy (可选)
kube-proxy是是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service)概念的一部分。它主要是维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果说工作节点(node)使用网络插件为 Service 实现本身的数据包转发, 并提供与 kube-proxy 等效的行为,那么你不需要在集群中的节点上运行 kube-proxy。
容器运行时
这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现
组件间相互通信
以创建Pod为例:
- 用户通过 UI 或者 CLI 提交一个 Pod 部署请求给 Kubernetes API Server。
- API Server 接收到请求后,将相关信息写入其存储系统 etcd。
- Scheduler 通过 API Server 的 watch 或 notification 机制得知有 Pod 需要调度,然后依据自身内存状态进行调度决策。
- 完成调度决策后,Scheduler 向 API Server 报告该 Pod 应被调度到的具体节点。
- API Server 收到报告后,把此次调度结果再次写入 etcd。
- API Server 接着通知相应节点进行 Pod 的实际执行启动。
- 相应节点的 kubelet 收到通知后,会调用 Container runtime 来启动并配置容器及其运行环境,同时调度 Storage Plugin 配置存储以及 network Plugin 配置网络。