学习 k8s
核心组件
控制面板组件
控制面板组件 包括 kube-apiserver、etcd、kube-scheduler、kube-controller-manager
负责管理集群的整体状态
kube-apiserver
职责:提供 Restful API 服务,来操作 k8s 资源对象(如 Pod、Deployment、Service 等)
流量来源:
- 内部:
- 控制面板组件,如 kube-scheduler 查询 pod 状态,kube-controller-manager 查询资源状态
- 外部:
- kubectl 命令
- kubernetes dashboard 等页面
- CI/CD 系统(Gitlab、Jenkins)
- 监控系统
etcd
提供一致性和高可用性的键值存储服务
kube-scheduler
查找尚未绑定到节点的 Pod,并将每个 Pod 分配给合适的节点
kube-controller-manager
负责运行各种控制器(Controller)来确保集群的状态与用户声明的期望状态一致
Node组件
Node 组件包括 kubelet、kube-proxy、container runtime
负责维护运行的 Pod 并提供 k8s 运行时环境
kubelet
是节点级别操作的关键代理,负责管理本节点上的 Pod 生命周期 和 容器运行时,确保 Pod 正常运行(健康检查、重启容器)
kube-proxy
是每个 Node 上负责网络代理的组件,负责 Service 的负载均衡和网络规则管理,确保 Pod 之间以及外部能否通过 Service 访问应用
Container runtime
负责管理容器的生命周期,包括 创建、启动、停止和销毁容器,是 k8s 与容器交互的执行者
架构
Workloads
workloads 是 k8s 上运行的应用程序,在一组 Pod 中运行它
为了减轻用户的使用负担,通常不需要用户直接管理每个 Pod
。
而是使用负载资源来替用户管理一组 Pod
这些负载资源通过配置控制器来确保 Pod 状态与用户所指定的状态相一致
Pod
Pod 是 Kubernetes 中创建和管理的、最小的可部署的计算单元
Pod 内的容器共享资源,不同 Pod 内的容器资源隔离
Pod 的共享上下文包含一组 Linux namespaces、cgroups 来实现隔离容器;Pod 内的容器共享 namespace 和文件卷,Pod 为其成员容器提供了两种共享资源:网络 和 存储
可以通过 kubectl 命令创建,但通常不需要直接创建,而是使用 workloads 资源来创建
Pod 的生命周期
Pod 的 phase:
- Pending:Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建
- Running:Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态
- Successded:Pod 中的所有容器都已成功结束,并且不会再重启
- Failed:Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止
- Unknown:因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败
应用容器:运行应用程序的容器
Init 容器:在应用容器启动前运行,包括一些应用镜像中不存在的实用工具和安装脚本,不会持续与主容器一起运行
Sidecar 容器:边车容器是与主应用容器在同一个 Pod 中运行的辅助容器。 这些容器通过提供额外的服务或功能(如日志记录、监控、安全性或数据同步)来增强或扩展主应用容器的功能, 而无需直接修改主应用代码
临时容器:对于交互式故障排查
workloads 管理
负责帮用户管理 Pod,有几个内置的 API 来声明式管理 workloads,分别是 Deployment、ReplicaSet、StatefulSet、DaemonSet、Job、CronJob
Deployment
Deployment 是集群上运行应用的最常见方式,适合在集群上管理无状态应用工作负载。Deployment 中的任何 Pod 都是可互换的,可以在需要时进行替换,这些 Pod 都是等价的
ReplicaSet
用来维护一组在任何时候都处于运行状态的 Pod 副本的集合,来保证给定数量的、完全相同的 Pod 的可用性,通常用 Deployment 来管理 ReplicaSet
StatefulSet
用来管理有状态的 Pod,最常见的用途是能够建立其 Pod 与其持久化存储之间的关联,如果该 StatefulSet 中的一个 Pod 失败了,Kubernetes 将创建一个新的 Pod, 并连接到相同的 PersistentVolume
DaemonSet
用来确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod
DaemonSet 的典型用法有:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
Job & CronJob
Job 用来运行一次性任务
CronJob 用来运行定时任务
如何使用上面的工具来管理应用的部署呢,包括扩缩和更新
组织资源配置
将多个资源归入同一个文件,可以简化对多个资源的管理。例如:
1 | apiVersion: v1 |
kind: Service,定义一组 Pod 的逻辑集合和访问策略的方式,主要功能:
- 服务发现:为 Pod 提供稳定的 IP 地址和 DNS 名称
- 负载均衡:将流量分发到一组 Pod
- 暴露服务:将服务暴露给集群内部或外部访问
spec:specification 规格,定义了资源的期望状态
labels: 标识和分类 k8s 对象
app:一个常用的标准标签,用于标识应用程序名称
selector:定义选择标准和关联关系,如 Service 使用 selector 确定它将流量路由到哪些 Pod
网络
K8s 网络模型由几个部分构成:
- 集群中每个 pod 都有自己唯一的 IP 地址
- Pod 网络:处理 Pod 之间的通信
- Service:为多个 Pod 组成的服务提供一个长效的 IP 地址或主机名,其中的各个 Pod 可以随时变化
- Gateway:(或其前身 Ingress)使集群外的客户端可以访问 Service
Service
将运行在一组 Pod 上的应用程序公开为网络服务的方法,每个 Service 对象定义端点(Pod)的一个逻辑集合以及如何访问这些 Pod 的策略,当 Pod 变化时,客户端不会感知这些变化
1 | apiVersion: v1 |
如上,协议为 TCP,对外端口 80,转发到一组 Pod 的端口是 9376
K8s 会为该 Service 分配一个 IP 地址(成为集群 IP)
Ingress
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP
目前 Ingress 已停止更新,新的功能集成到 网关API 中
Ingress 提供从集群外部到集群内 Service 的 http 和 https 路由,流量路由由 Ingress 规则来控制
Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡;Ingress 控制器负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器
Gateway API
存储
要解决的问题:
- 数据丢失: 容器中的文件在磁盘上是临时存放的,当容器崩溃或停止时,容器的状态不会被保存,因此在容器生命期内创建或修改的所有文件都将丢失。 在崩溃之后,kubelet 会以干净的状态重启容器
- 共享存储:当多个容器在一个 Pod 中运行并需要共享文件时,会出现另一个问题。 那就是在所有容器之间设置和访问共享文件系统可能会很有难度。
Colume 为 pod 中的容器提供了一种通过文件系统访问和共享数据的方式,存在不同类别的 Colume 用于不同的用途:
Colume 类型 | 数据持久性 | 使用场景 |
---|---|---|
configMap | ❌ 配置 | 应用配置文件 |
emptyDir | ❌ 临时 | 临时文件/缓存 |
PVC(PV) | ✅ 持久 | 数据库/生产应用数据 |
NFS | ✅ 持久 | 共享文件/媒体存储 |
CSI | ✅ 持久 | 扩展专业存储需求 |
hostPath | ⚠️ 节点级 | 开发调试/访问节点日志 |
持久券
PersistentVolume,PV 是集群中的一块存储,可以由管理员事先制备,或者使用存储类(Storage Class)动态制备,其特点为:
- 集群资源:PV 是集群级别的资源,不隶属于任何命名空间
- 生命周期独立:PV 的生命周期独立于使用它的 Pod
- 后端存储:PV 可以是 NFS、iSCSI、云存储(如 AWS EBS、GCE PD、Azure Disk)等
- 静态配置:通常由管理员预先创建
- 动态配置:可以通过 StorageClass 动态创建
1 | apiVersion: v1 |
PersistentVolumeClaim,PVC 申请了用户对存储的请求,PVC 可以请求特定的大小和访问模式(例如,可以挂载为 ReadWriteOnce、ReadOnlyMany、ReadWriteMany 或 ReadWriteOncePod)来消耗 PV 资源
其特点为:
- 命名空间资源:PVC 是是命名空间级别的资源
- 用户请求:用户通过 PVC 声明所需的存储大小和访问模式
- 绑定 PV:Kubernetes 会找到匹配的 PV 与之绑定
- 动态配置:当没有匹配的 PV 时,可以触发动态配置(如果有 StorageClass)
1 | apiVersion: v1 |
PV 与 PVC 的关系:
- 绑定过程:
- 用户创建 PVC,指定所需存储的大小和访问模式
- Kubernetes 控制平面查找匹配的 PV
- 如果找到合适的 PV,则将 PVC 绑定到 PV
- 如果没有找到,且配置了 StorageClass,则会动态创建 PV
- 访问模式:
ReadWriteOnce
(RWO):可被单个节点读写挂载ReadOnlyMany
(ROX):可被多个节点只读挂载ReadWriteMany
(RWX):可被多个节点读写挂载
- 回收策略:
Retain
:保留数据,需要手动清理Recycle
:覆盖 (不推荐,已弃用)Delete
:自动删除关联的存储资源(云存储支持)
使用场景
- 数据库存储:MySQL、PostgreSQL 等需要持久化数据的应用
- 文件共享:需要多个 Pod 共享的文件存储
- 日志存储:需要长期保存的日志数据
- 应用状态:有状态应用的状态数据存储
存储类
StorageClass 用来定义存储类别,允许管理员描述他们提供的存储类型,并支持动态卷配置
主要功能是:
- 动态券配置:动态创建 PV,如果 PVC 指定了 StorageClass 且没有现成的 PV 满足该 PVC 的需求,会按照 StorageClass 的描述来创建新的 PV
- 存储分类:管理员可以创建多个 StorageClass 来表示不同类型的存储,如 SSD、HDD 等
配置
ConfigMap
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。Pod 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。使用 ConfigMap 可以将配置数据和应用程序代码分开
Secret
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象,比如向 Pod 提供 SSH 密钥或密码
探针
- 存活探针:决定何时重启容器,如果一个容器的存活探针失败多次,kubelet 将重启该容器
- 就绪探针:决定何时容器准备好开始接受流量
- 启动探针:检查容器内的应用是否已启动
资源管理
- CPU 个数(一个 CPU 等于 1 个物理 CPU 核)
- 内存大小
minikube
启动
1 | minikube start |
查看 Deployment
1 | kubectl get deployments |
查看 Pod
1 | kubectl get pods |
删除 Deployment
1 | kubectl delete deployment {name} |
打开控制台
1 | minikube dashboard |
应用部署
部署 nginx
nginx.yaml
1 | apiVersion: v1 |
启动
1 | kubectl apply -f nginx.yaml |
建立 Docker Desktop 网络与宿主机的映射
1 | minikube service my-nginx-svc --url |
Reference
https://kubernetes.io/zh-cn/docs/tutorials/
https://kubernetes.io/zh-cn/docs/concepts/overview/components/