可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。系统部署衍变过程:传统部署 → 虚拟化部署 → 容器化部署。
容器类似于VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。因此,容器被认为是轻量级的。
优点
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
- 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度。
1. 能力
- 服务发现和负载均衡
使用DNS名称或自己的IP地址公开容器,如果进入容器的流量很大,K8s可以负载均衡并分配网络流量,从而使部署稳定。
- 存储编排
自动挂载选择的存储系统,例如本地存储、公共云提供商等。
- 自动部署和回滚
使用K8s描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为期望状态。例如,使用自动化K8s来部署创建新容器,删除现有容器并将它们的所有资源用于新容器。
- 自动完成装箱计算
指定每个容器所需CPU和内存(RAM)。当容器指定了资源请求时,K8s可以做出更好的决策来管理容器的资源。
- 自我修复
重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
- 密钥与配置管理
存储和管理敏感信息,例如密码、OAuth令牌和ssh密钥。在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
2. 非定义
由于K8s在容器级别而不是在硬件级别运行,它提供PaaS产品共有的一些普遍适用的功能。但他不是单体系统,默认解决方案都是可选和可插拔的。 K8s提供了构建开发人员平台的基础,但是在重要的地方保留了用户的选择和灵活性。
- 不限制支持的应用程序类型
K8s旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。如果应用程序可以在容器中运行,那么它应该可以在K8s上很好地运行。
- 不部署源代码,也不构建应用程序
持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。
- 不提供应用程序级别的服务作为内置服务
例如:消息中间件、数据处理框架(Spark...)、数据库(MySQL...)、缓存(Redis...)、集群存储系统(CEPH...)。这样的组件可以在K8s上运行,并且/或者可以由运行在K8s上的应用程序通过可移植机制(服务代理)来访问。
- 不要求日志记录、监视或警报解决方案
提供了一些集成作为概念证明,并提供了收集和导出指标的机制。
- 不提供或不要求配置语言/系统
例如 jsonnet提供了声明性 API, 该声明性 API 可以由任意形式的声明性规范所构成。
- 不提供也不采用任何全面的机器配置、维护、管理或自我修复系统
- 不仅仅是一个编排系统,实际上它消除了编排的需要
编排的技术定义是执行已定义的工作流程:首先执行 A,然后执行 B,再执行 C。 相比之下,Kubernetes 包含一组独立的、可组合的控制过程, 这些过程连续地将当前状态驱动到所提供的所需状态。 如何从 A 到 C 的方式无关紧要,也不需要集中控制,这使得系统更易于使用 且功能更强大、系统更健壮、更为弹性和可扩展。
3. 组件
K8s集群由一组被称作节点的机器组成,并且至少有一个工作节点。这些节点上运行K8s管理的容器化应用。
工作节点托管作为应用负载的组件的Pod。控制平面管理集群中的工作节点和Pod。为集群提供故障转移和高可用性,这些控制平面一般跨多主机运行,集群跨多个节点运行。
3.1. 控制平面
控制平面的组件(Control Plane Components)对集群做出全局决策(比如调度),以及检测和响应集群事件。例如:当不满足部署的replicas 字段时,启动新的pod。控制平面组件可以在集群中的任何节点上运行。通常会设置脚本在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。
3.1.1. api
API服务器是K8s控制面的前端。Kubernetes API服务器的主要实现是kube-apiserver,kube-apiserver设计上考虑了水平伸缩,可部署多个实例,并在这些实例之间平衡流量。
3.1.2. etcd
etcd是兼具一致性和高可用性的键值数据库,可以作为保存K8s所有集群数据的后台数据库。
3.1.3. scheduler
负责监视新创建的、未指定运行节点的Pods,选择节点让Pod在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
3.1.4. controller-manager
运行控制器进程的控制平面组件。从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
- 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成。
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌。
3.1.5. 云控制器管理器
云控制器管理器(cloud-controller-manager)是指嵌入特定云的控制逻辑的控制平面组件。 可将集群连接到云提供商的API 之上,并将与该云平台交互的组件同与你的集群交互的组件分离开来。cloud-controller-manager仅运行特定于云平台的控制回路。 如果在自己的环境中运行K8s,或者在本地计算机中运行学习环境, 所部署的环境中不需要云控制器管理器。
与kube-controller-manager类似,cloud-controller-manager将若干逻辑上独立的控制回路组合到同一个可执行文件中,提供同一进程的方式运行。 对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。云平台驱动的依赖:
- 节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除。
- 路由控制器(Route Controller): 用于在底层云基础架构中设置路由。
- 服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器。
3.2. 节点
节点(Node)组件在每个节点上运行,维护运行的Pod并提供K8s运行环境。
3.2.1. kubelet
一个在集群中每个节点上运行的代理。 保证容器(containers)都运行在Pod中。kubelet接收一组通过各类机制提供给它的PodSpecs,确保这些 PodSpecs中描述的容器处于运行状态且健康。kubelet不会管理不是由K8s创建的容器。
3.2.2. kube-proxy
集群中每个节点上运行的网络代理, 实现K8s服务(Service)概念的一部分。kube-proxy维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。如果操作系统提供了数据包过滤层并可用的话,kube-proxy 会通过它来实现网络规则。否则kube-proxy仅转发流量本身。
4. 对象
K8s对象是持久化的实体,使用这些实体去表示整个集群的状态。几乎每个对象包含两个嵌套的对象字段,它们负责管理对象的配置:spec(规约)和status(状态)。对于具有spec的对象,必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State) 。
status描述对象的当前状态(Current State),由K8s系统和组件设置并更新。在任何时刻,Kubernetes控制平面都一直积极地管理着对象的实际状态,以使之与期望状态相匹配。例如,K8s中的Deployment对象能够表示运行在集群中的应用。当创建Deployment时,可能需要设置Deployment的spec,以指定该应用需要有3个副本运行。K8s系统读取Deployment规约,并启动我们所期望的应用的3个实例 —— 更新状态以与规约相匹配。如果这些实例中有的失败了(一种状态变更),K8s系统通过执行修正操作来响应规约和状态间的不一致,在这里意味着它会启动一个新的实例来替换。
4.1. Yaml
Kubernetes Deployment必需字段和对象规约示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
必须字段
- apiVersion - 创建该对象所使用的 Kubernetes API 的版本
- kind - 想要创建的对象的类别
- metadata - 帮助唯一性标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
使用类似于上面的 .yaml 文件来创建 Deployment的一种方式是使用 kubectl 命令行接口(CLI)中的 kubectl apply 命令, 将.yaml 文件作为参数示例:
kubectl apply -f k8s.io/examples/ap… --record
deployment.apps/nginx-deployment created