服务的分类
有状态服务:会对本地环境产生依赖,例如需要把数据存储到本地磁盘,如mysql、redis;
无状态服务:不会对本地环境产生任何依赖,例如不会存储数据到本地磁盘,如nginx、apache;
资源和对象
kubernetes中的所有内容都被抽象为“资源”,如Pod、Service、Node等都是资源。“对象”就是“资源”的实例,是持久化的实体。如某个具体的Pod、某个具体的Node。Kubernetes使用这些实体去表示整个集群的状态。
对象的创建、删除、修改都是通过“kubernetes api”,也就是“api server”组件提供的api接口,这些是restful风格的api,与k8s“万物皆对象”的理念相符。命令行工具“kubectl”,实际上也是调用kubernetes api。
k8s中的资源类别有很多种,kubectl可以通过配置文件来创建这些“对象”,配置文件更像是描述对象“属性”的文件,配置文件格式可以是“json”或“yaml”,常用“yaml”。
对象的规约和状态
规约(spec)是必需的,它描述了对象的期望状态(desired state),即希望对象所具有的特征。当创建kubernetes对象时,必需提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。
状态表示了对象的实际状态,该属性由k8s自己维护,k8s会通过一系列的控制器对对应对象进行管理,让对象尽可能的让实际状态与期望状态重合。
资源的分类
资源一共分为命名空间级资源、集群级资源、元数据型资源。
命名空间级别的资源,如果不同的资源放在不同的命名空间下,他们就相互隔离。比如,有一个包租婆,他有一栋楼,张三和李四各租了其中的一间房子,那么资源是由包租婆统一分配的,但是张三和李四相互之间是隔离的。那么在张三房间中创建的pod,李四是不能访问的。命名空间下的资源类型有:工作负载型资源workload(Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob)、服务发现及负载均衡性资源ServiceDiscovery LoadBalance(Service、Ingress)、配置与存储型资源(Volume、CSI)、特殊类型的存储卷(ConfigMap、Secret、DownwardAPI)。
工作负载型资源(workLoad)
Pod(容器组):是kubernetes中最小的可部署单元。一个pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络IP地址、以及一些确定容器该如何运行的选项。pod容器组代表了kubernetes中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。docker是kubernetes pod中使用最广泛的容器引擎;kubernetes pod同时也支持其他类型的容器引擎。kubernetes集群中的pod存在两种使用途径:
一个pod中只运行一个容器。“one-container-per-pod”是kubernetes中最常见的使用方式。此时,可以认为pod容器组是该容器的wrapper,kubernetes通过pod管理容器,而不是直接管理容器。
一个pod中运行多个需要相互协作的容器,可以将多个紧密耦合、共享资源且始终在一起运行的容器编排在同一个pod。
replicas(副本):一个pod可以被复制成多份,每一份可以被称之为一个“副本”,这些“副本”除了一些描述性的信息(pod的名字、uid等)不一样之外,其他信息都是一样的,譬如pod内部的容器、容器数量、容器里面运行的应用等这些信息都是一样的,这些副本提供同样的功能。pod的“控制器”通常包含一个名为“replicas”的属性。“replicas”属性则指定了特定的pod的副本的数量,当当前集群中该pod的数量与该属性指定的值不一致时,k8s会采取一些策略去使得当前状态满足配置的要求。
ReplicationController(适用于无状态服务):RC
ReplicaSet(适用于无状态服务):RS,调度器、控制器,通过标签去控制pod的创建、副本数量
Deployment(适用于无状态服务):控制器,通过控制RS的创建去创建pod
StatefulSet(适用于有状态服务):为有状态服务所建立的管理器
DaemonSet(守护进程):可以在每一个节点都运行一个pod的组件
Job(任务/定时任务):工作、任务
CronJob(任务/定时任务):轮询工作、轮询任务,为批处理而生的
服务发现及负载均衡型资源(ServiceDiscory LoadBalance)
Service:简称svc,服务,将服务暴露出去
Ingress:将服务暴露出去
配置与存储型资源
Volume(存储卷):给pod提供持久化的能力
CSI:容器存储接口,可以扩展各种各样的第三方存储卷
特殊类型的存储卷
ConfigMap:当配置中心来使用的资源类型,一般用来存储配置文件达到热更新的状态
Secret:保存敏感数据,加密方案存储数据,一般用来保存密码文件、密钥等等
DownwardAPI:把外部环境中的信息输出给容器,类似于CSI
集群级别的资源,范围比命名空间要大,一个集群下可能会有多个命名空间。集群管理着命名空间资源。同一个集群下的各个命名空间均可见,在定义的时候不需要指定命名空间。集群下的资源类型有:名称空间Namespace、节点Node、角色Role、ClusterRole、RoleBinding、ClusterRoleBinding。
Namespace:名称空间就是集群级别资源的一种。
node:不像其他的资源(如pod和namespace),Node本质上不是kubernetes来创建的,kubernetes只是管理node上的资源。虽然可以通过manifest创建一个node对象,单kubernetes也只是去检查是否真的是有这么一个node,如果检查失败,也不会往上调度pod。
ClusterRole:集群角色,作用在集群下的,类似于学校的校长。如果给集群赋予了某一个集群角色,那么所有的名字空间都具有这个角色的权限。
Role:角色,他是作用在名字空间下的。类似于一个班的班长。
ClusterRoleBinding:集群角色绑定。比如学校和教室之间的关系可以理解为集群和名字空间的关系,校长就是集群角色。那么一个人要升职为校长,那么需要有委任书,这个委任书就是集群角色绑定,只要有这个委任书,这个人就是校长,将集群和角色绑定在一起了。
相对应的还有RoleBinding:角色绑定,作用在名字空间下。
元数据可以理解为一个模板,不是直接作用在资源或者对象上的,而是管控中间的变量,可以通过指标进行操作。元数据资源类型有:HPA、PodTemplate、LimitRange。
HPA(Horizontal Pod Autoscaler):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模板,是关于pod的定义,但是被包含在其他的kubernetes对象中(例如deployment、statefulSet、Daemonset等控制器中),控制器通过pod template信息来创建pod;
LimitRange:对集群内request和limits的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的pod的资源使用限制;
Pause容器
pause容器是一个很特殊的容器,又叫做infra容器,是每个pod都会自动创建的容器,不属于用户自定义的容器。
一个pod中的容器共享存储、网络资源就是通过pause容器来实现的。实际上K8S是通过让pod中的用户容器加入(join)另一个第三方容器的network namespace实现的共享,而这个第三方容器就是pause容器。
这么做的目的其实也比较简单,没有 pause 容器,那么 A 和 B 要共享网络,要不就是 A 加入 B 的 network namespace,要嘛就是 B 加入 A 的 network namespace, 而无论是谁加入谁,只要 network 的 owner 退出了,该 Pod 里的所有其他容器网络都会立马异常。
反过来,由于 pause 里只有是挂起一个容器,里面没有任何复杂的逻辑,只要不主动杀掉 Pod,pause 都会一直存活,这样一来就能保证在 Pod 运行期间同一 Pod 里的容器网络的稳定。
我们在同一 Pod 里所有容器里看到的网络视图,都是完全一样的,包括网络设备、IP 地址、Mac 地址等等,因为他们其实全是同一份,而这一份都来自于 Pod 第一次创建的这个 Infra container。
由于所有的业务容器都要依赖于 pause 容器,因此在 Pod 启动时,它总是创建的第一个容器,可以说 Pod 的生命周期就是 pause 容器的生命周期。
控制器
kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制pod的具体状态和行为,控制器包含:ReplicationController、ReplicaSet、Deployment、DaemonSet、StatefulSet、Job/CronJob、HorizontalPodAutoscaler
ReplicationController(RC)和ReplicaSet(RS)
ReplicationController (RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的pod来替代;而异常多出来的容器也会自动回收。
在新版的Kubernetes中建议使用ReplicaSet (RS)来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,但ReplicaSet支持集合式selector。
虽然 ReplicaSets 可以独立使用,但如今它主要被Deployments 用作协调 Pod 的创建、删除和更新的机制。当使用 Deployment 时,你不必担心还要管理它们创建的 ReplicaSet,Deployment 会拥有并管理它们的 ReplicaSet。
ReplicaSet 是下一代的 Replication Controller。 ReplicaSet 和 Replication Controller 的唯一区别是选择器的支持。ReplicaSet 支持新的基于集合的选择器需求,这在标签用户指南中有描述。而 Replication Controller 仅支持基于相等选择器的需求。
Deployment
Deployment是Kubernetes中一种声明式控制器,用于管理和维护一组Pod副本。它主要用于管理无状态应用的生命周期,通过声明Deployment,可以自动化地控制应用的副本数量、进行无停机更新、扩展、缩容等。
Deployment 控制器为 Pods和 ReplicaSets提供描述性的更新方式,用来替代以前的ReplicationController以方便管理应用。
Deployment的主要功能:
定义期望状态:指定希望部署的应用配置和数量。
管理副本:确保应用副本数量与配置的期望值一致。
无停机更新:支持滚动更新,逐步更新Pod,更新过程中不会中断服务。
版本回滚:可以回滚到之前的某个版本,以应对更新失败的情况。
扩展性:支持自动扩容和缩容,通过HPA(Horizontal Pod Autoscaler)等资源进行弹性管理。
Deployment与其他Kubernetes组件的关系:
Pod:Kubernetes中最基本的部署单元,表示一个或多个容器的集合。Pod共享存储、网络和上下文。
ReplicaSet:确保指定数量的Pod实例在任何时候都在运行。它通过监控Pod的状态来管理Pod的创建和删除。如果某个Pod异常终止,ReplicaSet会创建一个新的Pod来替代它。
Deployment:更高级别的抽象,管理ReplicaSet的创建和更新。Deployment允许用户声明希望运行的应用状态,包括Pod的模板、副本数量和更新策略。
Service: Deployment创建的Pod可以通过标签与Service进行关联。当创建一个Service时,可以指定一个或多个标签选择器来匹配Pod。这些匹配的Pod就会被Service所管理,并通过Service提供的虚拟IP地址和端口号进行访问。Service为Deployment创建的Pod提供了一个稳定的网络访问入口。这样,外部客户端或集群内的其他Pod就可以通过访问Service来间接访问到Pod提供的服务。Service还提供了负载均衡功能,可以将请求分发到多个Pod上,以实现高可用性和可扩展性。这对于提高应用的性能和可靠性具有重要意义。
StatefulSet
StatefulSet是用来管理有状态应用的服务。和无状态的Deployment不同,StatefulSet需要保持每个Pod的唯一性和持久性。比如数据库、消息队列这样的应用,每个实例的数据都是独立的,不能随意替换或删除,这时候就需要StatefulSet来管理。
StatefulSet的核心特性
唯一标识与稳定性
每个Pod分配唯一索引标识(如pod-0, pod-1),即使重启或迁移,标识不变。
依赖Headless Service提供稳定DNS记录(如pod-0.example.com),确保客户端始终连接到同一实例。
持久化存储
- 通过volumeClaimTemplates自动生成独立的PersistentVolumeClaim(PVC),每个Pod拥有专属存储卷,数据持久化。
有序扩缩容
- 扩容时按索引顺序创建新Pod(如从pod-2到pod-N),缩容时逆序删除旧Pod(如先删pod-0),保障服务连续性。
滚动更新策略
- 支持配置maxSurge(最大并发更新数)和maxUnavailable(最大不可用数),默认策略为逐个更新,减少对集群的影响。
StatefulSet VS Deployment
生命周期管理
StatefulSet
- 当增加或减少副本时,它会按顺序创建或删除Pod,确保旧的Pod先下线,新的Pod再上线,这样可以避免服务中断。
Deployment
- 并行更新,可能导致短暂的服务不可用。
应用场景
StatefulSet
主要用于管理有状态应用。
有状态应用需要持久化数据或具有唯一网络标识符。
StatefulSet提供了持久化存储和稳定的网络标识符,适用于需要保持数据完整性和服务身份的应用。
Deployment
主要用于管理无状态应用。
无状态应用通常不需要持久化数据或唯一网络标识符。
Deployment提供了一种简单的方式来部署和更新应用,支持滚动更新和回滚。
Pod管理
StatefulSet
Pod名称是基于索引的,具有固定的顺序和标识。每个Pod都有一个唯一的、持久的身份标识。
每个Pod可以有独自的存储卷,通常与PersistentVolumeClaim(PVC)结合使用,以确保数据的持久化和隔离。
Pod具有稳定的网络标识,如DNS名称,可以通过Headless Service精确访问到每一个Pod。
Deployment
Pod名称是随机生成的,没有固定的顺序或标识。每个Pod都是可替换的,具有相同的配置和环境。
Pod通常共享存储卷,但这不适用于有状态应用,因为数据可能会相互干扰。
Pod没有稳定的网络标识,通常通过Service进行通信。
部署与更新策略
StatefulSet
支持有序的创建和删除Pod,这在需要特定顺序执行初始化脚本或清理操作的情况下非常有用。StatefulSet不直接支持滚动更新,因为需要考虑数据的一致性和服务的连续性,更新过程通常需要更谨慎的操作,可能需要手动干预。
支持自动回滚和暂停/恢复更新。
Deployment
通过ReplicaSet管理Pod的副本数,支持滚动更新策略,允许逐个替换Pod以保持服务的可用性。
支持自动回滚和暂停/恢复更新。
其它特性
StatefulSet
- 适用于数据库集群(如MySQL、Cassandra)、分布式缓存系统(如Redis集群)以及任何需要持久化数据或特定网络标识的应用。
Deployment
- 适用于Web应用服务器、微服务以及任何不需要持久化数据或特定网络标识的应用。
Service&Ingress
概念以及作用
Ingress主要负责七层负载,将外部 HTTP/HTTPS 请求路由到集群内部的服务。它可以基于域名和路径定义规则,从而将外部请求分配到不同的服务。
Ingress的作用:
提供 基于 HTTP/HTTPS 的路由。
支持 TLS 终止(HTTPS)。
为集群内部多个服务提供一个 统一的访问入口。
提供高级功能,如 路径重写、反向代理、负载均衡。
Service主要是面向四层负载,基于TCP传输,用于将流量分发到一组 Pod。Service 抽象出 Pod 的网络访问,提供稳定的网络接口,即使 Pod 动态变化,其访问方式仍保持不变。
Service的作用:
提供 Pod 的 服务发现 和 负载均衡。
允许集群内外部流量访问特- 定的 Pod。
支持多种访问类型,包括 ClusterIP、NodePort、LoadBalancer 和 ExternalName。
使用场景对比
使用场景 | Ingress | Service |
---|---|---|
服务访问入口 | Ingress 可配置域名和路径规则,为多个服务提供统一入口。 | Service 无法管理多个服务,只能处理一个服务的流量。 |
内部服务通信 | 不适合用于集群内部通信。 | 使用 ClusterIP 类型的 Service 实现 Pod 之间通信。 |
外部流量接入 | 通过 Ingress 控制器暴露服务,适用于 HTTP/HTTPS 流量。 | 通过 NodePort 或 LoadBalancer 类型暴露服务。 |
TCP/UDP 流量 | 不支持,仅处理 HTTP/HTTPS。 | 支持 TCP、UDP 流量,通过 Service 直接转发。 |
域名路由 | 支持基于域名的路由规则。 | 不支持域名路由。 |
复杂流量管理(SSL、重定向等) | 支持多种高级功能,如 TLS、路径重写等。 | 只提供基础的流量转发功能。 |
关键特性对比
Ingress特性:
协议支持:仅支持HTTP和HTTPS;
路由规则:基于域名和路径进行路由,例如,根据路径/app1路由到Service A,路径/app2路由到service B;
TLS支持:直接HTTPS,TLS终止直接在Ingress层进行,配置TLS后,用户访问时自动升级为HTTPS;
负载均衡:在Ingress层负载均衡到不同的Service,每个Service内部pod之间的负载均衡由Service实现;
Service特性:
协议支持:支持HTTP、HTTPS、TCP、UDP等多种协议;
Service类型:
ClusterIP(默认):仅在集群内部可访问;
NodePort:通过每个节点上的特定端口暴露服务;
LoadBalancer:通过云提供商的负载均衡器暴露服务;
ExternalName:将请求重定向到外部DNS名称;
负载均衡:Service 将流量分发到其关联的多个 Pod,实现 Pod 级别的负载均衡;
服务发现:Kubernetes 自动为每个 Service 创建一个 DNS 入口,集群内其他服务可以通过服务名访问;
Ingress和Service之间的关系
Ingress依赖于Service,Ingress 本身并不直接与 Pod 通信,它将请求转发到 Service,而 Service 再将流量分发到具体的 Pod。
Ingress的典型流量场景:
用户请求 通过域名或 IP 访问 Ingress。
Ingress 根据配置规则,将流量转发到对应的 Service。
Service 负责将流量分配到 Pod。
Service 可以单独使用,而不需要依赖 Ingress。例如,NodePort 和 LoadBalancer 类型的 Service 可以直接暴露服务给外部。