@yangwenbo
2025-08-08T09:36:13.000000Z
字数 20006
阅读 68
K8s基础概念
Kubernetes是一个开源的容器编排平台,旨在解决大规模容器化应用的部署、扩缩容、运维难题。它的核心目标是通过声明式配置和自动化调度,让开发者从繁琐的基础设施管理中解放,专注于业务逻辑开发。
类比理解
- 若将容器(如Docker容器)比作“货物”,k8s则是智能的“物流系统”:自动调度货物到合适的车辆(节点),监控运输状态,并在故障时自动修复。
- 若将服务器集群比作“操作系统”,k8s则是其“内核”:统一管理进程(容器)的资源分配和生命周期。
功能 | 描述 |
---|---|
自动化运维 | 自愈(Pod自动重启)、动态扩缩容(HPA)、滚动更新与回滚 |
服务发现与负载均衡 | 通过Service和Ingress暴露服务,流量智能分发到健康容器 |
存储编排 | 支持动态挂载云存储、本地磁盘,满足有状态应用(如MySQL)需求 |
配置与密钥管理 | 使用ConfigMap和Secret解耦环境配置与镜像,保障敏感数据安全 |
- 单独的Docker无法满足生产需求
- 缺乏完整的生命周期管理
- 缺乏服务发现、负载均衡、配置管理、存储管理
- 程序的扩容、部署、回滚和更新依旧不够灵活
- 宿主机宕机容器无法自动恢复
- 程序级健康检查依旧不到位
- 端口管理比较复杂
- 流量管理依旧复杂
- K8s核心优势
- 高可用性:自动故障转移,保障业务连续性。
- 弹性伸缩:根据负载动态调整资源,降低成本。
- 生态丰富:Helm(包管理)、Prometheus(监控)、Istio(服务网格)等工具链完善。
- 挑战与权衡
- 学习曲线陡峭:需掌握YAML、网络模型(CNI)、存储方案等。
- 运维复杂度:中小团队可考虑Serverless(如AWS Lambda)简化架构。
- Master节点组件:
- kube-apiserver:集群的控制入口,提供REST API接口。
- kube-scheduler:负责Pod调度,决定Pod运行在哪个节点上。
- kube-controller-manager:运行各种控制器,确保集群状态与期望状态一致。
- etcd:分布式键值存储,保存集群所有配置信息。
- Node节点组件:
- kubelet:负责节点上的Pod生命周期管理。
- kube-proxy:负责实现服务(Service)负载均衡和网络代理。
- 容器运行时(如Docker、containerd):运行容器镜像的环境。
- userspace模式(已弃用):性能低,转发开销大。
- iptables模式(常用):性能中等,规则复杂,容易扩展。
- ipvs模式(推荐):性能高,负载均衡功能更强。
以部署一个应用为例:
- 用户通过kubectl提交Deployment配置。
- API Server接收请求并写入etcd。
- Controller Manager创建Pod,Scheduler将Pod绑定到Node。
- 目标Node的kubelet启动容器,kube-proxy配置网络规则。
- Service对外暴露服务,流量通过负载均衡分发到Pod。
- 微服务治理:管理数百个服务的部署、通信与监控。
- CI/CD流水线:集成Jenkins/GitLab,实现自动化构建与发布。
- 混合云管理:统一调度跨云厂商(AWS、Azure、阿里云)的资源。
Namespace在Kubernetes中是一种逻辑分组机制,允许将集群资源划分为独立的虚拟环境。
命名空间主要作用
- 资源隔离:不同团队或项目可以拥有自己独立的Namespace,以防止资源相互干扰
- 权限控制:可以为不同的Namespace设置不同的访问权限,实现不同的用户具有不同的权限
- 环境拆分:使用Namespace可以模拟出多个虚拟的集群环境,如开发、测试和生产环境。每个环境可以有自己的资源和服务,相互之间保持隔离,有助于简化部署和管理
- 资源配额和限制:划分不同的Namespace可以更加有效的分配资源和限制资源的使用量
- 服务发现和负载均衡:在同一个Namespace中服务发现和负载均衡更加简单和高效
- 简化管理:拆分不同的Namespace,可以更加方便的对Namespace下的资源进行操作,比如删除、备份或迁移等
Pod是Kubernetes最小的资源单位,一组容器的集合,生命周期短暂,可能随时被重建。
- 多容器协作
- 强依赖服务
- 简化应用的生命周期管理
- 兼容多种CRI运行时
- Always(默认):容器异常退出后自动重启。
- OnFailure:容器异常退出时才重启,成功完成则不重启。
- Never:无论成功失败,容器退出后都不重启。
状态 | 说明 |
---|---|
Pending(挂起) | Pod已被创建,但尚未调度到节点上,或正在拉取镜像。 可以通过 kubectl describe 查看处于Pending状态的原因 |
Running(运行中) | Pod已经成功调度到节点上,且所有容器都已创建并至少有一个容器处于运行状态。 可以通过 kubectl logs 查看Pod的日志 |
Succeeded(成功) | 所有容器执行成功并终止,并且不会再次重启。 可以通过 kubectl logs 查看Pod日志 |
Failed/Error(失败) | Pod中的至少一个容器异常退出(非0退出码),或者启动过程中发生了严重错误。 可以通过 logs 和describe 查看Pod日志和状态 |
Unknown(未知) | 通常是由于通信问题造成的无法获得Pod的状态 |
ImagePullBackOff/ErrImagePull | 镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的, 可以使用 describe 命令查看具体原因 |
CrashLoopBackOff | 容器启动失败, 可以通过 logs 命令查看具体原因,一般为启动命令不正确,健康检查不通过等 |
OOMKilled | 容器内存溢出,一般是容器的内存Limit设置的过小,或者程序本身有内存溢出。 可以通过 logs 查看程序启动日志 |
Terminating | Pod正在被删除。 可以通过 describe 查看状态 |
SysctlForbidden | Pod自定义了内核配置,但kubelet没有添加内核配置或配置的内核参数不支持。 可以通过 describe 查看具体原因 |
Completed | 容器内部主进程退出,一般计划任务执行结束会显示该状态。 此时可以通过 logs 查看容器日志 |
ContainerCreating | Pod正在创建,一般为正在下载镜像,或者有配置不当的地方。 可以通过 describe 查看具体原因 |
常见原因
- 资源不足:节点CPU、内存或临时存储不足。
- 节点选择问题:nodeSelector或nodeAffinity配置不匹配。
- 持久卷未绑定:PVC未找到可用PV。
- 污点与容忍不匹配:节点有排斥性污点,Pod未配置容忍。
- 资源配额超限:Namespace的ResourceQuota耗尽。
排查流程
1、查看Pod事件:
kubectl describe pod <pod-name> -n <namespace>
重点关注Events
中的错误提示(如Insufficient cpu
或未绑定的PVC)。
2、检查容器日志:
kubectl logs <pod-name> -c <container-name>
3、检查节点资源:
# 查看资源分配
kubectl describe node <node-name>
# 实时资源使用
kubectl top node
4、验证标签与选择器:
# 节点标签
kubectl get nodes --show-labels
# Pod选择器
kubectl get pod <pod-name> -o yaml | grep nodeSelector
5、检查污点与容忍:
# 节点污点
kubectl describe node <node-name> | grep Taints
# Pod容忍
kubectl get pod <pod-name> -o yaml | grep tolerations
可使用 kubectl top 命令:
# 节点资源
kubectl top nodes
# Pod资源
kubectl top pods
需提前安装 Metrics Server 组件。
PodDisruptionBudget定义允许同时不可用Pod的数量,用于保护应用高可用,避免维护或升级时服务中断。
VPA根据Pod历史资源使用情况自动调整Pod资源请求(CPU/内存)。当Pod重建时,以更合适的资源配置重启。
Deployment:控制Pod副本的部署和管理,提供滚动升级、回滚等功能,确保应用的高可用性。
- Deployment通过RS管理Pod,同时提供了如下的能力:
- 声明式创建和更新
- 自动化部署和回滚
- 一键式缩容
- 自动灾难修复
- 更高级的更新方式
健康检查、平滑退出
DaemonSet确保每个符合条件的节点运行一个Pod副本,适用于系统级服务。
- 节点全覆盖
- 新节点加入时自动创建Pod,节点删除时回收Pod。
- 经典场景:日志收集(Fluentd)、监控代理(Node Exporter)。
- 更新策略
- RollingUpdate:逐步替换旧Pod,可配置maxUnavailable。
- OnDelete:手动删除旧Pod后触发更新。
- 灵活调度控制
- 通过nodeSelector或affinity选择特定节点。
- 示例:仅在GPU节点部署AI推理服务:
template:
spec:
nodeSelector:
gpu: "true"
- 日志收集代理(如Fluentd)
- 节点监控Agent(如Node Exporter)
- 网络组件(如CNI插件)
DaemonSet确保每个节点运行一个Pod,通常用于基础设施服务。
检查是否有节点选择器、污点、以及是否有足够用的资源
- Deployment:主要用于无状态应用,Pod可任意扩展、缩减,无严格顺序要求。
- StatefulSet:主要用于有状态的服务,Pod具有稳定的标识(网络、存储),Pod启动和销毁严格按照顺序进行(如数据库)。
- DaemonSet:主要部署监控软件、收集日志的(或者需要在每一个节点部署一个pod)
高级资源是用来管理pod的,是用不同的方式创建和管理pod
Service是K8s开箱即用的一个用于提供负载均衡、服务发现等能力的资源。
主要功能:
- 服务之间的服务发现
- 代理一个或一组Pod
- 代理IP或域名
- ClusterIP(默认):在集群内访问服务,不对外暴露。
- NodePort:通过节点IP和静态端口对外暴露服务(适合测试或临时访问)。
- LoadBalancer:结合云服务提供商的负载均衡器,直接对外提供服务。
- ExternalName:通过DNS别名映射到外部服务。
Ingress为K8s集群中的服务提供了一个统一的入口,可以提供负载均衡、SSL终止和基于名称(域名)的虚拟主机、应用的灰度发布等功能,在生产环境中常用的Ingress控制器有Treafik、Nginx、HAProxy、Istio等。
相对于Service,Ingress工作在七层(部分Ingress控制支持2和6层),所以可以支持HTTP协议的代理,也就是基于域名的匹配规则。
404 表示访问的路由不存在,通常问题如下:
- Ingress 路径配置的不正确
- Ingress 的配置未被 Controller 解析
- 未使用正确的域名和路径访问
- 代理的服务没有该路径
- 请求的方法不同
413(Request Entity Too Large)报错
有时候需要上传一些大文件给程序,但是 nginx 默认允许的最大文件大小只有 8M,不足以满足生产最大上传需求,此时可以通过 nginx.ingress.kubernetes.io/proxy-body-size 参数进行更改(也可以在 ConfigMap 中全局添加):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
namespace: study-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 32m
spec:
....
503 一般是代理的服务不可用导致的,通常问题如下:
- Ingress 代理配置错误,比如 Service 名字或端口写错
- Ingress 代理的 Service 不存在
- Ingress 代理的 Service 后端 Pod 不正常
504 一般是代理的服务处理请求的时间过长,导致 Nginx 等待超时,此时需要确认服务的处
理时长,或者查看服务是否有问题
CORS 跨域报错:CORS错误。说明被跨域给拦截了,可以添加跨域配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: longtime
namespace: study-ingress
annotations:
# 允许跨域的请求方法
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST,OPTIONS, DELETE"
# 允许携带的请求头
nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, Xapp123-XPTO"
# 允许跨域的域名
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
spec:
....
在k8s中会找到三台或者两台的机器通过Ingress来部署Controller,仅仅部署我们Controller一个pod,不会部署其他的业务pod。
前面有个LB(DMZ、F5等)对外发布的,可以被用户直接访问到
域名 --> LB --> Controller(80/443)
Ingress Controller接收Ingress资源定义的HTTP(S)规则,根据Host、路径(path)等将外部请求路由到不同的Service上。常用的Ingress Controller有NGINX、Traefik、HAProxy、Envoy等。
- Ingress相当于控制器的配置文件,在Ingress中指定路由信息,会被Controller解析为自己的配置文件
- Ingress是k8s的一类资源,而Controller可以是不同的工具
- Ingress仅实现外部到集群服务的HTTP(s)流量入口路由
- Service Mesh则覆盖服务间通信,包括流量管理、服务发现、负载均衡、熔断、监控、认证等更全面的能力。
NetworkPolicy通过label选择Pod,基于Ingress/Egress规则定义允许或拒绝Pod间网络访问,配合网络插件(如Calico)实现网络隔离策略。
示例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
以上规则将禁止namespace内所有Pod的进出流量。
Sidecar是指在Pod中使用辅助容器,增强主容器功能。典型例子:Istio中Envoy代理作为Sidecar,实现流量管理、安全策略、监控等功能。
- Secret以Base64编码存储在etcd中。
- 生产环境中应启用etcd加密。
- RBAC限制访问Secret的权限。
- 使用第三方密钥管理系统(如Vault)更安全。
- ConfigMap:存储明文非敏感配置,如环境变量、配置文件等。
- Secret:存储加密的敏感信息,如密码、Token和证书。
- emptyDir:生命周期跟随Pod,仅适合临时存储。
- hostPath:挂载节点文件系统,可能有安全风险。
- PersistentVolumeClaim (PVC):与PersistentVolume关联的持久化存储卷。
- configMap与secret:挂载配置或敏感数据。
- Downward API:元数据挂载,主要用于容器访问pod的一些元数据,比如标签、命名空间等
- Volume:Pod 内部的存储抽象,用于容器间共享数据(如日志目录)或临时存储(如 emptyDir)。生命周期与 Pod 强绑定,Pod 删除则数据销毁,无法跨节点持久化
- PV:集群管理员配置的持久化存储资源(如云磁盘/NFS),独立于 Pod 生命周期,属于集群级别资源
- PVC:用户对存储资源的申请,PVC绑定到合适的PV上供Pod使用
CSI(Container Storage Interface)是一种标准接口,用于将各种存储系统连接到Kubernetes。通过CSI插件,用户可以使用任意外部存储系统,如Ceph、NFS、AWS EBS、阿里云盘等。
StorageClass用于定义存储资源的类别,并且与存储插件或Provisioner相关联。CSI提供里一个标准化的接口,用于集成外部存储系统》CSI和StorageClass一般会协同工作进而提供对动态存储对支持。
- PVC一直Pending的原因
- PVC的空间申请大小大于PV的大小
- PVC的StorageClassName没有和PV的一致
- PVC的accessModes和PV的不一致
- 请求的PV已被其他的PVC绑定
- 挂载的PVC的Pod一直Pending的原因
- PVC没有创建成功/PVC不存在
- PVC和Pod不住同一个Namespace
- Provisioning(创建)
- 静态创建(Static Provisioning)
- 管理员预先创建 PV,定义存储容量、访问模式和存储介质。
- 动态创建(Dynamic Provisioning)
- 用户提交 PVC (PersistentVolumeClaim) 时,动态创建 PV。
- 需要使用 StorageClass 来定义存储配置和创建规则。
- Binding(绑定)
- 当用户创建 PersistentVolumeClaim (PVC) 时,Kubernetes 会根据 PVC 指定的要求(容量、访问模式、存储类别)寻找合适的 PV 并绑定。
- PV 与 PVC 一旦绑定,进入 Bound 状态,两者形成一对一绑定关系。
- Using(使用)
- PV 绑定到 PVC 后,Pod 可通过 PVC 挂载并使用存储。
- PV 在 Bound 状态期间持续提供存储服务。
- Releasing(释放)
- 用户删除 PVC 后,对应的 PV 状态会变成 Released。
- 此时数据依旧存在,但无法再被其他 PVC 使用,等待管理员处理。
- Reclaiming(回收策略)
PV 的回收策略(Reclaim Policy)决定 PV 被释放后的行为。可选的策略包括:
策略 | 说明 | 场景举例 |
---|---|---|
Retain | 保留 PV 和其上的数据,管理员手动清理 | 数据保护场景 |
Recycle(已废弃) | 删除数据,清空 PV,回收再利用(K8s 1.23起已移除) | 已废弃,不再使用 |
Delete | 删除 PV 和后端存储的数据 | 临时数据或非关键场景 |
- 推荐策略:
- 对于关键数据或生产环境:使用 Retain,数据由管理员人工处理。
- 对于临时数据:使用 Delete,PV 和数据会自动清理。
- 规则类型
- 硬亲和性(Required) :必须满足的条件
- 软亲和性(Preferred) :优先但不强制
- 应用场景
- 硬件定向调度:如SSD存储节点
- 多区域高可用:强制Pod分散在多个区域
亲和性与反亲和性通过节点亲和性(NodeAffinity)
和Pod亲和性(PodAffinity/PodAntiAffinity)
实现。
- 亲和性(Affinity):允许Pod根据节点或其他Pod的特征调度在特定节点。
- 反亲和性(Anti-affinity):防止Pod被调度到具有特定特征的节点或与其他Pod位于同一节点。
使用nodeAffinity
指定Pod倾向于部署到特定节点,而PodAntiAffinity则避免多个相似Pod集中在同一节点上,增强容灾能力。
通常会部署多个副本,并且使用亲和力或者其他策略让服务尽量部署至不同的节点
使用拓扑域划分不同的可用域,然后使用亲和力尽量把服务分散开,同时根据需求优先调度某些节点。
先去配置一个节点亲和力,选择subnet。
1、使用requiredDuringSchedulingIgnoredDuringExecution/preferredDuringSchedulingIgnoredDuringExecution,分散使用NodeAffinity;如果副本数大于拓扑域,就只能使用preferredDuringSchedulingIgnoredDuringExecution,否则多余的pod会处于 Pending 状态
2、使用 preferredDuringSchedulingIgnoredDuringExecution + podAntiAffinity ,会优先(但不强制)将5个副本分散到不同节点(基于topologyKey),且仅选择带subnet标签的节点部署,若节点不足则允许共存
- 污点是应用与节点的一种属性,用于排斥某些Pod。节点上的污点会阻止任何没有相应容忍的Pod调度到该节点上。
- 容忍是应用与Pod的一种属性,允许Pod被调度到具有特定污点的节点上,通过在Pod的规范中添加容忍,Pod可以忽略节点上的污点。
首先根据节点划分标签组,之后根据标签配置污点,最后给不同租户添加不同的节点选择器和容忍。
故障隔离、故障恢复、资源隔离、专用节点隔离、多租户多环境隔离、节点平滑维护与下线等。
- NoSchedule:禁止调度Pod到该节点上,但是已经运行在该节点到服务不受影响。适用于资源隔离和节点维护的场景。
- NoExecute:禁止调度Pod到该节点上,同时已经运行在该节点上的Pod也会被驱逐(终止并重新调度)。适用于节点故障、紧急维护和故障快速恢复的场景。
- PreferNoSchedule:类似于NoSchedule。但不是一个硬性限制,调度器会尽量避免将新的Pod调度到这个节点上,但如果其他节点都不满足条件,Pod仍然会被调度到这个节点上。适用于软性资源隔离的场景。
机制 | 调度方向 | 适用场景 |
---|---|---|
污点与容忍 | 节点排斥 | Pod节点隔离、专用资源池 |
节点亲和性 | Pod主动选择节点 | 定向调度、负载均衡优化 |
协作示例:
- 使用亲和性优先选择GPU节点。
- 通过污点限制仅容忍的Pod可调度。
imagePullPolicy
有哪些可选值,意义是什么?在 Kubernetes 中,imagePullPolicy
有以下三个可选值:
- Always
latest
标签镜像(默认策略)。- 镜像频繁更新,确保总能拉到最新版本。
- 含义:每次启动容器时,总是尝试重新拉取镜像,即使本地已存在该镜像。
- IfNotPresent
- 使用固定版本号(例如:
myapp:v1.0.1
)的镜像。- 降低镜像拉取频率,加速 Pod 启动。
- 含义:只有当本地不存在指定镜像时才会去远程仓库拉取镜像。
- Never
- 离线环境或镜像提前加载到节点本地的情况。
- 确保严格控制镜像来源,不允许从远程仓库获取。
- 含义:永远不会主动去拉取镜像,必须使用本地已存在的镜像。
- 默认规则:
- 当镜像标签为
latest
时,默认值为:Always。- 当镜像标签不是
latest
时,默认值为:IfNotPresent。
- latest标签不明确,难以跟踪版本。
- latest镜像变化频繁,可能出现不可控的行为。
- 影响滚动升级和回滚机制。
通过在Pod中定义resources
字段的requests
(申请)和limits
(限制),如CPU、内存等,防止资源争用或失控。
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
名称 | 定义 | 使用场景 |
---|---|---|
ResourceQuota | 资源限制、LimitRange资源使用范围及默认值、QoS服务质量 | 用于在多租户环境下为命名空间设置资源总量限制,避免某个租户过度使用资源 |
LimitRange | 可以确保命名空间内的Pod有合理的资源请求和限制范围,避免不合理的配置 | 规范配置:避免容器内存超限崩溃;自动填充未声明的资源请求值 |
QoS | 用于根据Pod的资源配置确定其在资源紧张的优先级,确保关键任务的Pod能够获得资源 | 保障核心业务 |
- Guaranteed:设置相同的requests和limits,保证资源。
- Burstable:requests < limits,可能资源被限制或驱逐。
- BestEffort:没有设置requests和limits,资源最低保证。
每个空间都需要限制Pod和RS的资源,之后根据需要限制内存和CPU。
根据实际情况配置、适当超分、重要服务采用 Guaranteed 级别的服务
- 超过内存(limits):Pod会被OOMKilled,容器自动重启。
- 超过CPU(limits):Pod被CPU限流(CPU被throttle),性能受限,但不会被驱逐或杀掉。
- 节点资源不足(CPU/内存压力)
- 节点维护(kubectl drain操作)
- Pod违反QoS策略(超出内存limits)
- 节点NotReady、宕机等异常状态
- readinessProbe:避免流量被转发到未就绪Pod。
- livenessProbe:自动重启异常Pod,提高服务可用性。
- Liveness探针:确定容器是否存活,失败时重启容器。
- Readiness探针:容器是否准备好接受流量,未就绪时不会接收请求。
- Startup探针:用于慢启动应用,确保启动完成前不触发其他探针,以防止误判重启。
- Exec:执行命令,成功返回0则探测成功。
- HTTPGet:通过HTTP请求健康检查。
- TCPSocket:通过TCP端口检查容器是否正常运行。
- 使用kubectl cordon标记节点为不可调度。
- 使用taint与toleration实现节点级别Pod调度控制。
kubectl taint nodes node01 key=value:NoSchedule
- 节点资源充足性(CPU/内存)
- 节点亲和性与反亲和性
- 污点(taint)和容忍度(toleration)
- 自定义调度策略(调度扩展器)
RBAC通过Role定义资源操作权限,通过RoleBinding将权限绑定给用户或ServiceAccount。ClusterRole与ClusterRoleBinding用于跨Namespace的权限定义。
注意:RBAC只具备添加权限,不具备拒绝权限
RBAC授权模式分为 Roles 和 Bindings 两种组件:
- Roles:用于定义相关权限
- Bindings:用于把权限绑定至相关主体,比如用户和组
- Role:命名空间级别的权限,权限规则仅限于命名空间内
- ClusterRole:集群级别的权限,权限规则覆盖整个集群,同时可以绑定到某个空间内
- RoleBindings:将 Role 或者 ClusterRole 的权限绑定到用户、组或服务账户,并指定到某个空间内,绑定后用户只具备该空间的相关权限
- ClusterRoleBindings:将 ClusterRole 绑定到用户、组或服务账户,绑定后用户具备集群的相关权限
Helm是K8s的包管理器,类似于Linux上的apt或yum,可以用包的形式工程化管理和部署复杂的k8S应用程序,比如一键安装zookeeper集群、一键部署整个项目等。
- Helm:Helm的管理工具
- Chart:Helm的包,是一个包含K8s资源定义的安装文件包
- Release:Helm每次部署会产生一个 Release ,可以用于回滚等
- Repository:Helm Chart存储库,用于存储和分发Chart
- 资源管理:Helm Chart是一组预定义的YAML文件,描述了K8s应用程序的各个组件配置与模板
- 版本控制:Helm支持版本控制,可以轻松回滚到之前的版本
- 依赖管理:Chart可以声明依赖关系,Helm可以自动解析并安装这些依赖
- 模板化:Charts可以使用Go的模板语言,动态生成资源文件
Operator是一种用于扩展K8s API的自定义控制器,可以实现在原生资源对象上进行自定义资源类型。通过Operator,也可以实现将复杂的任务转化对K8s资源的操作,让应用程序的管理和维护更加简单和规范。
- 简化复杂应用的管理:像管理K8s资源一样管理复杂的系统
- 一致性操作:通过资源定义决定行为,各个环境可以统一配置
- 扩展集群能力:自定义资源类型,扩展集群的调度能力
- CRD:Operator使用k8s的CRD来定义新的资源类型,新的类型可像核心资源被管理,比如定义一个叫做Database的CRD,可以用于一键启动一个数据库实例。
- Controller:Operator控制器,该控制器监视自定义资源的状态,并根据用户的配置自动执行相应的操作,比如创建一个数据库,执行一次备份任务等。
- Helm:
- 适合简单的应用程序或微服务,尤其是那些不需要复杂运维任务的应用
- 开发简单,无需深入了解开发知识
- Operator:
- 适合复杂的应用程序(如数据库、消息队列、缓存系统等),除部署外,也需要一些额外任务的应用,比如备份等
- 开发稍微复杂,需要了解相关开发知识
HPA是指K8s水平Pod自动扩缩容,是一个K8s原生的自动化伸缩工具。主要用于根据服务的度量指标(如CPU使用率、内存使用率或其他自定义指标)自动调整服务的副本。
HPA可以通过增加或减少工作负载的副本数来确保应用程序能够处理当前的流量和负载,同时避免资源浪费。
- 必须安装metrics-server或其他自定义metrics-server
- 必须配置requests参数
- 不能扩容无法缩容的对象,比如DaemonSet
- Pod级:HPA,根据CPU、内存等指标自动扩缩容。也可根据自定义指标或外部指标进行扩缩容,如队列长度或HTTP请求数。
- 节点级:Cluster Autoscaler,根据资源不足自动增加或减少节点。
ECK是Elastic官方提供的Kubernetes Operator,用于简化在Kubernetes环境中部署、管理和扩展Elastic Stack的全方位组件。
- Elasticsearch:用于管理和部署Elasticsearch集群
- Kibana:用于管理和部署Kibana服务
- Beat:用于管理和部署Beat服务
- Logstash:用于管理和部署Logstash服务
- 多维数据模型:Prometheus的数据采用时间序列数据进行存储,可以通过指标名称和标签进行检索、分组、过滤和聚合
- 灵活的查询语法:使用PromQL语法可以查询和聚合数据,可用于绘制图表或触发告警
- 存储简化:Prometheus本身就是一个时序数据库,可以提供本地存储和分布式存储,并且每个Prometheus都是自治和独立的
- 拉取模型:Prometheus通过基于HTTP的Pull的模式,定期从配置的目标中拉取应用程序暴露Metrics数据,同时可以使用PushGateway进行Push数据
- 动态发现:Prometheus同时支持动态服务发现和静态配置发现监控目标
- 告警通知:Prometheus支持告警规则的多级配置,并支持通知到多种媒介
- 完善仪表盘:Prometheus具备多种图形和仪表盘支持,同时可以使用Grafana等工具创建丰富等可视化界面
- 安装
- Operator
- Prometheus:用于定义 Prometheus Server 实例
- Alertmanager:用于定义 Alertmanager 实例
- Grafana
- 监控
- ServiceMonitor:用于定义获取监控数据的目标,Operator 根据 ServiceMonitor 自动生成 Prometheus 配置
- Probe:用于定义静态目标,通常和 BlackBox Exporter 配合使用
- PodMonitor:用于监控一组动态的Pod,PodMonitor对象负责发现一些符合规范的Pod,并生成 Prometheus 配置来进行监控
- ScrapeConfig:用于自定义监控目标,通常用于抓取K8s集群外部的目标数据
- 告警
- PrometheusRule:用于定义告警规则
- 通知
- AlertmanagerConfig:用于定义 Alertmanager 实例
- 数据模型和查询语言:Zabbix使用关系型数据库来存储数据,Prometheus采用的是TSDB的时间序列数据库。TSDB使用一种称为WAL的写前日志,以确保数据的可靠性。Prometheus是支持外部数据库存储的。
- 自动化和配置管理:Prometheus具有自动化和自动配置的能力,它可以自动发现服务和指标,并对它们进行监控。Zabbix也提供了类似的功能,但需要手动配置。
- 可视化和警报:Zabbix和Prometheus都支持可视化和警报功能。Zabbix提供了一个基于Web的前端界面,可以查看监控数据和设置警报。Prometheus通常与Grafana等工具一起使用,以实现更高级的可视化和警报功能。
- 性能和扩展性:Prometheus在性能和扩展性方面表现良好,能够处理大规模的时间序列数据。Zabbix也具有良好的性能和扩展性,但在大规模监控方面可能需要更多的资源和配置。
- zabbix 更加适合用于 本地计算机 的监控,而 Prometheus 更适合在现在流行的 云计算 监控上使用。
- 快速定位故障点
- 快速定位性能依赖关系
- 理解服务依赖关系
- 全局流量可视化
1、客户端发起请求
2、服务A开始处理请求并创建初始Trace和Span
3、服务A将请求转发给服务B,同时传递 race ID 和 Span ID
4、服务B根据传递的信息继续创建新的Span,并标记父Span
5、所有服务处理完成后,各自产生的Span数据都会发送至追踪平台进行汇总
6、用户可以通过UI查看整个Trace的详细信息
Skywalking是一个针对分布式系统的应用性能监控和可观测性分析平台。Skywalking提供了包括分布式追踪、指标监控、故障诊断信息、服务网格遥测分析、异常告警以及可视化界面等功能,可帮助开发人员和运维团队更好地理解和管理应用和服务。
核心特性:
- 分布式追踪:Skywalking可以为请求生成跟踪数据,能够帮助用户了解整个调用链路的情况,从而定位性能瓶颈或问题根源
- 度量分析:支持对服务的健康状况进行度量分析,如响应时间、吞吐量、成功率等关键性能指标(KPI)
- 告警机制:支持自定义规则告警,当检测到异常情况时自动发送告警通知
- 丰富的UI界面:提供了直观易用的Web UI,方便用户查看追踪数据、监控指标及服务拓扑结构等
- 低侵入性:通过字节码注入的方式实现代码级别的监控,无需修改业务逻辑即可完成接入
- 多语言支持:除了Java之外,还支持.NET Core、Node.js、Python、Go等多种编程语言,满足不同开发环境的需求
- 多平台集成:支持与服务网格、Kubernetes集成
- Service:Service指的是一个或一组提供相同功能或业务逻辑的应用。可以是一个微服务、一个web服务、一个数据库或者其他类型的后端服务
- Instance:Instance是指服务的一个具体运行实例。在一个分布式环境种,同一个服务可能部署在多个不同的服务器或者容器上,每个容器或服务器上的这个服务就是一个Instance
- Endpoint:Endpoint是指服务中可被外部访问的具体路径或接口,端点是服务对外暴露功能的入口点
Service Mesh(服务网格)的目标为解决微服务之间复杂的链路关系。
Service Mesh将程序开发的网络功能和程序本身解耦,网络功能下沉到基础架构,由服务网格实现服务之间的负载均衡等功能,并且除网络功能外,也提供了其他更高级的功能,比如全链路加密、监控、链路追踪等。
- 负载均衡
- 服务发现
- 熔断降级
- 动态路由
- 故障注入
- 错误重试
- 安全通信
- 语言无关
Istio是一个开源的服务网格(Service Mesh)产品,专为微服务架构设计,用于透明地管理服务间通信、安全、监控和流量策略。
Istio通过Sidecar拦截并控制服务间的所有流量,将复杂的微服务治理(如流量管理、安全策略)从业务代码中剥离,并下沉到基础设施层,使开发者更专注于业务逻辑,以提升开发效率。
Istio几乎无需修改任何代码就可以实现如下功能:
- 双向TLS加密
- HTTP、gRPC、WebSocket和TCP流量的自动负载均衡
- 错误重试、故障转移和故障注入等
- 访问控制、限流、认证、鉴权等
- 可观测性指标、链路追踪、日志等
- 集群内入口和出口的流量管理
Istio从逻辑上分数据平面和控制平面:
- 控制平面:Control Plane负责管理和配置数据平面的流量策略,由管理员创建的Istio资源会解析成相关的配置下发到数据平面
- 数据平面:Data Plane负责拦截并处理所有入站(Inbound)和出站(Outbound)流量,用来执行由控制平台下发的策略,比如路由、负载均衡、重试、熔断、TLS加密等,同时数据平台还可以收集流量目标、日志和追踪数据,并发送给监控系统。
- Sidecar模式:此模式会为集群中启动的每个pod都部署一个Envoy代理,或者为在虚拟机上运行的服务运行一个Envoy代理
- Ambient模式:此模式在每个节点上启动一个四层代理,也可以为每个命名空间启动一个Envoy代理实现七层功能(1.22版本之后新加入的)
对比项 | 对比维度 | Sidecar模式 | Ambient模式 |
核心架构 | |||
代理部署方式 | 每个Pod注入一个Envoy Sidecar容器 | 分层部署: L4:每个阶段部署一个Ztunnel代理 L7:每个空间部署一个或多个Waypoint代理 |
|
流量管理 | 通过iptables/IPVS规则劫持Pod的进出流量 | 四层由Ztunnel处理,七层由Waypoint处理 | |
覆盖范围 | 所有注入Sidecar的Pod | 默认纳入所有Pod,无需添加任何注解 | |
故障可用性 | 只影响某个故障的Pod | 影响当前节点或当前空间下的所有服务 | |
资源开销 | |||
代理数量 | 每一个Pod一个Envoy | Ztunnel:每一个节点一个代理 Waypoint:通常每个命名空间一个或多个 |
|
内存/CPU消耗 | 较高 | 较低 | |
启动延迟 | Pod启动需等待Sidecar就绪 | Pod启动无需等待代理,延迟更低 | |
性能对比 | 调用延迟 | 每个请求经过两次Ztunnel代理 | L4经过Ztunnel,L7经过由Waypoint,可能更多 |
- DestinationRule:定义服务子集和流量策略,路由的最终目标。
- 版本划分:根据标签划分同一个服务的不同版本
- 负载均衡策略:支持配置各种负载均衡算法(如轮询、随机、最少连接)
- 熔断器:支持配置最大连接数、熔断等
- VirtualService:路由规则的核心,控制流量去向。
- 灰度发布:支持基于比例的流量分配
- A/B测试:支持基于请求头、URI、权重等条件的流量分配
- 重试:支持错误重试、故障注入、链接超时等策略
- Gateway:管理外部流量入口和出口,与VirtualService协同实现内外流量统一治理
- 端口监听:可根据协议指定对外暴露的端口
- TLS:可以添加域名证书提供http访问
- 域名:可以根据域名进行路由分发
- 出口管控:可以将出口的流量固定从EgressGateway的服务中代理出去
- Pod调度失败排查:从资源、标签、污点、存储等多维度入手。
- DaemonSet使用场景:节点级守护进程,如日志、监控插件。
- 污点与容忍:实现节点隔离,需谨慎使用
NoExecute
。- 节点亲和性:结合硬性规则和软性权重,优化调度分布。