一、k8s基本概念
Kubernetes 简称 k8s,是支持云原生部署的一个平台,起源于谷歌。谷歌早在十几年之前就对其应用,通过容器方式进行部署。 k8s 本质上就是用来简化微服务的开发和部署的,关注点包括自愈和自动伸缩、调度和发布、调用链监控、配置管理、Metrics 监控、日志监控、弹性和容错、API 管理、服务安全等,k8s 将这些微服务的公共关注点以组件形式封装打包到 k8s 这个大平台中,让开发人员在开发微服务时专注于业务逻辑的实现,而不需要去特别关系微服务底层的这些公共关注点,大大简化了微服务应用的开发和部署,提高了开发效率。
master 节点由以下组件组成;
• etcd,一种的分布式存储机制,底层采用 Raft 协议,k8s 集群的状态数据包括配置、节点等都存储于 etcd 中,它保存了整个集群的状态。
• API server,对外提供操作和获取 k8s 集群资源的的 API,是唯一操作 etcd 的组件,其他的组件包括管理员操作都是通过 API server 进行交互的,可以将它理解成 etcd 的 “代理人”。
• Scheduler ['skɛdʒuələr'],在 k8s 集群中做调动决策,负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上。
• Controller Manager [kənˈtrolɚ],相当于集群状态的协调者,观察着集群的实际状态,与 etcd 中的预期状态进行对比,如果不一致则对资源进行协调操作让实际状态和预期状态达到最终的一致,维护集群的状态,比如故障检测、自动扩展、滚动更新等。
node节点由以下组件组成:
• Controller Runtime,下载镜像和运行容器的组件,负责镜像管理以及 Pod 和容器的真正运行(CRI)。
• Pod [pa de],k8s 中特有的一个概念,可以理解为对容器的包装,是 k8s 的基本调度单位,实际的容器时运行在 Pod 中的,一个节点可以启动一个或多个 Pod。
• kubelet [ku-ber-let],负责管理 worker 节点上的组件,与 master 节点上的 API server 节点进行交互,接受指令执行操作。
• kube-proxy[ˈprɒk.si],负责对 Pod 进行寻址和负载均衡
二、k8s核心概念
1. 集群 Cluster [klʌstɚ]
集群有多个节点组成且可以按需添加节点(物理机/虚拟机),每一个节点都包含一定数量的 CPU 和内存 RAM。
2. 容器 Container [kənˈtenɚ]
k8s 本身是一个容器调度平台,从宿主机操作系统来看,容器就是一个一个的进程。从容器内部来看容器就是一个操作系统,它有着自己的网络、CPU、文件系统等资源。
3. POD
k8s 也不是直接调度容器的,而是将其封装成了一个个 POD,POD 才是 k8s 的基本调度单位。每个 POD 中可以运行一个或多个容器,共享 POD 的文件系统、IP 和网络等资源,每一个 POD 只有一个 IP。
4. 副本集 ReplicaSet [rɛplɪkə]
Kubernetes 中的一个核心控制器对象,它的核心使命非常简单却至关重要:确保在任何时刻,都有指定数量的、完全相同的 Pod 副本(Replicas)在运行。
副本集可对应一个应用的一组 POD,运行时副本集会监控和维护 POD 的数量,数量过多则会下线 POD,过少则启动 POD。
通过标签选择器(Label Selector)识别 Pod
-
ReplicaSet 使用一个强大的
selector
字段来定义它要管理哪些 Pod。 -
这个选择器基于 Pod 上附加的标签(Labels)进行匹配。
-
只有那些标签匹配选择器条件的 Pod,才会被 ReplicaSet 视为由它管理的副本。
使用 Pod 模板(Pod Template)创建新 Pod
- ReplicaSet 定义中包含一个 template 字段。
- 这个模板描述了当需要创建新 Pod 副本时,这些 Pod 应该是什么样子(比如使用哪个容器镜像、需要多少 CPU/内存、挂载哪些卷、设置什么环境变量等)。
- 新创建的 Pod 会自动获得 ReplicaSet 的选择器所期望的标签,确保它们能被 ReplicaSet 识别和管理。
它可以通过模板来规范某个应用的容器镜像、端口,副本数量等。
5. 服务 service
它解决了一个至关重要的网络问题:如何让一组动态变化的 Pod(通常是副本集的后端)能够被稳定、可靠地访问?
它的核心使命是: 为运行在一组 Pod 上的应用程序提供单一、稳定的网络入口点和访问方式,无论后端的 Pod 如何创建、销毁、迁移或扩展。
Service解决什么问题:
- pod的动态IP:pod不断的因为各种原因进行销毁和重建,每次重启和重建都会分配一个新的IP
- 一个副本集(RepilcaSet)维护多个相同功能的pod副本,同时将每个pod的IP展示在客户端是没有必要的
- 直接跟踪的困难:客户端跟踪一个不断变化的pod IP列表是及其浪费算力的
如何解决:
- 提供稳定的虚拟 IP (VIP) 和 DNS 名称:
Service 会被分配一个持久的 Cluster IP 地址(在集群内部有效)和一个DNS 名称(例如 my-svc.my-namespace.svc.cluster.local)。
这个 VIP 和 DNS 名称在 Service 的整个生命周期内保持不变,即使后端的 Pod 全部被替换了。
客户端只需要记住这个稳定的地址或名称来访问服务。
服务发现: Service 自动发现符合其标签选择器(Label Selector)的所有 Pod。
你通过定义 selector(例如 app: my-app)告诉 Service 它应该管理哪些 Pod(通常就是由 ReplicaSet/Deployment 管理的那些 Pod)
Service 会持续监控集群,将匹配该标签的、处于 Running 状态的 Pod 加入其端点列表(Endpoints)(或更现代的 EndpointSlices)
- 注:Endpoints(端点)在网络或API上下文中指代通信的入口点或终点,通常用于数据交换或服务交互。它是客户端与服务器、服务与组件之间进行信息传输的特定地址或接口。
2.负载均衡:
当客户端(无论是集群内的其他 Pod 还是外部客户端,取决于 Service 类型)向 Service 的 VIP 或 DNS 名称发起请求时,Service 自动将流量负载均衡到其后端健康的 Pod 列表上。
- 注:网络负载均衡基于传输层(如TCP/IP)分发流量,例如LVS(Linux Virtual Server)或硬件负载均衡器(如F5)。
默认的负载均衡策略是轮询(Round Robin)。
- 注: 负载均衡算法有:
- 轮询(Round Robin)依次分配请求到每个服务器。
- 加权轮询(Weighted Round Robin):根据服务器性能分配不同权重。
- 最少连接(Least Connections):优先选择当前连接数最少的服务器。
- IP哈希(IP Hash):根据客户端IP固定分配同一服务器,保持会话粘性。
4. Service的类型和解耦:
- ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
- LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
- ExternalName: 把集群外部的服务引入集群内部,直接使用
- Ingress : 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http,https服务(七层,只能发布这俩个服务)
- 7层负载均衡比4层负载均衡更加智能
4层负载均衡比7层负载均衡更加简洁高效
Service 完全解耦了客户端和后端 Pod 的具体实现。
POD 在 k8s 中是不固定的,可能会挂起或者重启,且挂起重启都是不可预期的,那么这就会导致服务的 IP 也随着不停的变化,给用户的寻址造成一定的困难。而 service 就是用来解决这个问题的,它屏蔽了应用的 IP 寻址和负载均衡,消费方可直接通过服务名来访问目标服务,寻址和负载均衡均由 service 底层进行。
6. 发布 守护进程集 Deployment [di:'plɔimənt]
副本集就是一种基本的发布机制,可以实现基本的或者高级的应用发布,但操作较为繁琐。未来简化这些操作,k8s 引入了 Deployment 来管理 ReplicaSet,进而管理pod,实现一些高级发布机制。核心技术是创建新的ReplicaSet来替代新的,例如:
- 滚动更新是逐步使用旧版本替换掉新版本的ReplicaSet,优点是更新期间应用可用。
- 重建更新是删除旧版本的pod在创建所有新版本的pod,优点:确保某一时刻只有一个版本运行
7. ConfigMap/Secret
微服务在上线时需要设置一些可变配置,环境不同则配置值不同,有些配置如数据库的连接字符串在启动时就应该配好,有些配置则可以在运行中动态调整。为了实现针对不同环境灵活实现动态配置,微服务就需要 ConfigMap 的支持。
核心作用: 将非敏感的、纯文本的配置数据(如配置文件、环境变量、命令行参数)从容器镜像中分离出来,以键值对(Key-Value)或完整配置文件的形式存储和管理。
k8s 平台内置支持微服务的配置(ConfigMap),开发人员将配置填写在 ConfigMap 中,k8s 再 将 ConfigMap 中的配置以环境变量的形式注入 POD,这样 POD 中的应用就可以访问这些配置。
使用方法:
- 挂载为卷 (Volume): 将一个或多个 ConfigMap 项作为文件挂载到容器的指定目录下(常用且支持热更新)。
- 设置为环境变量: 将 ConfigMap 的键值对注入为容器的环境变量。
- 在 Pod 命令/参数中引用: 在 command 或 args 中使用 $(KEY_NAME) 语法引用 ConfigMap 的值。
- 作为只读卷: 挂载后容器内文件是只读的。
Secret 是一种特殊的 ConfigMap,提供更加安全的存储和访问配置机制。
8. DaemonSet [dimən]
DaemonSet 是 Kubernetes 管理节点级守护进程的基石。当你的服务需要像“贴身助手”一样,出现在集群的每一个节点(或满足条件的节点)上,执行日志收集、监控、网络、存储等基础设施任务时,DaemonSet 就是最自然、最强大的选择。它确保了这些关键服务在节点维度的高可用性和全覆盖性。
9.Job
Job本身是Kubernetes中一种执行一次性任务的控制器,负责创建Pod并确保它们成功完成
Job的主要目的是管理一次性任务,确保任务运行到完成。与常规Pod不同,Job创建的Pod在任务完成后会自动终止。Job会跟踪Pod的执行状态,并根据需要重试失败的Pod。
Job通常用于批处理任务、数据处理或其他需要确保完成的工作负载。当任务成功完成后,Job会记录完成状态,但不会自动删除相关资源(除非配置了自动清理)。
10.CronJob
CronJob是一种用于管理定时任务的资源对象。它允许你按照预定的时间表定期运行任务,类似于Linux系统中的cron守护进程。CronJob非常适合用于执行周期性的任务,例如备份、清理、报告生成等。
1.CronJob工作流程
当CronJob被创建后,Kubernetes会根据指定的时间表定期创建Job对象。每个Job对象会启动一个或多个Pod来执行任务。CronJob控制器负责监控时间表,并在适当的时间创建新的Job。
2.CronJob的关键字段
- schedule: 指定任务执行的时间表,使用标准的cron表达式。
- jobTemplate: 定义Job的模板,包括Pod的配置、容器镜像、命令等。
- concurrencyPolicy: 控制并发执行的任务数量,可选值为Allow、Forbid和Replace。
- startingDeadlineSeconds: 设置任务启动的截止时间,如果任务在指定时间内未能启动,则视为失败。
- successfulJobsHistoryLimit: 保留成功完成的Job历史记录的数量。
- failedJobsHistoryLimit: 保留失败的Job历史记录的数量。
三、资源划分和管理
1.命名空间
Kubernetes中的Namespace是一种用于在集群内部组织和隔离资源的机制。一个Namespace可以看作是一个虚拟的集群,它将物理集群划分为多个逻辑部分,每个部分都有自己的一组资源(如Pod、Service、ConfigMap等)。
Namespace 适合用于隔离不同用户创建的资源
用于给集群中的任何对象组进行分类、筛选和管理。每一个添加到Kubernetes集群的工作负载必须放在一个命名空间中。
不同的业务(web、数据库、消息中间)可以部署在不同的命名空间,实现业务的隔离,并且可以对其进行资源配额,限制cpu、内存等资源的使用
2.命名空间的特性
1.隔离性(核心特性) • 核心作用: 将不同命名空间内的标识符(变量、函数、类等)完全隔离,避免同名冲突。 • 实现方式: ◦ 相同名称在不同命名空间中互不影响(如 A::calculate() 与 B::calculate())。 ◦ 未显式指定命名空间时,默认使用当前作用域或全局命名空间。
类比: 文件系统中,C:\Project\utils.log 和 D:\Backup\utils.log 互不影响;
DNS 中,mail.company.com 与 mail.university.edu 指向不同服务器。
2. 层次性与嵌套 • 核心作用: 支持命名空间的多级嵌套,形成逻辑层级,增强代码组织性。
3. 访问控制与可见性 • 核心作用: 通过显式声明控制命名空间内成员的暴露范围。
- 关键机制:
导出(Export/Public):
■ C++:通过 using 声明或直接限定访问。
■ Python:用 __all__ 或下划线约定(_internal 表示私有)。
■ JavaScript:export 关键字声明公开成员。
隐藏(Private):
未导出的成员仅在命名空间内部可见(如 Python 的 _private_var)。
2.标签与注解
1.标签(Labels)
核心目的 :标识与选择对象,用于逻辑分组和资源关联(如 Service 通过标签选择 Pod)。 核心特性
1. 结构化键值对
- 格式:key=value(如 env=prod, app=frontend)。
- 键的语法:字母/数字开头,支持 -、_、.(如 app.kubernetes.io/name)。
2. 高效查询与过滤 ◦ 支持选择器(Selectors)进行对象筛选:
yaml文件
# Service 选择标签为 app=nginx 的 Pod
selector:
app: nginx
命令行操作
kubectl get pods -l env=prod,app!=backend # 筛选 env=prod 且 app 非 backend 的 Pod
3.影响 Kubernetes 行为
- 服务发现:Service 通过标签关联 Pod。
- 控制器管理:Deployment 通过标签管理 ReplicaSet。
- 网络策略:NetworkPolicy 通过标签控制流量。
- 节点调度:NodeSelector 按标签选择节点(如 node-type: gpu)。
4. 不可变设计
-
更新标签需重建对象(如 Pod 的标签不可动态修改)。
2.注解(Annotations)
核心目的 存储非标识性元数据,用于工具扩展、运维说明或记录上下文信息(不影响 K8s 核心逻辑)。
核心特性
1. 自由格式的键值对
值可以是 JSON、XML、纯文本等任意数据(如维护者信息、Git Commit ID)。
yaml文件
metadata:
annotations:
owner: "team-devops@example.com"
commit-id: "a1b2c3d"
policy/last-updated: "2023-10-01T12:00:00Z"
2.不参与对象选择
- 无法用于 Selectors:不能通过注解筛选资源。
- 不影响 K8s 内部逻辑:仅作为附加信息存储。
3. 工具链与生态集成
- CI/CD 工具:记录构建信息(如 Jenkins 写入构建号)。
- 监控系统:Prometheus 通过注解配置抓取规则:
yaml
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
- Ingress 控制器:Nginx Ingress 通过注解定制行为:
yaml
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
4.支持动态更新
- 可直接修改(如 kubectl annotate),无需重建对象。