目录
一 整体架构和组件基本概念
1.1 组件
1.1.1 master节点
1.1.2 node节点
1.1.3 附加组件
二 资源和对象
2.1 资源分类
2.2 元数据资源
Horizontal Pod Autoscaler(HPA)
PodTemplate
LimitRange
2.3 集群资源
namespace
Node
ClusterRole
ClusterRoleBinding
2.4 命名空间资源
2.4.1 pod
2.4.1.1 副本
2.4.1.2 Label
2.4.1.3 控制器controller
适用于无状态服务
1⃣️ Replication Controller (已废弃,ReplicaSet替代)
2⃣️ ReplicaSet
3⃣️ Deployment
适用于有状态服务
主要特点
组成
注意事项
DaemonSet
任务/定时任务
job
CronJob
2.4.2 服务发现
service
ingress
endpoints
2.4.3 存储
2.4.4 特殊类型配置
2.4.5 其他
一 整体架构和组件基本概念
基本介绍
Kubernetes(通常写成“k8s”)是Google开源的容器集群管理系统。其设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群,Kubernetes不仅仅支持Docker,其他容器技术:CRI-O、containerd
功能特性:
自动化容器部署与复制 随时扩展或收缩容器规模 组织容器成组,提供容器间的负载均衡 快速更新及回滚容器版本 提供弹性伸缩,如果某个容器失效就进行替换
1.1 组件
用户通过kubectl或者dashboard访问api-server进行管理控制
整体分为master和node,master也包含node的功能,但是master多了api-server、manager、scheduler和etcd
1.1.1 master节点
Master 节点也称为控制节点,每个 k8s 集群都有一个 Master 节点负责整个集群的管理控制
-
API Server:提供了 HTTP Rest 接口的服务进程,所有资源对象的增、删、改、查等操作的唯一入口;
-
Controller Manager:k8s 集群所有资源对象的自动化控制中心;
-
cloud-controller-manager:第三方云平台提供的控制器的api对接管理功能
-
Scheduler:k8s 集群所有资源对象自动化调度控制中心;
-
ETCD:k8s 集群注册服务发现中心,可以保存 k8s 集群中所有资源对象的数据。键值类型存储的分布式数据库。老版本:基于内存,新版本:持久化存储
1.1.2 node节点
Node 节点的作用是承接 Master 分配的工作负载。Master会根据集群中每个Node上的可用资源情况,自动调度Pod的部署
-
kubelet: Master在每个 Node 上的代理,负责Master和Node之间的通信,并管理Pod和容器.
-
kube-proxy: 实现了k8s中的服务发现和反向代理功能.在反向代理方面,kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与Service对应的一组后端Pod中.在服务发现方面,kube-proxy使用etcd的watch机制,监控集群中Service和Endpoint对象数据的动态变化,并且维护一个Service到Endpoint的应设管理,从而保证了后端Pod的IP地址发生变化时不会对访问者造成影响.
-
container runtime:Docker或其他容器,负责从镜像仓库拉取容器镜像、解压缩容器及运行应用程序.
1.1.3 附加组件
-
kube-dns 负责为整个集群提供 DNS 服务
-
Ingress Controller 为服务提供外网入口
-
Prometheus 提供资源监控
-
Dashboard 提供 GUI页面
-
Federation 提供跨可用区的集群
-
Fluentd-elasticsearch 提供集群日志采集、存储与查询
二 资源和对象
Kubernetes 中的所有内容都被抽象为“资源”,如 Pod、Service、Node 等都是资源。“对象”就是“资源”的实例,是持久化的实体。如某个具体的 Pod、某个具体的 Node。Kubernetes 使用这些实体去表示整个集群的状态。
对象的创建、删除、修改都是通过 “Kubernetes API”,也就是 “Api Server” 组件提供的 API 接口,这些是 RESTful 风格的 Api,与 k8s 的“万物皆对象”理念相符。命令行工具 “kubectl”,实际上也是调用 kubernetes api。
K8s 中的资源类别有很多种,kubectl 可以通过配置文件来创建这些 “对象”,配置文件更像是描述对象“属性”的文件,配置文件格式可以是 “JSON” 或 “YAML”,常用 “YAML”。
2.1 资源分类
资源分为元数据、集群、命名空间级别
-
元数据级别资源
-
元数据级别作用域最大,所有资源都可使用元空间级别
-
是对资源的元数据描述
-
-
集群级别资源
作用在集群上,集群下所有资源可访问使用
-
命名空间级别资源
作用在命名空间上,在该命名空间范围内的资源可访问使用
2.2 元数据资源
主要针对pod的描述
Horizontal Pod Autoscaler(HPA)
Pod 自动扩容:可以根据 CPU 使用率或自定义指标(metrics)自动对 Pod 进行扩/缩容。
-
控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况
-
支持三种metrics类型
-
预定义metrics(比如Pod的CPU)以利用率的方式计算
-
自定义的Pod metrics,以原始值(raw value)的方式计算
-
自定义的object metrics
-
-
支持两种metrics查询方式:Heapster和自定义的REST API
-
支持多metrics
PodTemplate
Pod Template 是关于 Pod 模板的定义
但是被包含在其他的 Kubernetes 对象中(例如 Deployment、StatefulSet、DaemonSet 等控制器)。控制器通过 Pod Template 信息来创建 Pod。
LimitRange
对pod的资源使用进行限制
比如java应用的初始内存2G,最大内存4G
可以对集群内 Request 和 Limits 的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的 Pod 的资源使用限制。
2.3 集群资源
namespace
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群,这些虚拟集群被称为命名空间。
作用是用于实现多团队/环境的资源隔离。
命名空间 namespace 是 k8s 集群级别的资源,可以给不同的用户、租户、环境或项目创建对应的命名空间。
默认 namespace:
-
kube-system 主要用于运行系统级资源,存放 k8s 自身的组件
-
kube-public 此命名空间是自动创建的,并且可供所有用户(包括未经过身份验证的用户)读取。此命名空间主要用于集群使用,关联的一些资源在集群中是可见的并且可以公开读取。此命名空间的公共方面知识一个约定,但不是非要这么要求。
-
default 未指定名称空间的资源就是 default,即你在创建pod 时如果没有指定 namespace,则会默认使用 default
Node
一般一台物理机部署一个node
不像其他的资源(如 Pod 和 Namespace),Node 本质上不是Kubernetes 来创建的,Kubernetes 只是管理 Node 上的资源。虽然可以通过 Manifest 创建一个Node对象(如下 json 所示),但 Kubernetes 也只是去检查是否真的是有这么一个 Node,如果检查失败,也不会往上调度 Pod。
ClusterRole
ClusterRole 是一组权限的集合,但与 Role 不同的是,ClusterRole 可以在包括所有 Namespace 和集群级别的资源或非资源类型进行鉴权。
ClusterRoleBinding
ClusterRoleBinding:将 Subject 绑定到 ClusterRole,ClusterRoleBinding 将使规则在所有命名空间中生效。
2.4 命名空间资源
2.4.1 pod
Pod(容器组)是 Kubernetes 中最小的可部署单元
pod就像豌豆荚一样,其中包含一组(一个或多个)容器,这些容器共享存储、网络、以及怎样运行这些容器的声明
一个 Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络 IP 地址、以及一些确定容器该如何运行的选项。Pod 容器组代表了 Kubernetes 中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。
Docker 是 Kubernetes Pod 中使用最广泛的容器引擎;Kubernetes Pod 同时也支持其他类型的容器引擎。
Kubernetes 集群中的 Pod 存在如下两种使用途径:
-
一个 Pod 中只运行一个容器。"one-container-per-pod" 是 Kubernetes 中最常见的使用方式。此时,您可以认为 Pod 容器组是该容器的 wrapper,Kubernetes 通过 Pod 管理容器,而不是直接管理容器。
-
一个 Pod 中运行多个需要互相协作的容器。您可以将多个紧密耦合、共享资源且始终在一起运行的容器编排在同一个 Pod 中,可能的情况有:
2.4.1.1 副本
一个 Pod 可以被复制成多份,每一份可被称之为一个“副本”,这些“副本”除了一些描述性的信息(Pod 的名字、uid 等)不一样以外,其它信息都是一样的,譬如 Pod 内部的容器、容器数量、容器里面运行的应用等的这些信息都是一样的,这些副本提供同样的功能。
Pod 的*“控制器”*通常包含一个名为 “replicas” 的属性。“replicas”属性则指定了特定 Pod 的副本的数量,当当前集群中该 Pod 的数量与该属性指定的值不一致时,k8s 会采取一些策略去使得当前状态满足配置的要求。
2.4.1.2 Label
Label是附着到object上(例如Pod)的键值对。可以在创建object的时候指定,也可以在object创建后随时指定。Labels的值对系统本身并没有什么含义,只是对用户才有意义。
一个Label是一个key=value的键值对,其中key与value由用户自己指定
Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去,Label通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除
我们可以通过指定的资源对象捆绑一个或多个不同的Label来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等管理工作。例如:部署不同版本的应用到不同的环境中;或者监控和分析应用(日志记录、监控、告警)等。
一些常用label示例如下所示:
版本标签:"release" : "stable" , "release" : "canary"...
环境标签:"environment" : "dev" , "environment" : "production"
架构标签:"tier" : "frontend" , "tier" : "backend" , "tier" : "middleware"
分区标签:"partition" : "customerA" , "partition" : "customerB"...
质量管控标签:"track" : "daily" , "track" : "weekly"
Label相当于我们熟悉的“标签”,给某个资源对象定义一个Label,就相当于给它打了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制
2.4.1.3 控制器controller
在 Kubernetes 中,用于管理和运行Pod的对象
在 Kubernetes 中,控制器通过监控集群的公共状态,并致力于将当前状态转变为期望的状态
需要原因:
当 Pod 被创建出来,Pod 会被调度到集群中的节点上运行,Pod 会在该节点上一直保持运行状态,直到进程终止、Pod 对象被删除、Pod 因节点资源不足而被驱逐或者节点失效为止。Pod 并不会自愈,当节点失效,或者调度 Pod 的这一操作失败了,Pod 就该被删除。如此,单单用 Pod 来部署应用,是不稳定不安全的。
Kubernetes 使用更高级的资源对象 *“控制器”* 来实现对Pod的管理。控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。 例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。
常用controller:
-
deployment
-
部署无状态应用
-
部署无状态应用: 认为pod 都一样,没有顺序要求, 不用考虑在哪个node 运行,随意进行扩展和伸缩
-
管理Pod和 ReplicaSet
-
部署、滚动升级等
-
典型的像web服务、分布式服务等
-
-
StatefulSet
-
部署有状态应用
-
有状态应用,每个pod 都独立运行,保持pod 启动顺序和唯一性; 有唯一的网络标识符,持久存储; 有序,比如mysql 主从; 主机名称固定。 而且其扩容以及升级等操作也是按顺序进行的操作。
-
-
DaemonSet
-
部署守护进程
-
DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。 新加入的node 也同样运行在一个pod 里面。
-
-
job
-
一次性任务
-
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
-
-
Cronjob
-
周期性定时任务
-
适用于无状态服务
1⃣️ Replication Controller (已废弃,ReplicaSet替代)
Replication Controller 简称 RC,RC 是 Kubernetes 系统中的核心概念之一
RC 可以保证在任意时间运行 Pod 的副本数量,能够保证 Pod 总是可用的
如果实际 Pod 数量比指定的多那就结束掉多余的
如果实际数量比指定的少就新启动一些Pod
当 Pod 失败、被删除或者挂掉后,RC 都会去自动创建新的 Pod 来保证副本数量
所以即使只有一个 Pod,我们也应该使用 RC 来管理我们的 Pod。
可以说,通过 ReplicationController,Kubernetes 实现了 Pod 的高可用性。
2⃣️ ReplicaSet
RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收(已经成为过去时),在 v1.11 版本废弃。
Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有本质的不同,只是名字不一样,并且 RS 支持集合式的 selector。
3⃣️ Deployment
Deployment 为 Pod 和 Replica Set 提供声明式更新。
你只需要在 Deployment 中描述你想要的目标状态是什么,Deployment controller 就会帮你将 Pod 和 Replica Set 的实际状态改变到你的目标状态。你可以定义一个全新的 Deployment,也可以创建一个新的替换旧的 Deployment。
适用于有状态服务
StatefulSet
StatefulSet中每个 Pod 的 DNS 格式为 statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
-
serviceName 为 Headless Service 的名字
-
0..N-1 为 Pod 所在的序号,从 0 开始到 N-1
-
statefulSetName 为 StatefulSet 的名字
-
namespace 为服务所在的 namespace,Headless Servic 和 StatefulSet 必须在相同的 namespace
-
.cluster.local 为 Cluster Domain
主要特点
-
稳定的持久化存储
Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
-
稳定的网络标志
Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现
-
有序部署,有序扩展
Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从 0到 N-1,在下一个Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现
-
有序收缩,有序删除
即从 N-1 到 0
组成
-
Headless Service
用于定义网络标志(DNS domain)
Domain Name Server:域名服务
将域名与 ip 绑定映射关系
服务名 => 访问路径(域名) => ip
-
volumeClaimTemplate
用于创建 PersistentVolumes
注意事项
-
kubernetes v1.5 版本以上才支持
-
所有Pod的Volume必须使用PersistentVolume或者是管理员事先创建好
-
为了保证数据安全,删除StatefulSet时不会删除Volume
-
StatefulSet 需要一个 Headless Service 来定义 DNS domain,需要在 StatefulSet 之前创建好
DaemonSet
部署守护进程
DaemonSet 保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:
-
日志收集,比如 fluentd,logstash 等
-
系统监控,比如 Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond 等
-
系统程序,比如 kube-proxy, kube-dns, glusterd, ceph 等
任务/定时任务
job
一次性任务,运行完成后Pod销毁,不再重新启动新容器。
CronJob
CronJob 是在 Job 基础上加上了定时功能。
2.4.2 服务发现
解决K8S集群内应用间网络访问(东西流量)和k8s集群与外网网络访问(南北流量)
service
“Service” 简写 “svc”。Pod 不能直接提供给外网访问,而是应该使用 service。Service 就是把 Pod 暴露出来提供服务,Service 才是真正的“服务”,它的中文名就叫“服务”。
可以说 Service 是一个应用服务的抽象,定义了 Pod 逻辑集合和访问这个 Pod 集合的策略。Service 代理 Pod 集合,对外表现为一个访问入口,访问该入口的请求将经过负载均衡,转发到后端 Pod 中的容器。
ingress
Ingress 可以提供外网访问 Service 的能力。可以把某个请求地址映射、路由到特定的 service。
ingress 需要配合 ingress controller 一起使用才能发挥作用,ingress 只是相当于路由规则的集合而已,真正实现路由功能的,是 Ingress Controller,ingress controller 和其它 k8s 组件一样,也是在 Pod 中运行。
endpoints
为Service管理后端Pod,当后端Pod被创建或销毁时,endpoints列表会更新Pod对应的IP地址,以便Service访问请求能够确保被响应。
2.4.3 存储
valume
数据卷,共享 Pod 中容器使用的数据。用来放持久化的数据,比如数据库数据。
CSI
Container Storage Interface 是由来自 Kubernetes、Mesos、Docker 等社区成员联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序。
CSI 规范定义了存储提供商实现 CSI 兼容的 Volume Plugin 的最小操作集和部署建议。CSI 规范的主要焦点是声明 Volume Plugin 必须实现的接口。
2.4.4 特殊类型配置
configMap
用来放配置,与 Secret 是类似的,只是 ConfigMap 放的是明文的数据,Secret 是密文存放。
Secret
Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。
Secret 有三种类型:
Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;
kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。
downwardAPI
将pod信息共享到容器内,让容器可以直接读取到pod信息
downwardAPI 这个模式和其他模式不一样的地方在于它不是为了存放容器的数据也不是用来进行容器和宿主机的数据交换的,而是让 pod 里的容器能够直接获取到这个 pod 对象本身的一些信息。
downwardAPI 提供了两种方式用于将 pod 的信息注入到容器内部:
环境变量:用于单个变量,可以将 pod 信息和容器信息直接注入容器内部
volume 挂载:将 pod 信息生成为文件,直接挂载到容器内部中去
2.4.5 其他
role
Role 是一组权限的集合,例如 Role 可以包含列出 Pod 权限及列出 Deployment 权限,Role 用于给某个 Namespace 中的资源进行鉴权。
RoleBinding
RoleBinding :将 Subject 绑定到 Role,RoleBinding 使规则在命名空间内生效。