运维常见题-云原生基础
DeepSeek V4 Flash 辅助生成。为确保内容的可靠性,笔者已对大部分关键论点进行了人工复核与校验。但鉴于大模型的固有局限,本文仍可能存在认知偏差或未尽准确之处。若您在阅读中发现存疑或矛盾之处,欢迎反馈讨论,笔者将及时核实与修正。🤔 云原生是什么?你是什么理解的?
云原生(Cloud Native)是"以云为设计目标"的应用构建与运行方式:应用生来为云而设计(微服务化、容器化、动态编排),充分利用云的弹性、分布式与自动化能力,而非"把传统应用搬到云上"。核心要素:容器化、微服务、
DevOps、持续交付、可观测性,以CNCF生态(K8s等)为实现底座。什么是云原生(定义)
- 云原生是一种设计理念 + 技术栈 + 交付模式:应用从架构设计到部署运维都围绕云的能力展开
- 关键区别:不是"上云"(把应用搬到云服务器),而是"生于云"(应用按云的特性设计)
- 官方定义参考:
CNCF定义云原生技术为"让组织在公有云、私有云、混合云等动态环境中构建和运行可扩展应用的技术",使应用具备松散耦合、韧性、可管理、可观测特性
云原生核心要素(
CNCF官方示例技术)- 容器:应用打包成容器(镜像),标准化运行环境、可移植
- 微服务:应用拆分为小型独立服务,独立开发部署扩展
- 服务网格:流量管理/安全/观测下沉到
Sidecar(Istio等) - 不可变基础设施:服务器不可变(镜像重建而非打补丁)
- 声明式 API:用声明式配置描述期望状态,系统自愈(
K8s控制器) - 注:“容器化、微服务、
DevOps、持续交付"四要素是国内流传说法,CNCF官方定义未将DevOps/持续交付列为要素,表述时应注明出处
云原生的关键特性
- 弹性:按负载自动扩缩容(
K8sHPA),资源按需使用 - 不可变基础设施:服务器不可变(用镜像重建而非打补丁)
- 声明式管理:用声明式配置(YAML)描述期望状态,系统自愈(
K8s控制器) - 可观测性:Metrics/Logs/
Traces 三支柱 - 自动化:部署/扩展/故障恢复全部自动化
- (这些特性源自
CNCF定义;12-Factor 是应用设计准则,是另一套参考)
- 弹性:按负载自动扩缩容(
云原生技术生态(
CNCF全景)- 容器:
Docker、containerd - 编排:
Kubernetes(K8s) - 服务网格:
Istio、Linkerd - 可观测性:
Prometheus、Grafana、OpenTelemetry、SkyWalking - 交付:
GitOps(Argo CD)、CI/CD(Jenkins/GitLab CI) - Serverless:
Knative、FaaS
- 容器:
运维视角理解
- 云原生对运维是"范式转变”:从"管理服务器"到"管理集群/声明式配置",从"人工运维"到"自动化+自愈",从"监控"到"可观测性"
- 核心能力:
K8s集群运维、容器安全、可观测性平台、GitOps流程
协助记忆
- 云原生 = “为云而生的应用”:容器打包、微服务拆分、
K8s编排、自动伸缩、声明式自愈。 - 四要素口诀:“容器、微服务、
DevOps、持续交付”。
- 云原生 = “为云而生的应用”:容器打包、微服务拆分、
进阶思考
- 云原生和"上云"有什么区别?
- 上云:把现有应用部署到云服务器(还是单体/传统部署方式,只是换机房)。云原生:按云特性重新设计应用(微服务化、容器化、弹性、自动化)——上云是"搬家",云原生是"重新设计"。
- 为什么说
K8s是云原生的"底座"?K8s提供了容器编排的"操作系统能力":调度、弹性伸缩、自愈、服务发现、滚动发布。云原生的声明式管理、弹性、自动化都依赖它。没有K8s,微服务/容器很难大规模管理。
- 云原生是"银弹"吗?有什么代价?
- 不是。云原生带来弹性/效率,但也引入复杂度:学习曲线陡(
K8s/服务网格)、基础设施复杂、运维门槛高、小项目可能过度设计。“不上云原生也能做好业务,上了云原生可能更复杂”——按需选择。
- 不是。云原生带来弹性/效率,但也引入复杂度:学习曲线陡(
- 云原生和"上云"有什么区别?
扩展信息
CNCF与云原生生态:CNCF(Cloud Native Computing Foundation)托管K8s、Prometheus、Envoy、etcd 等核心项目- 云原生全景图(Landscape):覆盖编排、存储、网络、可观测性、安全、Serverless 等
- 12 要素(12-Factor App):
- 代码库、依赖、配置、后端服务、构建发布运行分离、进程、端口绑定、并发、可处置、开发生产等价、日志、管理进程——云原生应用设计的经典准则
🤔 传统应用与云原生应用有什么区别?
传统应用与云原生应用的区别核心是"架构、部署、运维、扩展"四维差异:单体 vs 微服务、物理/VM 部署 vs 容器编排、人工运维 vs 自动化自愈、垂直扩展 vs 弹性伸缩。本质:传统应用"为运行而设计",云原生应用"为云而设计"。
架构维度
- 传统:单体/分层架构,模块间紧耦合,改一处整体重发
- 云原生:微服务/分布式架构,服务独立开发部署扩展
部署维度
- 传统:物理机/虚拟机部署,环境依赖手工配置,部署周期长(周/月)
- 云原生:容器化打包(镜像),
K8s编排,环境标准化,秒级/分钟级发布
运维维度
- 传统:人工运维(SSH 登录、手工部署/监控),故障靠人处理
- 云原生:自动化运维(声明式配置、控制器自愈),故障自动恢复(重启/重新调度)
扩展维度
- 传统:垂直扩展(加 CPU/内存),扩容慢、有上限
- 云原生:水平扩展(加副本/实例),按负载自动伸缩(
HPA),弹性
弹性与容错
- 传统:单点风险高,故障影响大
- 云原生:多副本 + 负载均衡 + 自愈,单实例故障自动替换
开发与交付
- 传统:开发运维割裂,发布频率低(版本季度/月发)
- 云原生:
DevOps+ CI/CD,持续交付(灰度/蓝绿),发布频率高(日/周)
对比速查表
维度 传统应用 云原生应用 架构 单体 微服务 部署 物理机/VM,手工配置 容器 + K8s编排运维 人工 自动化/自愈 扩展 垂直为主(加资源) 水平(加副本)+ 弹性 发布 低频(周/月) 高频(日/周)+ 灰度 故障 单点风险 自动恢复 设计理念 为运行而设计 为云而设计
协助记忆
- 对比口诀:“单体对微服务、VM 对容器、人工对自动、垂直对水平、低频对高频”。
- 本质一句话:“传统应用在机器上跑,云原生应用在云里长”。
进阶思考
- 传统应用能否"改造"成云原生?
- 能,但要渐进:①容器化(最基础,先解决环境/部署标准化)②微服务化(拆分为服务,最难)③平台化(上
K8s,自动化编排)④云原生特性(弹性/可观测/GitOps)。“先容器化、再微服务化"是主流路径,直接全拆风险大。
- 能,但要渐进:①容器化(最基础,先解决环境/部署标准化)②微服务化(拆分为服务,最难)③平台化(上
- 云原生应用一定比传统应用"性能好"吗?
- 不一定。云原生带来的是"弹性、可用性、交付效率”,不是天然性能优势(微服务化反而增加网络开销)。性能优化是另一回事。云原生的价值在"运维效率 + 扩展能力 + 可用性"。
- VM 和容器的本质区别是什么?
- VM:虚拟化硬件(每个 VM 有完整 OS),隔离强、资源开销大、启动分钟级。容器:共享宿主机内核(进程级隔离),启动秒级、密度高。云原生选择容器是因为"轻量 + 快 + 可编排"。
- 传统应用能否"改造"成云原生?
扩展信息
- 迁移路径参考:
6R策略(AWS 经典):Rehost(搬迁)、Replatform(平台化)、Refactor(重构)、Repurchase(替换为 SaaS)、Retain(保留)、Retire(退役)- 注:Relocate(区域/可用区迁移)是现行 7R 新增项,不属于经典
6R
- 云原生就绪评估:
- 应用是否适合微服务化?是否容器化?是否有自动化 CI/CD?是否可观测?是否弹性可伸缩?——评估改造优先级
- 迁移路径参考:
🤔 什么是 “不可变基础设施”?
不可变基础设施(Immutable Infrastructure)是"服务器/实例一旦创建就不修改,需要变更时销毁重建"的理念:不登录服务器打补丁/改配置(可变),而是用新镜像重建实例替换(不可变)。核心价值:一致性(环境可复现)、可预测(无漂移)、快速回滚(换旧镜像)、自动化(重建即替换)。
核心理念
- 不可变:运行的实例是"金像"(golden image)快照,运行期不修改(不打补丁、不改配置、不装软件)
- 变更方式:需要变更 → 构建新镜像 → 创建新实例 → 切换流量 → 销毁旧实例(而不是"登录修改")
- 配置从代码:配置写入镜像/配置中心,实例本身不可变
与可变基础设施(传统)对比
维度 可变基础设施 不可变基础设施 变更方式 登录服务器打补丁/改配置 重建实例替换 一致性 易漂移(环境差异) 镜像一致(可复现) 故障处理 登录修复 销毁重建(自愈) 回滚 难(改错了要逆操作) 快(切回旧镜像) 自动化 低(依赖人工) 高(重建即部署) 为什么不可变(价值)
- 一致性:所有实例从同一镜像创建,环境完全一致(消除"在我这能跑")
- 可预测:无配置漂移(不会因为历史修改导致环境差异)
- 快速回滚:新版本有问题,切回旧镜像实例即可(容器场景秒级;虚拟机镜像场景分钟级)
- 可审计:镜像版本可追溯,环境状态可复现
- 安全:无后门残留(每次重建是干净环境)
实现技术
- 容器镜像:
Docker镜像即不可变(构建后不变,重建容器) - 虚拟机模板:云厂商镜像(AMI 等)
- 编排:
K8s(Pod重建)、Packer(构建镜像)、Terraform(声明式资源)
- 容器镜像:
代价与注意
- 实例重建慢于"打补丁"(构建+创建+切换)
- 状态数据要外置(实例不可变 → 数据放外部存储/数据库)
- 需要完善的 CI/CD(镜像构建流水线)支撑
协助记忆
- 不可变基础设施 = “服务器像一次性餐具”:用完就扔(销毁重建),不反复清洗使用(不打补丁)。
- 口诀:“改配置不如换镜像,修服务器不如重建实例”。
进阶思考
- 不可变基础设施和"宠物 vs 牛"比喻是什么?
- 传统服务器像宠物(有名字、要精心维护、坏了要治);不可变基础设施像牛群(无差别、坏了直接换一头)。“宠物牛群”(
PetsvsCattle)是云原生的经典比喻,核心是"实例可抛弃、可重建"。
- 传统服务器像宠物(有名字、要精心维护、坏了要治);不可变基础设施像牛群(无差别、坏了直接换一头)。“宠物牛群”(
- 日志/数据文件怎么办(实例不可变)?
- 状态外置:数据存数据库/对象存储,日志推送到集中日志系统,实例内只放无状态应用代码。这也呼应了"无状态应用"设计——实例可以随时销毁重建而不丢数据。
- 不可变基础设施和配置管理(
Ansible)冲突吗?- 不冲突,是演进:
Ansible是"可变时代"的工具(登录配置);不可变基础设施用"镜像构建"(Packer/CI)替代运行时配置。但Ansible仍用于"构建镜像阶段"和"管理集群基础设施"(K8s节点、网络)。
- 不冲突,是演进:
- 不可变基础设施和"宠物 vs 牛"比喻是什么?
扩展信息
- 相关概念:
- 金像(Golden Image):标准化的基础镜像模板
- 宠物 vs 牛(
PetsvsCattle):服务器可抛弃理念 - 蓝绿部署/滚动部署:不可变基础设施的发布模式
- 工具链:
- 镜像构建:
Packer、DockerBuild、Kaniko - 编排重建:
K8s(Deployment/Rollout)、云 ASG(Auto Scaling Group) - 声明式管理:
Terraform、K8s清单
- 镜像构建:
- 相关概念:
🤔 云原生应用架构涉及到哪些技术?
云原生技术栈按层覆盖"容器与编排 + 服务治理 + 交付 + 可观测 + 安全 + 存储":容器(
Docker/containerd)→ 编排(K8s)→ 服务网格(Istio)→ 注册/配置/网关 → CI/CD +GitOps→ 可观测(Prometheus/OTel)→ 安全(扫描/策略/运行时)→ 存储(CSI/分布式存储)。核心是K8s生态。容器与编排层(底座)
- 容器运行时:
containerd、CRI-O(注:K8s1.24 起移除 dockershim,Docker不再是CRI原生运行时,需cri-dockerd桥接) - 编排调度:
Kubernetes(K8s)——自动部署/扩缩/自愈 - 容器网络:
CNI(Calico、Flannel、Cilium) - 容器存储:
CSI(Rook部署Ceph+ ceph-csi、Longhorn、云盘)
- 容器运行时:
微服务与服务治理层
- 注册中心:
Nacos、Consul - 配置中心:
Nacos、Apollo - 网关:
Kong、APISIX、Spring Cloud Gateway - 服务网格:
Istio、Linkerd(流量管理/安全/观测下沉到Sidecar;Envoy是数据面代理,网格需含控制面)
- 注册中心:
交付与发布层
- CI/CD:
Jenkins、GitLab CI、GitHub Actions GitOps:Argo CD、Flux- 镜像仓库:Harbor、
DockerHub - 发布策略:蓝绿、灰度(金丝雀)、滚动
- CI/CD:
可观测性层
- 监控:
Prometheus+Grafana - 日志:
Loki、ELK - 链路:
SkyWalking、Jaeger(注:Jaeger已转向OpenTelemetry,v2 基于OTelCollector)、Zipkin - 统一标准:
OpenTelemetry(OTel)
- 监控:
安全层
- 镜像安全:
Trivy、Clair(扫描漏洞) - 策略:OPA
Gatekeeper、Kyverno(准入控制) - 运行时:
Falco(行为检测)、Seccomp/AppArmor(内核安全机制) - 密钥管理:KMS、Vault、
External Secrets
- 镜像安全:
Serverless 与边缘
FaaS:云厂商函数计算(Lambda/函数计算);Knative是容器级 Serverless 平台(scale-to-zero,非严格FaaS)- 边缘:K3s、边缘计算平台
技术栈选型逻辑
- 核心必备:
K8s+ 容器 + CI/CD +Prometheus(四件套) - 进阶:服务网格(
Istio)、GitOps(Argo CD)、Serverless - 按需:有状态应用加
CSI存储、安全要求高加策略引擎
- 核心必备:
协助记忆
- 技术栈分层:“容器编排(
K8s)、服务治理(Nacos/Istio)、交付(CI/CD/GitOps)、可观测(Prometheus/OTel)、安全(Trivy/Falco)"。 - 核心四件套:"
K8s+ 容器 + CI/CD +Prometheus"。
- 技术栈分层:“容器编排(
进阶思考
K8s生态里CNI/CSI/CRI是什么?CRI(容器运行时接口):K8s与容器运行时交互的标准(containerd/CRI-O);CNI(容器网络接口):容器网络插件标准(Calico/Cilium);CSI(容器存储接口):存储插件标准(云盘/NFS/分布式存储)。三者是K8s扩展性的关键接口。
- 服务网格(
Istio)在技术栈里解决什么?- 把流量管理(路由/灰度)、安全(
mTLS)、可观测(指标/追踪)下沉到Sidecar代理,业务代码零侵入——解决多语言、多框架的治理统一问题。适合大型/多语言系统,小型系统可不上。
- 把流量管理(路由/灰度)、安全(
- 为什么
GitOps是云原生交付的趋势?- Git 作为"唯一事实源”(声明式描述期望状态),变更走 Git 流程(评审/审批/审计),自动化同步到集群(
Argo CD)。对比传统 CI/CD:更可审计、可回滚、可复现,符合"基础设施即代码 + 声明式"理念。
- Git 作为"唯一事实源”(声明式描述期望状态),变更走 Git 流程(评审/审批/审计),自动化同步到集群(
扩展信息
CNCF核心项目分类:- 编排:
K8s、etcd;服务网格:Istio、Linkerd、Envoy;可观测:Prometheus、OTel、Jaeger;存储:Rook、Longhorn;安全:OPA、Falco;Serverless:Knative
- 编排:
- 云原生技术全景图:
- 官方 Landscape 按运行时/编排/应用/平台/可观测/安全等分类,是选型参考
- 运维入门路线:
- 先
Docker→ 再K8s→ 再Prometheus/日志 → 再GitOps/服务网格(循序渐进)
- 先
🤔 云原生应用如何实现弹性扩展和高可用性?
云原生弹性扩展靠"水平扩缩 + 自动伸缩 + 无状态设计":水平扩展(加副本)配合
K8sHPA(按 CPU/自定义指标自动伸缩)、VPA(垂直)、Cluster Autoscaler(节点伸缩);高可用靠"多副本 + 负载均衡 + 自愈 + 多可用区/多活"。核心:资源按需、故障自动恢复。弹性扩展(弹性伸缩)
- 水平扩展(Horizontal Scaling):增加/减少副本数(
Pod数量),无状态服务扩展弹性大、无架构瓶颈(但仍受集群节点容量、外部依赖连接数(DB/Redis)等约束) - 垂直扩展(Vertical Scaling):增加单实例资源(CPU/内存),有上限
- 自动伸缩(Autoscaling):
HPA(Horizontal Pod Autoscaler):按 CPU 利用率/自定义指标(QPS、延迟——自定义指标需部署 custom metrics adapter(如PrometheusAdapter)并经 metrics API 暴露)自动增减PodVPA(VerticalPodAutoscaler):按资源使用自动调整Pod资源请求(注:VPA与HPA若同时基于 CPU/内存 resource 指标会互相干扰,官方建议避免在同指标上并用)Cluster Autoscaler:按集群资源需求自动增减节点KEDA:基于事件驱动(消息队列积压等)的自动伸缩
- 水平扩展(Horizontal Scaling):增加/减少副本数(
高可用(HA)设计
- 多副本:服务多副本部署(至少 2+),单实例故障不影响
- 负载均衡:
Service/Ingress分发流量,屏蔽故障实例 - 自愈(Self-Healing):
K8s控制器检测故障自动重建(Pod重启/重新调度) - 健康检查:livenessProbe(存活,失败重启容器)/readinessProbe(就绪,失败摘除流量)——两者机制不同,配合使用
- 多可用区/多活:跨可用区部署(AZ),甚至多地域(多活),防区域故障
无状态设计(弹性前提)
- 应用实例不存状态(Session/数据外置到
Redis/数据库/对象存储) - 任意实例可被销毁重建而不丢数据(配合不可变基础设施)
- 有状态应用(数据库)用
StatefulSet+ 持久卷,弹性受限
- 应用实例不存状态(Session/数据外置到
弹性扩展实现示例(
K8sHPA)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: myapp-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: myapp minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
协助记忆
- 弹性口诀:“水平加副本(
HPA)、垂直加资源(VPA)、节点按需扩(Autoscaler)"。 - 高可用口诀:“多副本 + 负载均衡 + 自愈 + 多可用区”。
- 弹性口诀:“水平加副本(
进阶思考
HPA和Cluster Autoscaler有什么区别?HPA管”Pod数量"(应用层伸缩);Cluster Autoscaler管"节点数量"(基础设施层伸缩)。当Pod扩容但节点资源不足时,Cluster Autoscaler增加节点;缩容时回收节点。两者配合实现"应用 + 基础设施"全链路弹性。
- 为什么无状态应用才能"弹性"?
- 有状态(Session 在本地/数据在本地盘)时,实例销毁会丢数据,无法随意增减副本。无状态(状态外置)后,任意实例可随时销毁/新建,弹性才可行。所以"弹性"的前提是"无状态"。
- 高可用和容灾有什么区别?
- 高可用(HA):故障时快速恢复(同区域,多副本自动切换,秒/分钟级)。容灾(DR):灾难时恢复业务(跨区域,数据复制+切换,分钟/小时级)。云原生通常先做好 HA,再考虑跨区域容灾。
扩展信息
- 弹性扩展相关概念:
- 突发扩容(Burst):突发流量时快速加副本;缩容保护(scale-down protection)
- 资源配额(ResourceQuota)/限制范围(LimitRange):控制资源使用
- 优先级/抢占(Priority/Preemption):关键业务优先调度
- 云厂商弹性能力:
- AWS Auto Scaling、阿里云弹性伸缩(ESS)、Azure VMSS——云原生与云厂商弹性能力结合
- 弹性扩展相关概念:
🤔 微服务在设计时如何适配云原生环境?
微服务适配云原生环境的核心是"12 要素 + 容器化 + 声明式 + 可观测":配置外置(环境变量/配置中心)、无状态化、日志标准输出、进程无本地状态、通过端口绑定暴露、依赖显式声明;部署上容器化 +
K8s编排 + 可观测性接入。12 要素适配(云原生设计准则)
- 配置外置:配置不写代码(环境变量/配置中心
Nacos/Apollo),环境差异注入 - 无状态化:进程不存本地状态,状态外置(
Redis/DB/对象存储),实例可随时销毁 - 日志标准输出:日志写 stdout/stderr(容器收集),不写本地文件
- 端口绑定:应用自监听端口、不依赖外部 Web 服务器(
PORT环境变量是 Heroku 惯例,非强约束),镜像可移植 - 依赖声明:依赖(数据库/消息/缓存)显式声明,通过服务发现/配置注入
- 构建发布分离:构建产物(镜像)与运行配置分离
- 可处置性:进程可快速启停(优雅关闭 SIGTERM),支持弹性
- 配置外置:配置不写代码(环境变量/配置中心
容器化适配
- 镜像构建:多阶段构建、最小化镜像(减小体积/攻击面)
- 非 root 运行:容器内非 root 用户(安全)
- 健康检查:提供健康探针端点(/health),配合
K8s探针 - 优雅退出:处理 SIGTERM,平滑下线
K8s适配- 部署描述:
Deployment+Service+ConfigMap(声明式) - 资源声明:requests/limits(资源调度)
- 可观测接入:指标端点(
Prometheus)/日志 stdout/链路追踪 SDK - 弹性适配:无状态 + 水平扩展(
HPA)
- 部署描述:
服务治理适配
- 注册中心:
Nacos/Consul(服务发现) - 配置中心:
Nacos/Apollo(动态配置) - 网关:API 网关统一入口
- 熔断限流:Sentinel/Resilience4j
- 注册中心:
协助记忆
- 云原生适配口诀:“配置外置、状态无态、日志 stdout、端口暴露、依赖声明”。
- 一句话:“让服务像’云里的公民’——可复制、可销毁、可观测、可编排”。
进阶思考
- 为什么"日志写 stdout"是云原生要求?
- 容器/编排层统一收集 stdout(
K8s日志机制/容器日志驱动),写文件则无法统一收集、且容器销毁日志丢失。stdout 让日志随容器生命周期管理,配合集中日志系统(Loki/ELK)实现统一可观测。
- 容器/编排层统一收集 stdout(
- 优雅退出(Graceful Shutdown)为什么重要?
- 滚动更新/缩容时,旧实例被终止。若直接 kill,进行中的请求被中断(用户报错)。优雅退出:收到 SIGTERM 后停止接收新请求 → 处理完进行中请求 → 退出,保证发布/缩容不丢请求。这是
K8spreStop/terminationGracePeriod 配合应用的实现。
- 滚动更新/缩容时,旧实例被终止。若直接 kill,进行中的请求被中断(用户报错)。优雅退出:收到 SIGTERM 后停止接收新请求 → 处理完进行中请求 → 退出,保证发布/缩容不丢请求。这是
ConfigMap和Secret的区别?ConfigMap存普通配置(明文),Secret存敏感信息(密码/密钥,Base64 编码 + 可加密)。云原生微服务用它们挂载配置,或配合配置中心动态下发。
- 为什么"日志写 stdout"是云原生要求?
扩展信息
- 12 要素清单速查:
- 代码库、依赖、配置、后端服务、构建发布分离、进程、端口绑定、并发、可处置、开发生产等价、日志、管理进程
K8s健康探针:- livenessProbe(存活,失败重启)、readinessProbe(就绪,失败摘流量)、startupProbe(启动)
- 12 要素清单速查:
🤔 服务网格(Service Mesh)解决了什么问题?
服务网格(
ServiceMesh)把"服务间通信的横切关注点"从业务代码下沉到基础设施代理层(Sidecar):流量管理(路由/灰度/重试)、可观测性(指标/追踪/访问日志)、安全(mTLS加密/认证)、韧性(熔断/限流/超时)无需改业务代码即可获得。核心:非侵入式服务治理。解决的核心问题
- 服务治理与业务代码解耦:熔断/限流/重试/超时等逻辑不用写在每个服务的 SDK 里(Spring Cloud 等框架侵入代码)
- 多语言/多框架统一治理:Java/Python/Go 等不同语言的服务,治理逻辑难以统一(框架不同)
- 服务间通信安全:服务间加密(
mTLS)、认证、授权统一管理 - 可观测性统一:流量指标/调用链/访问日志自动采集(无需逐服务埋点)
- 流量精细化控制:按版本/标签路由(灰度)、流量镜像、故障注入(混沌测试)
工作原理
1 2 3 4服务 A (Sidecar) ←→ 服务 B (Sidecar) 业务容器与 Sidecar 共存于一个 Pod(Sidecar 代理拦截进出流量) 控制面(Istiod)下发配置给 Sidecar(路由/策略/证书) 数据面(Envoy Sidecar)执行转发/治理- 数据面(Data Plane):
EnvoySidecar代理,拦截并处理服务间流量 - 控制面(Control Plane):
Istiod(Istio)/控制组件,管理配置和证书下发
- 数据面(Data Plane):
三大能力(服务网格价值)
- 流量管理:请求路由(灰度/版本)、超时重试、故障注入、流量镜像
- 安全:
mTLS(服务间加密认证)、AuthorizationPolicy(授权策略,旧称 RBAC)、证书自动轮换(SPIFFE身份) - 可观测性:指标(
Prometheus)、分布式追踪(Jaeger/OTel)、访问日志 - 注:熔断/超时/重试/流量管理是网格一等能力;限流非一等公民(
Istio无一等 RateLimit API,通常需EnvoyFilter + 外部限流服务,官方标注实验性)
主流实现
- Istio:最主流,功能全(流量/安全/观测),控制面
Istiod + 数据面Envoy - Linkerd:轻量(只做服务网格核心),性能好、易运维
Consulservice mesh(HashiCorp,术语"ConsulConnect"已弃用,且官方已宣布逐步退役该产品)- 注:NGINX
ServiceMesh 已于 2023-07 停售/终止维护
- Istio:最主流,功能全(流量/安全/观测),控制面
适用场景与代价
- 适用:多语言微服务、治理需求强、需要统一安全/观测的大型系统
- 代价:每个
Pod多一个Sidecar(资源开销)、链路多一跳(延迟)、运维复杂度增加
协助记忆
- 服务网格 = “服务间的交警和保镖”:管流量(交警)、保安全(保镖)、记日志(记录仪),业务车(代码)只管开。
- 三大能力:“流量管理、安全(
mTLS)、可观测性”。
进阶思考
- 服务网格和 Spring Cloud 治理有什么区别?
- Spring Cloud(Sentinel/Hystrix 等):治理逻辑在应用 SDK 里(侵入代码、绑定语言/框架)。服务网格:治理下沉到
Sidecar(非侵入、语言无关)。两者解决的问题类似,服务网格是"更彻底的解耦",适合多语言;纯 Java 项目两者可二选一。
- Spring Cloud(Sentinel/Hystrix 等):治理逻辑在应用 SDK 里(侵入代码、绑定语言/框架)。服务网格:治理下沉到
Sidecar模式为什么是"一个Pod两个容器"?Sidecar与业务容器同Pod共享网络命名空间:Sidecar能拦截进出业务容器的流量(通过 iptables/透明代理),无需改业务代码和网络配置。这是服务网格"非侵入"的技术基础。
- 服务网格的延迟/资源代价有多大?
- 每个
Pod增加一个Sidecar容器(内存约几十 MB)+ 流量多一跳(延迟通常亚毫秒至 1~2ms 量级)。大规模下资源开销可观。所以轻量场景(单语言/小规模)可能不上网格,用框架治理更省。
- 每个
- 服务网格和 Spring Cloud 治理有什么区别?
扩展信息
- 服务网格生态:
Istio(功能全)、Linkerd(轻量)、Consulservice mesh、Kuma- 标准接口:Gateway API(SMI 规范已于 2023-09 被
CNCF归档,不再列为现行标准)
- 相关概念:
Sidecar模式:通用模式(日志采集 sidecar、代理 sidecar)- 流量镜像(Traffic Mirroring):复制流量到新版本测试(不干扰线上)
- 故障注入(Fault Injection):注入延迟/错误测试韧性(混沌工程)
- 服务网格生态:
🤔 服务网格如何进行流量管理?
服务网格流量管理靠"虚拟服务 + 目标规则 + 网关"声明式控制:
VirtualService(定义路由规则:按 Header/权重/URI 路由到不同版本)、DestinationRule(定义负载均衡/连接池/熔断)、Gateway(入口流量管理);实现灰度发布、金丝雀、蓝绿、流量镜像、超时重试熔断。核心资源(
Istio流量管理模型)VirtualService(虚拟服务):定义路由规则——请求按什么条件(Header/URI/权重)路由到哪个版本/服务DestinationRule(目标规则):定义目标服务的策略——负载均衡算法、连接池(连接数/超时)、熔断(异常点检测)、TLS- Gateway(网关):入口流量(
IngressGateway)管理——外部流量进入网格的入口 ServiceEntry(服务条目):把网格外服务纳入管理(外部依赖)
常见流量管理场景
- 灰度/金丝雀发布:按权重把部分流量切到新版本
1 2 3 4 5 6 7 8 9 10 11 12apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: myapp spec: hosts: ["myapp"] http: - route: - destination: { host: myapp, subset: v1 } weight: 90 - destination: { host: myapp, subset: v2 } weight: 10 - 按 Header 路由:特定用户(Header 带
user=test)路由到新版本(内部测试) - 超时重试:设置请求超时、失败重试次数
- 熔断:
DestinationRule配置异常点检测(连续错误触发摘除) - 流量镜像:复制线上流量到新版本(验证不影响线上)
- 故障注入:注入延迟/错误(混沌测试韧性)
- 灰度/金丝雀发布:按权重把部分流量切到新版本
流量管理与其他方式的对比
- 网关层(
Nginx/APISIX):也能做灰度(Header/比例),但只在外围 - 服务网格:服务间每一跳都能精细控制(A→B、B→C 各自策略),粒度更细
K8sService:只做简单负载均衡(无法按版本/Header 路由)
- 网关层(
入口流量(南北向)与内部流量(东西向)
- 南北向(外部→服务):
IngressGateway 管理入口流量 - 东西向(服务↔服务):
Sidecar管理内部流量(路由/策略)
- 南北向(外部→服务):
协助记忆
- 流量管理三件套:"
VirtualService(路由规则)、DestinationRule(目标策略)、Gateway(入口)"。 - 口诀:“VS 管路由,DR 管策略,Gateway 管入口”。
- 流量管理三件套:"
进阶思考
VirtualService和DestinationRule的关系是什么?VirtualService定义"怎么路由"(条件/权重 → 发到哪个 subset);DestinationRule定义"subset 是什么 + 到了之后怎么办"(负载均衡/熔断/TLS)。两者配合:VS 引用 DR 里定义的 subset(v1/v2),DR 定义 subset 的标签选择器。
- 服务网格的灰度发布和网关灰度有什么区别?
- 网关灰度只在入口做一次分流(适合"按入口"的简单场景);服务网格灰度能对服务间调用做分流(A 调 B 时按版本路由),支持更复杂的多跳灰度(如链路灰度),粒度更细。
Istio的mTLS如何保证服务间安全?- 控制面(
Istiod)自动为每个服务签发证书(SPIFFE身份),Sidecar间用mTLS加密通信并验证身份(自动轮换)。业务代码无感知,服务间通信默认加密 + 双向认证。
- 控制面(
扩展信息
Istio资源速查:VirtualService(路由)、DestinationRule(策略)、Gateway(入口)、ServiceEntry(外部服务)、Sidecar(代理配置)- 注:Gateway 资源只声明监听端口/协议,实际路由由绑定的
VirtualService完成
- 流量管理术语:
- Subset(子集:按标签分版本)、Canary(金丝雀)、Traffic Mirroring(流量镜像)、Circuit Breaker(熔断)
- 其他网格的流量管理:
Linkerd:简化模型(ServiceProfile),能力比Istio少但更易用
🤔 无服务器架构(Serverless)是什么?与云原生的关系?
无服务器架构(Serverless)是"开发者不关心服务器"的运行模型:平台按需分配/伸缩/计费资源,代码即函数(
FaaS)或容器托管(Serverless 容器),按需伸缩(FaaS/Knative可缩到零)、空闲不耗资源。它是云原生的重要形态(云原生的弹性极致化),但不是唯一形态。什么是 Serverless(定义)
- 开发者只写代码/部署函数,不管理服务器(OS、扩容、补丁由平台负责)
- 平台按请求/事件自动分配资源、自动伸缩(甚至缩到零)
- 按用量计费(按执行次数/时长,空闲不收费)
两种主要形态
FaaS(函数即服务):以函数为单位(如AWS Lambda、阿里云函数计算),事件触发,冷启动- Serverless 容器(容器级 Serverless):以容器为单位、弹性托管(如
AWS Fargate、Knative、阿里云 ASK);注意与"托管容器编排服务"(ECS/ACK/EKS,属CaaS)区分
Serverless 的特点
- 弹性极致:自动伸缩(
FaaS/Knative可缩到零;Fargate/ASK等需配置伸缩策略) - 免运维:平台管基础设施(扩容/补丁/高可用)
- 按量计费:
FaaS按执行次数/时长/请求量;容器形态(如Fargate)按 vCPU/内存*时长计费 - 事件驱动:通常由事件触发(HTTP、消息、定时、对象存储事件)
- 弹性极致:自动伸缩(
与云原生的关系
- Serverless 是云原生的一个维度:云原生是"为云设计"的理念,Serverless 是其中"免运维/极致弹性"的实现方式
- 云原生不止 Serverless:容器 +
K8s、微服务、服务网格等也是云原生 - 演进关系:容器化 →
K8s编排 → Serverless(把基础设施管理再往平台推进一步) - 两者结合:Serverless 满足云原生的"弹性、自动化、按需"特性
适用场景与局限
- 适用:函数计算(图片处理/事件处理)、弹性业务(突发流量)、微服务(部分函数化)
- 局限:冷启动延迟、不适合长时间/有状态/高吞吐计算、供应商锁定、调试难
协助记忆
- Serverless = “只写代码不管服务器”:按次收费、自动伸缩、缩到零。
- 关系口诀:“云原生是理念,Serverless 是实现之一(免运维的极致弹性)"。
进阶思考
- Serverless 是"真的没有服务器"吗?
- 不是,服务器仍然存在,只是"开发者不管理”(平台管理)。所以叫"无服务器"指"对开发者无感",而非物理无服务器。
- 冷启动(Cold Start)问题是什么?怎么缓解?
- 冷启动:函数/容器首次启动要加载运行时,延迟高(几百 ms~几秒)。缓解:预留并发(Provisioned Concurrency)、语言优化、减少依赖、预热。
- Serverless 和 Serverful(容器/
K8s)怎么选?- Serverless:适合事件驱动、突发弹性、业务简单、可接受冷启动/供应商绑定。
K8s:适合复杂应用、长连接、有状态、需精细控制、避免锁定。两者可混用(核心K8s+ 边缘/突发函数)。
- Serverless:适合事件驱动、突发弹性、业务简单、可接受冷启动/供应商绑定。
- Serverless 是"真的没有服务器"吗?
扩展信息
- Serverless 生态:
- 云
FaaS:AWSLambda、Azure Functions、阿里云函数计算、腾讯云 SCF - 自托管:
Knative、OpenFaaS、Fission、Kubeless - 容器 Serverless:AWS
Fargate、阿里云 ASK(ServerlessK8s)
- 云
- Serverless 相关术语:
FaaS/CaaS、冷启动/预热、预留并发、按量计费、事件源
- Serverless 生态:
🤔 限流、熔断和降级是什么意思?怎么实现?
限流、熔断、降级是分布式系统的"三把保护伞":限流(限制请求频率,防流量冲垮)、熔断(下游故障时快速失败,防级联雪崩)、降级(负载过高/故障时牺牲非核心保核心)。实现上限流用令牌桶/漏桶(Sentinel/网关)、熔断用状态机(熔断器模式)、降级靠兜底逻辑。
限流(Rate Limiting)
- 定义:限制单位时间内请求量,超过则拒绝/排队(保护系统不被冲垮)
- 算法:
- 固定窗口/滑动窗口:按时间窗口计数
- 漏桶(Leaky Bucket):容量内缓冲突发、输出速率恒定(削峰填谷)
- 令牌桶(Token Bucket):允许突发,按速率补充令牌(常用)
- 实现:
Sentinel、资源网关限流、nginx limit_req、ratelimit(网关)
熔断(Circuit Breaker)
- 定义:下游服务故障/异常时,自动"断开"快速失败,不继续调用(保护自身 + 给下游恢复时间),防级联雪崩
- 熔断器状态机:
- 关闭(Closed):正常调用
- 打开(Open):失败达到阈值,快速失败(熔断开启)
- 半开(Half-Open):过一段时间放少量试探,成功则恢复关闭
- 实现:
Sentinel(熔断规则)、Resilience4j(CircuitBreaker)、Hystrix(停维护)
降级(Degradation/Fallback)
- 定义:系统负载过高/依赖故障时,主动牺牲非核心功能(返回兜底/降级响应),保证核心可用
- 场景:秒杀时非核心接口降级、依赖挂了返回缓存/默认值
- 实现:兜底逻辑(Fallback)、开关(动态配置开关)、服务降级策略
三者的区别与联系
概念 保护目标 触发 手段 限流 防止流量过大 请求量超阈值 拒绝/排队 熔断 防下游故障级联 下游失败率超阈值 快速失败 降级 保核心可用 负载高/依赖故障 牺牲非核心/兜底 - 联系:常组合使用(限流挡流量,熔断挡下游,降级兜底核心)
协助记忆
- 三把伞口诀:“限流挡流量(令牌桶)、熔断挡雪崩(状态机)、降级保核心(兜底)"。
- 熔断三态:“关闭→打开→半开→恢复”。
进阶思考
- 熔断和降级的本质区别是什么?
- 熔断:针对"下游故障”,主动"断开调用"防止雪崩(是保护手段);降级:系统"负载过高或依赖故障"时,主动"降服务等级"返回兜底(是取舍策略,和熔断可并用——依赖故障时既有熔断快速失败、也有降级兜底)。熔断是断开,降级是变弱。
- 令牌桶和漏桶怎么选?
- 令牌桶:允许一定突发(桶里有令牌就放行),适合需要容突发流量的场景(常用)。漏桶:输出速率恒定(削峰),适合需要平滑速率的场景。实战多用令牌桶(允许突发 + 限平均速率)。
- 为什么熔断能防止"雪崩效应"?
- 下游故障 → 若一直调用:上游线程/连接被占满等待 → 上游资源耗尽 → 上游也故障 → 级联放大。熔断在下游失败时快速返回(不等待),释放上游资源,切断级联链,并给下游恢复时间。
- 熔断和降级的本质区别是什么?
扩展信息
- 限流算法补充:
- 计数器(固定窗口):实现简单但窗口边界有突刺
- 滑动窗口:细粒度,准确但开销大
- 令牌桶:允许突发(Guava RateLimiter)
- 漏桶:恒定速率
- 实现组件:
- Java:Sentinel(阿里)、Resilience4j、Hystrix(停维护)、Guava RateLimiter
- 网关:
Nginxlimit_req、APISIX/Kong限流插件 - 云:云 WAF 频率限制、网关限流
- 限流算法补充:
🤔 什么是有状态 / 无状态应用?
有状态/无状态应用的核心区别是"是否在本地保存状态":无状态应用(Stateless)不在实例本地保存会话/数据,任何实例可处理任意请求、可随时销毁重建;有状态应用(Stateful)在本地保存状态(数据/会话/顺序),实例不可随意替换,扩缩容/故障恢复复杂。
无状态应用(Stateless)
- 实例不保存状态:请求处理后不依赖本地存储
- 任何请求可被任何实例处理(可水平扩展、负载均衡)
- 实例可随时销毁/重建(配合不可变基础设施)
- 状态外置:Session存
Redis、数据存 DB/对象存储 - 例子:Web 后端(纯计算/转发)、无状态 API 服务
有状态应用(Stateful)
- 实例保存状态:数据/会话/顺序/状态机在本地
- 实例不可随意替换:涉及稳定网络标识、存储绑定与有序扩缩容(配持久卷的
StatefulSet实例删除重建后,PV 重挂载、状态仍在;约束的是标识/存储/顺序而非"一换就丢") - 数据持久化:需要持久卷(PV)保存数据
- 扩缩容/故障恢复复杂(主从/复制/一致性)
- 例子:数据库(
MySQL/PostgreSQL)、Redis、消息队列(Kafka)、ZooKeeper 等
对比
维度 无状态 有状态 本地状态 无(外置) 有(本地) 扩缩容 易(加副本即可) 难(涉及数据) 故障恢复 快(重建即好) 复杂(数据恢复/主从) 存储 不需要持久卷 需要持久卷 典型 Web 后端、API 数据库、缓存、MQ 云原生对状态的处理
- 无状态化:尽量把应用设计成无状态(状态外置),提升弹性
- 有状态:
K8s用StatefulSet(稳定网络标识 + 持久卷)+ Operator(管理数据库/消息等) - 存储:PV/PVC、
CSI(Rook/Longhorn/云盘)
协助记忆
- 无状态 = “失忆的服务”(处理完就忘,任何实例都能干);有状态 = “记事的服务”(本地有账本,换人不行)。
- 口诀:“无状态好弹性(数据外置),有状态需持久化(PV 保数据)"。
进阶思考
- 为什么微服务/云原生推崇"无状态”?
- 无状态才能水平扩展、快速弹性、故障自动恢复(任意实例可销毁重建)。有状态是弹性和自动化的阻碍。所以架构上尽量无状态化,把状态下沉到专门的存储(DB/缓存)。
- 数据库这类有状态应用如何上云原生?
- 用
StatefulSet+ 持久卷 + Operator(如KubeBlocks、MySQLOperator、ECK):由 Operator 管理部署/备份/主从/扩缩。也常用"数据库托管服务"(云 RDS)代替自建,把有状态复杂度的运维交给云平台。
- 用
- Session 粘性(Sticky Session)是有状态还是无状态?
- 依赖粘性会话的应用本质是"有状态"(Session 在实例本地)。云原生尽量把 Session 外置到
Redis(共享会话),使应用变无状态(任意实例可处理)。粘性会话是"掩盖有状态"的临时方案,非最佳实践。
- 依赖粘性会话的应用本质是"有状态"(Session 在实例本地)。云原生尽量把 Session 外置到
- 为什么微服务/云原生推崇"无状态”?
扩展信息
K8s有状态应用相关:StatefulSet:稳定Pod名称/网络标识、有序部署、持久卷Headless Service:给有状态应用提供稳定 DNS- Operator:用
K8s模式管理有状态应用(KubeBlocks、MySQLOperator、Strimzi 等)
- 无状态化的常用手段:
- Session →
Redis、消息 → MQ、数据 → DB/对象存储、文件 → 对象存储(S3)
- Session →
🤔 GitOps 的核心理念是什么?
GitOps的核心理念是"Git 作为唯一事实源(Single Source of Truth)":用 Git 仓库声明式地描述系统期望状态(部署配置/应用版本),通过自动化控制器(如Argo CD)持续比较并同步集群实际状态到期望状态,一切变更走 Git(评审/审批/审计/回滚)。核心:声明式 + 版本化 + 自动化收敛。核心原则
- Git 是唯一事实源:所有环境(应用/基础设施)的期望状态都声明在 Git
- 声明式配置:用 YAML 描述期望状态(而非命令式操作)
- 自动化同步:控制器持续对比"期望(Git)“与"实际(集群)",差异自动收敛
- 变更走 Git:任何变更(部署/回滚/改配置)都通过 Git 提交(Pull Request 评审/审批/审计)
- 可回滚/可审计:Git 历史即变更记录,随时可回滚到任意版本
工作原理
1 2 3 4开发者/运维 → 修改 Git(期望状态)→ Git 提交/评审 → Argo CD(控制器)检测到变更 → 拉取清单 → 对比集群实际状态 → 同步(应用变更) → 集群达到期望状态(自愈)核心价值
- 可审计:所有变更在 Git(谁改的、改了什么、何时)
- 可回滚:Git 回滚即部署回滚(经控制器轮询同步,
Argo CD默认几分钟轮询周期 + 应用滚动,非严格秒级) - 可复现:环境状态可从 Git 重新构建
- 自动化:无需 ssh 到集群手动操作
- 自愈:集群漂移(被手动改)可被检测并恢复
实现工具
- Argo CD:最主流(apps 部署、多集群、Sync/Health)
- Flux:
GitOps工具集(Kustomize/Helm集成) - 配合:
Kustomize/Helm(配置管理)、Git 平台(GitLab/GitHub)
GitOps与传统 CI/CD 的区别- 传统:CI/CD 流水线"推送"部署(Pipeline 驱动,push 模式)
GitOps:控制器"拉取"Git 持续同步(Pull 模式,Git 驱动)
协助记忆
GitOps核心 = “Git 说了算”:期望状态在 Git,控制器自动让集群变成那样。- 四原则口诀:“Git 唯一源、声明式配置、自动同步、变更走 Git”。
进阶思考
GitOps的"Pull 模式"和传统 CI/CD 的"Push 模式"区别?- Push:流水线构建后主动部署到集群(需要集群凭证,部署动作在流水线)。Pull:控制器驻在集群内主动拉取 Git 变更并应用(集群凭证不出集群,更安全),且持续对比自愈。Pull 模式更符合"声明式 + 收敛”。
GitOps如何处理"密钥/Secrets"?- Git 不能明文存密钥。用
Sealed Secrets(加密后入库)、External Secrets(引用外部)或与 Vault 集成,Git 只存加密引用,解密在集群侧。
- Git 不能明文存密钥。用
GitOps能管"一切基础设施"吗?- 能扩展到基础设施即代码:
Terraform(TerraformController)、跨集群、跨云。Argo CD管应用部署,配合Terraform/Crossplane管基础设施,统一 Git 管理。
- 能扩展到基础设施即代码:
扩展信息
- 主流工具对比:
Argo CD:功能全、UI 好、应用/多集群管理Flux:轻量、与上面的Kustomize/Helm集成好Terraform+ Atlantis /TerraformCloud(PR 驱动 + 漂移检测)才接近GitOps;Terraform+GitHub Actions是"以 Git 为入口的 IaC",非严格GitOps(缺持续收敛/自愈)
GitOps相关概念:- 期望状态/实际状态/Sync(同步)/Self-healing(自愈)/App of Apps 模式(
Argo)
- 期望状态/实际状态/Sync(同步)/Self-healing(自愈)/App of Apps 模式(
- 主流工具对比:
🤔 CI/CD 与 GitOps 有什么区别?
CI/CD 与
GitOps的核心区别在"部署由谁驱动 + 是否持续收敛":CI/CD 是流水线"推送"部署(Pipeline 驱动,构建后主动部署,Push 模式);GitOps是控制器"拉取"Git 声明式持续同步(Pull 模式,Git 为唯一源,自动收敛自愈)。GitOps聚焦"CD 阶段"并把部署声明化、版本化、可回滚。CI/CD 是什么
- CI(持续集成):代码合并后自动构建、测试(单元/集成),保证代码质量
- CD(持续交付 vs 持续部署):持续交付(Continuous Delivery)= 代码随时可发布、发布到生产可手动审批;持续部署(Continuous
Deployment)= 合并即自动发布到生产。两者区别在"是否人工审批生产发布" - 实现:
Jenkins、GitLab CI、GitHub Actions - 特点:流水线驱动(Pipeline),构建产物(镜像/包)推送部署(Push 模式)
GitOps是什么- Git 为唯一事实源:期望状态声明在 Git(YAML)
- 控制器拉取 Git 并同步到集群(Pull 模式,如
Argo CD/Flux) - 持续对比期望 vs 实际,差异自动收敛(自愈)
- 一切变更走 Git(评审/审计/回滚)
关键区别
维度 CI/CD GitOps部署驱动 流水线推送(Push) 控制器拉取(Pull) 事实源 流水线/仓库 Git(唯一源) 声明式 可选 必须 持续收敛/自愈 无 有(自动对比修复) 回滚 流水线重新部署 Git revert(控制器同步后生效) 聚焦阶段 CI + CD 主要是 CD 关系与配合
- 互补:CI(构建测试)产出的镜像,交给
GitOps(CD)部署——“CI 管构建,GitOps管部署” - 常见组合:CI 流水线(构建镜像/更新 Git 清单)→
GitOps控制器(自动同步部署)
- 互补:CI(构建测试)产出的镜像,交给
协助记忆
- 口诀:“CI/CD 是流水线推(Push),
GitOps是控制器拉(Pull)"。 - 定位:“CI 管构建测试,
GitOps管声明式部署 + 自愈”。
- 口诀:“CI/CD 是流水线推(Push),
进阶思考
- 为什么说
GitOps侧重"CD"而不覆盖 CI?GitOps解决的是"部署阶段”:Git 声明期望状态 + 控制器同步。构建/测试(CI)仍需传统流水线(或GitOps前驱任务)。所以 CI/CD 是"从代码到部署"全流程,GitOps是其中的"部署声明化"环节,二者常配合。
GitOps和传统 CD(直接部署)的部署安全差异?- 传统 CD:部署凭证在流水线(可能被滥用)、部署命令黑盒、无版本记录。
GitOps:变更必须过 Git(PR 评审/审批),凭证在集群内控制器(不外泄),部署可审计/可回滚。更符合"变更管理 + 审计"要求。
- 传统 CD:部署凭证在流水线(可能被滥用)、部署命令黑盒、无版本记录。
GitOps响应"紧急热修复"够快吗?- 热修复需走 Git(写补丁→评审→合并→控制器同步),比直接 ssh 慢一些。但配合 CI(自动构建新版镜像)和控制器配置(更短轮询/Webhook 触发),可实现分钟级。紧急场景也可临时手动(但违背
GitOps原则,需事后补录)。
- 热修复需走 Git(写补丁→评审→合并→控制器同步),比直接 ssh 慢一些。但配合 CI(自动构建新版镜像)和控制器配置(更短轮询/Webhook 触发),可实现分钟级。紧急场景也可临时手动(但违背
- 为什么说
扩展信息
- CI/CD 工具:
- CI:
Jenkins、GitLab CI、GitHub Actions、CircleCI - CD:
Argo CD、Flux、Spinnaker、Jenkins(CD 插件)
- CI:
GitOps工具:Argo CD(最主流)、Flux、Rancher Fleet、Weave GitOps
- CI/CD 工具:
🤔 Argo CD 如何实现 K8s 应用的持续部署?
Argo CD是Kubernetes的GitOps工具:它把"Git 仓库中的应用清单"作为期望状态,持续拉取并同步到集群。核心机制:①注册 Git 仓库与应用 ②控制器周期/事件触发拉取 Git ③diff 对比(期望 vs 实际)④Sync 应用变更 ⑤自愈(漂移自动恢复)+ 回滚(app rollback)。核心概念
- Application(应用):声明一个应用的部署来源(Git 仓库 + 路径 + 目标集群/命名空间)
- Source(来源):Git 仓库中的清单(部署 YAML 或
Kustomize/Helm) - Sync(同步):把 Git 期望状态应用到集群
- Sync 策略:自动/手动(默认手动,需确认)
- Health(健康状态):检查应用是否健康(部署完成/可用)
工作流程
1 2 3 4 5 61. 用户在 Git 仓库提交应用清单(期望状态) 2. Argo CD 注册 Git 仓库 + 创建 Application(指定 Git 路径/目标集群) 3. 控制器周期轮询 Git(或 Webhook 触发) 4. 对比 Git 期望状态 vs 集群实际状态(diff) 5. 发现差异 → Sync(应用变更)或提示 6. 持续监控:集群漂移(手动改动)→ 自愈恢复(若开启)核心功能
- 声明式部署:从 Git 声明应用状态(YAML/
Helm/Kustomize) - 自动同步:检测 Git 变更自动部署(Auto Sync)
- 自愈:检测集群漂移自动恢复(Self-Healing)
- 回滚:
argocd app rollback <app> <revision>回滚到历史版本 - 可视化:Web UI 展示应用同步/健康状态
- 多集群:一个
Argo CD管理多个K8s集群 - 多仓库:支持多个 Git 仓库/
Kustomize/Helm
- 声明式部署:从 Git 声明应用状态(YAML/
典型用法(App of Apps)
- 用一个"父 Application"管理多个"子 Application"(每个微服务一个 app)
- 统一入口管理整套应用栈
部署示例(创建 Application)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: myapp spec: destination: server: https://kubernetes.default.svc namespace: prod source: repoURL: https://git.example.com/myapp.git path: deploy targetRevision: main syncPolicy: automated: selfHeal: true prune: true
协助记忆
Argo CD= “K8s的 Git 同步器”:Git 是期望,控制器拉到集群,漂移自动恢复。- 核心四动作:“Register(注册)、Diff(对比)、Sync(同步)、Heal(自愈)"。
进阶思考
Argo CD的"自愈(Self-Healing)“和"自动同步(Auto Sync)“区别?- 自动同步:Git 变更 → 自动部署到集群(Git 侧驱动)。自愈:集群被手动改动(偏离 Git)→ 自动恢复为 Git 状态。两者方向相反(自动同步向集群推 Git 变更,自愈把集群拉回 Git 状态)。注意:
selfHeal是syncPolicy.automated的子选项,必须先开自动同步才能启用自愈(即"可开自动同步而不开自愈”,不能脱离自动同步单独开自愈)。
- 自动同步:Git 变更 → 自动部署到集群(Git 侧驱动)。自愈:集群被手动改动(偏离 Git)→ 自动恢复为 Git 状态。两者方向相反(自动同步向集群推 Git 变更,自愈把集群拉回 Git 状态)。注意:
Argo CD如何安全访问 Git 仓库?- 支持 SSH/HTTPS 凭证(repository 注册时配置),也支持 HTTPS 证书、私有仓库。安全实践:用只读凭证、SSH key 管理、仓库按需授权。
Argo CD和Helm/Kustomize是什么关系?Argo CD是"部署编排”(同步 Git→集群);Helm/Kustomize是"清单生成”(把模板/基础渲染成 YAML)。Argo CD支持直接使用Helm/Kustomize作为 source:Git 里存 chart/模板,Argo渲染后部署。是配合关系。
扩展信息
Argo CD常用命令:1 2 3 4 5argocd app list # 应用列表 argocd app sync <app> # 手动同步 argocd app get <app> # 应用详情 argocd app rollback <app> <rev> # 回滚 argocd app set <app> --sync-policy automated # 设置自动同步- 相关概念:
- Sync/OutOfSync/Healthy/Synced(应用状态)、App of Apps 模式、多集群管理
- Git 仓库类型:Plain YAML /
HelmChart /Kustomize
🤔 什么是可观测性(Observability)?
可观测性(Observability)是从系统"外部输出"推断"内部状态"的能力:通过监控指标(Metrics)、日志(Logs)、链路追踪(
Traces)三支柱,回答"系统为什么变成这样",而不只是"系统是否正常"。核心:从"被告知故障"(监控)到"主动探知根因"(可观测)。什么是可观测性(定义)
- 通过系统产生的外部信号(指标/日志/追踪)理解系统内部运行状态的能力
- 目标:能回答未知问题(“什么出问题了、为什么、影响多大”),而不只是预设问题的告警
- 来自控制理论:系统可观测 = 由输出能推断内部状态
三大支柱(Three Pillars)
- Metrics(指标):数值型测量(CPU、QPS、延迟、错误率),适合告警和趋势
- Logs(日志):事件记录(错误堆栈、业务日志),适合排障细节
Traces(追踪):请求跨服务调用链(耗时分布),适合定位分布式问题- 三者互补:指标发现异常 → 日志看细节 → 追踪定位跨服务根因
监控 vs 可观测性(关键区别)
- 监控(Monitoring):预设问题(“是否正常?““CPU 高吗”),已知问题告警——“告诉你出事了”
- 可观测性(Observability):能回答未知问题(“为什么慢?““哪个环节故障?")——“告诉你为什么”
- 可观测性是监控的进阶:不光有告警,还要能快速定位根因
云原生可观测性特点
- 动态环境(容器/
K8s)实例易变,单机监控不够,需要集中/关联 - 分布式调用跨服务,需要链路追踪(传统监控看不到)
- 强调:关联(指标/日志/追踪通过标签/
TraceID关联)、自动化、标准(OpenTelemetry)
- 动态环境(容器/
协助记忆
- 可观测性 = “系统是黑盒,但能通过仪表看内部”(三支柱:指标/日志/追踪)。
- 区别口诀:“监控告诉你出事了,可观测性告诉你为什么”。
进阶思考
- 为什么"传统监控不够"要提可观测性?
- 传统监控预设指标(CPU/内存/流量),适合单机已知问题。但微服务/容器环境:①实例动态变化 ②故障跨服务传递 ③未知问题无法用预设告警发现。可观测性通过关联三支柱 + 更高维度(
RED/USE)回答未知根因。 - 补充:监控(动作/预设告警)与可观测(系统属性/探知根因)实为互补关系,可观测性是监控的深化而非简单升级。
- 传统监控预设指标(CPU/内存/流量),适合单机已知问题。但微服务/容器环境:①实例动态变化 ②故障跨服务传递 ③未知问题无法用预设告警发现。可观测性通过关联三支柱 + 更高维度(
- 可观测性的"三根支柱"还是"四信号”?
- 经典是"三支柱”(Metrics/Logs/
Traces),OpenTelemetry提出的 “Profiles”(性能剖析)仍处于推进阶段(under development),并非已完全落地。面试常答三支柱,进阶可提四信号(Profiles)。
- 经典是"三支柱”(Metrics/Logs/
- 可观测性建设从哪入手?
- 先打牢基础:①统一指标采集(
Prometheus)②日志集中(Loki/ELK)③接入链路(OTel/SkyWalking)→ 再建关联(TraceID贯通)→ 再自动化(SLO/告警/根因分析辅助)。勿一上来追求全栈,先核心服务。
- 先打牢基础:①统一指标采集(
- 为什么"传统监控不够"要提可观测性?
扩展信息
- 可观测性信号:Metrics/Logs/
Traces(Profiling、Events、Dumps 扩展) - 相关框架:
RED(Rate/Error/Duration)指标法、USE(Utilization/Saturation/Errors)指标法SLO/SLI(服务目标/指标)、Error Budget(错误预算)
- 工具栈:
Prometheus+Grafana+Loki+OpenTelemetry+SkyWalking/Jaeger
- 可观测性信号:Metrics/Logs/
🤔 传统监控与云原生可观测性有什么区别?
传统监控与云原生可观测性的核心区别:①对象(主机/单体 vs 容器/
Pod/服务)②方式(静态指标 vs 动态关联三支柱)③目标(已知告警 vs 未知根因)④架构(单机采集 vs 分布式集中)⑤生命周期(一次性配置 vs 随实例动态)。可观测性是云原生的"监控升级版”。监控对象不同
- 传统监控:物理机/虚拟机、进程、中间件(监控"节点”)
- 云原生:容器、
Pod、服务、集群(监控对象动态变化,实例频繁启停)
数据维度不同
- 传统监控:以指标为主(CPU/内存/磁盘/网络),维度单一
- 云原生:指标 + 日志 + 链路三支柱,且关联(日志/追踪用
TraceID贯穿;指标与追踪经 exemplars/标签关联——指标本身无TraceID字段)
目标与方式不同
- 传统监控:预设告警阈值,“是否越线”(已知问题告警)
- 云原生:能回答"为什么”(根因分析),自动关联定位
架构不同
- 传统监控:Agent → 中心(
Zabbix/Nagios),预先配置主机的静态拓扑(默认服务端轮询 Agent 拉取,亦支持主动上报) - 云原生:云原生采集(
Prometheus拉取 + 服务发现),指标随实例自动发现(无需手动配主机)
- 传统监控:Agent → 中心(
生命周期不同
- 传统监控:主机长期存在,配置一次长期有效
- 云原生:实例动态创建/销毁,监控需自动发现(
K8s服务发现、动态标签)、下发自动随实例
扩展性
- 传统监控:横向扩展成本高
- 云原生:可水平扩展(
Prometheus联邦/Thanos)、多集群集中
对比速查
维度 传统监控 云原生可观测性 对象 主机/进程 容器/ Pod/服务数据 指标为主 指标+日志+链路 方式 静态阈值告警 动态关联根因 目标 已知问题 未知根因 架构 Agent→中心 拉取+服务发现+集中 生命周期 静态配置 动态发现 价值
- 能应对容器动态性(自动发现监控对象)
- 能定位分布式根因(链路追踪)
- 支持云原生发布(灰度/回滚的可观测验证)
协助记忆
- 区别口诀:“对象(主机 vs 容器)、维度(指标 vs 三支柱)、目标(告警 vs 根因)、架构(静态 vs 动态)"。
- 一句话:“传统监控盯着机器,云原生可观测盯着服务和链路”。
进阶思考
- 为什么要"动态发现"监控对象(服务发现)?
K8s里Pod频繁创建/销毁(伸缩/发布),IP 变化、生命周期短,无法像传统那样手动加主机。Prometheus用K8s服务发现(自动发现Pod/Service并拉指标),实例来了自动监控,走了自动移除——这是云原生监控能跑起来的前提。
- 传统 Zabbix 监控和
Prometheus能不能直接类比?Zabbix与Prometheus的核心差异:Zabbix是"预先配置主机 + 静态拓扑”(默认服务端轮询 Agent 拉取,也支持主动上报),适合固定基础设施;Prometheus是"拉取 + 服务发现"(适合动态容器)。不是说谁好,而是适配不同场景。
- 监控数据和可观测数据的区别?
- 监控数据:预设好的、结构化的指标(看是否越线);可观测数据:更丰富(含链路/关联/上下文),支持临时性探索(查看特定请求的完整轨迹)。可观测性使用"更多维的数据回答更未知的问题"。
- 为什么要"动态发现"监控对象(服务发现)?
扩展信息
- 传统监控工具:
Zabbix、Nagios、Cacti(主机/网络监控) - 云原生监控工具:
Prometheus(指标)+Grafana(可视化)+Alertmanager(告警)Loki/ELK(日志)、OpenTelemetry/SkyWalking/Jaeger(链路)- 云:阿里云 ARMS、微软 Azure Monitor、AWS CloudWatch
- 关联方式:
TraceID贯穿、K8s标签(labels)统一、统一可观测平台(如Grafana全家桶)
- 传统监控工具:
🤔 云原生可观测性的三大核心支柱(Metrics、Logs、Traces)分别是什么?
可观测性三大支柱(Three Pillars)是:Metrics(指标)、Logs(日志)、
Traces(链路追踪)。三者定位互补——指标(数值型、适合告警/趋势)、日志(事件记录、适合排障细节)、追踪(跨服务调用链、适合定位分布式根因);配合使用:指标发现异常 → 日志看细节 → 追踪定位跨服务调用链。Metrics(指标,度量)
- 定义:数值型测量,按时间序列记录(如 CPU、QPS、延迟、错误率、内存)
- 特点:轻量、可聚合、适合告警和趋势分析、存储小成本低
- 用法:预设指标(
Prometheus采集)、阈值告警、RED/USE指标法 - 局限:只有数值,看不到"为什么"(无上下文/细节)
Logs(日志,事件)
- 定义:按时间顺序的事件记录(错误堆栈、业务日志、访问日志、审计日志)
- 特点:信息最丰富(有上下文)、适合排障细节、可搜索(结构化日志 JSON 已主流)
- 用法:集中日志(
Loki/ELK)、按关键字检索、排障根因 - 局限:数据量大、非结构化、难聚合对比(需要解析)
Traces(追踪,调用链)- 定义:一次请求/事务跨多个服务/组件的完整调用链(
Trace/Span)及每段耗时 - 特点:能看到分布式链路拓扑和每跳耗时、定位"慢在哪"
- 用法:分布式链路追踪(
SkyWalking/Jaeger/OpenTelemetry)、跨服务根因定位 - 局限:采集有开销(常需采样,低流量可全量);只覆盖采样到的请求
- 定义:一次请求/事务跨多个服务/组件的完整调用链(
三支柱协作(完整排障流程)
1 2 3指标告警(Rate/Error 异常)→ 初步定位哪个服务 → 看日志(错误堆栈/上下文)→ 深入细节 → 看追踪(TraceID 贯穿:请求跨了哪些服务、每跳耗时)→ 定位根因关联方式
TraceID贯穿日志+追踪(同一请求的日志和调用链用TraceID关联)- 统一标签(服务名/命名空间)关联指标
- 现代平台(如
Grafana数据源联动 + 日志↔追踪派生字段)支持一键跳转(日志↔追踪↔指标)
协助记忆
- 三支柱口诀:“指标看概况(数值/告警)、日志看细节(事件/堆栈)、追踪看链路(跨服务/耗时)"。
- 协作口诀:“指标发现、日志定位、追踪查根”。
进阶思考
- 三支柱各适合什么场景(怎么分工)?
- 指标:实时告警 + 趋势(“服务还活着吗?CPU 高吗?");日志:详细排障(“报了什么错?");追踪:分布式定位(“这个请求为什么慢,卡在哪个服务?")。缺哪个都难完整排障。
- 为什么"只有指标"不够(要加日志/追踪)?
- 指标告诉你"有异常”(QPS 掉/错误率升),但不知道为什么(看不到异常的具体请求/原因)。日志给细节、追踪给跨服务全貌。三者互补才能从"知道出事"到"找到原因”。
- 追踪和
APM有什么区别?- 追踪(Tracing)是采集跨服务调用链(技术手段);
APM(应用性能监控)是建立在追踪/指标之上的应用级性能监控产品(含 UI、告警、分析)。追踪是APM的核心数据源之一。
- 追踪(Tracing)是采集跨服务调用链(技术手段);
- 三支柱各适合什么场景(怎么分工)?
扩展信息
- 工具对应:
- 指标:
Prometheus+Grafana+Alertmanager - 日志:
Loki、ELK(Elasticsearch/Logstash/Kibana)、Fluentd - 链路追踪系统(后端):
Jaeger、Zipkin、Pinpoint - 注意:
OpenTelemetry是统一采集框架(API/SDK/Collector),不是追踪后端,别与追踪系统并列混淆
- 指标:
- 指标方法:
RED(Rate/Error/Duration,请求导向)、USE(Utilization/Saturation/Errors,资源导向)
- 工具对应:
🤔 OpenTelemetry 是什么?
OpenTelemetry(OTel)是CNCF的"可观测性标准框架”:为指标(Metrics)、日志(Logs)、追踪(Traces)提供统一的采集 API、SDK、协议和 Agent,实现"一次埋点、到处上报”——应用代码与后端(监控/日志/链路平台)解耦,避免厂商锁定和重复埋点。是什么(定义)
- 云原生可观测性的开放标准:一套 API + SDK + 协议(
OTLP)+ Collector - 解决"每个可观测平台一套 SDK"的碎片化问题(
Prometheus、Jaeger、SkyWalking各自埋点) CNCF项目,由OpenTracing+OpenCensus合并而来(2019),已于 2026 年 5 月成为CNCF毕业项目(云原生可观测性事实标准)
- 云原生可观测性的开放标准:一套 API + SDK + 协议(
核心组件
- API + SDK:应用接入的统一接口(埋点),支持多语言(Java/Go/Python/JS 等)
OTLP(OpenTelemetryProtocol):统一的传输协议(数据如何发往后端)- Collector(采集器):接收/处理/转发遥测数据(可做采样、过滤、导出到多个后端)
- Exporters(导出器):把数据导出到具体后端(
Prometheus远端写 +OTLP直连Jaeger/Loki等;旧Jaeger/Lokiexporter 已移除) - Instrumentation(插桩):自动/手动埋点(自动插桩:自动捕获常见框架调用)
工作流程
1 2应用(OTel SDK 埋点)→ Collector(收集/处理)→ 导出到后端(Prometheus/Jaeger/Loki...) 数据格式统一(OTLP),后端可替换(解耦)价值(为什么要用)
- 统一标准:一套 API 覆盖三信号,避免重复埋点
- 厂商中立:不绑定具体监控/链路平台(可切换后端)
- 多语言一致:各语言 SDK 行为一致
- 自动插桩:无需改代码即可捕获常见框架(Web 框架/HTTP 客户端/DB)
- 与
K8s生态集成:云原生事实标准
与同类的关系(
OpenTracing/OpenCensus)OpenTelemetry是OpenTracing+OpenCensus的继任者(合并成一个规范)- 原有
OpenTracing/OpenCensus项目逐渐被OTel取代
协助记忆
OTel= “可观测性的 USB 接口”:统一采集标准,插什么后端都行(不锁定)。- 组成口诀:“API+SDK(埋点)、
OTLP(协议)、Collector(收集)、Exporter(导出)"。
进阶思考
OTel和Prometheus/Jaeger是什么关系?- 不是替代关系:
OTel负责"采集中间层”(统一收集/导出),Prometheus/Jaeger是"后端"(存储/展示/告警)。OTel把数据用统一格式导出到这些后端,让后端可替换、解耦。
- 不是替代关系:
OTelCollector 有什么用(为什么要中间代理)?- Collector 作为"遥测数据网关":统一接收各应用数据 → 采样/过滤/脱敏 → 分发到多个后端(如同时导到
Prometheus指标 +Jaeger链路 +Loki日志)。解耦应用与后端,也便于集中配置和数据治理。
- Collector 作为"遥测数据网关":统一接收各应用数据 → 采样/过滤/脱敏 → 分发到多个后端(如同时导到
OTel怎么实现"自动插桩"?- 通过字节码注入(Java Agent)/钩子(各语言),自动捕获主流框架的调用(HTTP、DB、消息),无需业务代码手动埋点。适合快速接入,但复杂业务逻辑仍需手动埋点补充。
扩展信息
OTel生态:CNCF项目,SDK 支持 Java/Go/Python/JS/.NET 等- Collector:otel-collector(核心)、接收/处理/导出管线
OTLP:gRPC/HTTP 协议、protobuf 定义
- 语义约定(Semantic Conventions):
- 统一
Span/指标/日志的字段命名(如 attribute 命名规范),保证跨语言/跨后端一致
- 统一
🤔 你用过哪些链路追踪系统?
常用链路追踪系统分"开源"和"商业/云":开源(
SkyWalking、Jaeger、Zipkin、Pinpoint)+ 云APM(阿里云 ARMS、腾讯云APM);核心能力:跨服务调用链采集(Trace/Span)、耗时分布、拓扑图、与日志/指标关联、采样。回答时可按"工具 + 特点 + 适用场景 + 画链路/降采样"组织。- 主流开源链路追踪系统
- SkyWalking:国产(Apache),Java/Go/.NET 等,自动插桩强、自带 UI/拓扑/告警,国内广泛使用
- Jaeger:
CNCF,开源,分布式追踪(源于 Uber),兼容OpenTelemetry,带 UI;v2 已基于OTelCollector 架构(与OTel深度融合) - Zipkin:Twitter 开源(现
CNCFincubating),经典分布式追踪,与 Sleuth(Spring Cloud)经典搭配 - Pinpoint:Naver 开源,Java 为主,自动插桩 + 调用栈分析,UI 直观
- 商业/云
APM- 阿里云 ARMS、腾讯云
APM、Datadog、New Relic、Dynatrace——全栈(指标+日志+链路)一体化
- 阿里云 ARMS、腾讯云
- 核心功能(链路追踪系统都具备)
Trace/Span采集:一次请求跨服务的完整调用链- 耗时分析:每跳(
Span)耗时,定位慢在哪 - 拓扑图:服务间调用关系可视化
- 采样:全量采集开销大,多采用抽样(如按比例/固定速率)
- 关联:与日志(
TraceID)、指标关联
- 选型考虑
- 技术栈:Java 微服务 →
SkyWalking(自动插桩方便) - 开源/标准:
Jaeger/OTel兼容(云原生标准) - 全栈需求:云
APM(指标+日志+链路) - 成本:开源自建(
SkyWalking/Jaeger)vs 商业付费
- 技术栈:Java 微服务 →
- 主流开源链路追踪系统
协助记忆
- 工具口诀:"
SkyWalking(国产 UI 好)、Jaeger(CNCF标准)、Zipkin(经典)、Pinpoint(Java 自动插桩)"。 - 选型:“Java 用
SkyWalking,云原生标准用Jaeger/OTel"。
- 工具口诀:"
进阶思考
- 链路追踪为什么需要"采样”?
- 全量采集每个请求的
Trace数据量巨大(高 QPS 下存储/网络开销大)。采样(按比例/固定速率/尾部采样)在"数据量"和"可观测性"间平衡,比例视 QPS 与成本而定(常见 1%~10% 乃至更低,Jaeger默认采样概率约 0.1%)。但采样会漏掉低频问题,需结合指标/日志补。
- 全量采集每个请求的
Trace和Span的区别?Trace(一次请求的完整调用链)= 多个Span的树状集合;Span(单个操作/调用,如一次 HTTP 调用、一次 DB 查询)是链路的基本单位,带SpanID、父SpanID、上下级关系。
- 分布式追踪的"采样决策"如何在跨服务间一致?
- 若各服务独立采样,同一
Trace可能在服务 A 采样、服务 B 丢弃,导致链路断裂。需"一致采样":由入口(第一个服务)决定是否采样,并把采样标志通过上下文(Header)传给下游(或集中式采样决策服务)。
- 若各服务独立采样,同一
- 链路追踪为什么需要"采样”?
扩展信息
- 与 Spring Cloud 的关系:
- Sleuth +
Zipkin(经典 Spring Cloud 链路)、Micrometer Tracing(新一代) SkyWalking也有 Spring Cloud 集成(Agent 自动接入)
- Sleuth +
- 与
OTel关系:OTel是标准采集层,Jaeger等可作为OTel后端;SkyWalking有OTel协议接入
- 链路追踪数据模型:
TraceID(全局)、SpanID(单段)、ParentSpanID(父段)、ServiceName、Operation、Duration
- 与 Spring Cloud 的关系:
🤔 容器运行时安全性怎么做?
容器运行时安全的核心是"纵深防御 + 最小特权":镜像安全(扫描/最小化/签名)、运行时隔离(非 root/capabilities 最小化/只读根文件系统/seccomp/AppArmor)、运行时检测(
Falco行为监控)、网络隔离(NetworkPolicy)、供应链(镜像签名/SBOM)。容器安全=CVE 漏洞 + 配置加固 + 行为监控三层并重。第一层:镜像安全(前置,构建时)
- 镜像扫描:
Trivy/Clair扫描镜像漏洞(CVE),阻止高危镜像部署 - 最小化镜像:用最小基础镜像(distroless/scratch),减少攻击面
- 镜像签名:
cosign(Sigstore)验证镜像签名(防投毒) - SBOM:软件物料清单,追踪依赖
- 私有仓库:从可信仓库拉取,不用 latest 标签
- 镜像扫描:
第二层:运行时隔离(配置加固)
- 非 root 运行:镜像内指定非 root 用户 +
securityContext强制runAsNonRoot: true(镜像层和运行时层配合,这里统一强调运行时强制) - Capabilities 最小化:
drop: [ALL]只加必要能力,禁止特权容器(privileged: false) - 只读根文件系统:
readOnlyRootFilesystem: true - Seccomp:限制容器系统调用(seccompProfile)
- AppArmor/SELinux:应用级强制访问控制
- allowPrivilegeEscalation: false:禁止提权
Pod安全标准(PSS):restricted/baseline 级别(PodSecurity Admission)
- 非 root 运行:镜像内指定非 root 用户 +
策略与准入控制(强制)
- 准入控制(Admission
Controller):在资源创建/更新的 admission 阶段校验拦截,阻止不安全配置进入集群(PodSecurity Admission、OPAGatekeeper、Kyverno) - 阻止不安全配置(特权、root、hostPath)进入集群
- 准入控制(Admission
运行时检测(行为监控)
- Falco:运行时行为监控(检测 shell 进入容器、异常系统调用、可疑文件操作)
- 云安全产品:云容器安全(CWPP)
网络隔离
- NetworkPolicy:默认拒绝 + 最小放行(
Pod间隔离) - 服务网格
mTLS:服务间加密认证
- NetworkPolicy:默认拒绝 + 最小放行(
供应链与应用层
- 密钥管理:
Secret加密(KMS)、避免明文 - 镜像仓库访问控制、CI/CD 安全(构建环境可靠)
- 集群安全:
K8s本身加固(控制面/API 访问)、RBAC 最小权限
- 密钥管理:
协助记忆
- 容器安全三层:“镜像(扫描/最小化)、配置(非root/能力最小化/只读)、行为(
Falco监控)"。 - 最小特权口诀:“非 root、drop capabilities、只读根文件系统、seccomp”。
- 容器安全三层:“镜像(扫描/最小化)、配置(非root/能力最小化/只读)、行为(
进阶思考
- 为什么容器内"以 root 运行"是危险的?
- 容器内 root 与宿主 root 有权限映射风险(部分情况下可访问宿主资源/提权),一旦容器逃逸或被利用,root 权限危害巨大。所以最佳实践用非 root 运行 + 最小 capabilities,把"被攻破后的危害"降到最低。
- 镜像扫描和运行时检测有什么区别?
- 镜像扫描(静态):构建/部署前扫镜像文件的已知 CVE(
Trivy/Clair)——防"已知漏洞”。运行时检测(动态):运行中的行为监控(Falco检测异常行为)——防"未知攻击/逃逸"。两者互补:扫描防已知,运行时防未知。
- 镜像扫描(静态):构建/部署前扫镜像文件的已知 CVE(
- 为什么 seccomp/AppArmor 能增强隔离?
- 容器共享宿主内核,默认允许大部分系统调用。Seccomp 限制容器可用的系统调用(白/黑名单),AppArmor 限制应用行为(文件/网络访问),减少可利用的内核攻击面——把"内核漏洞被利用"的概率降低(撤销不用的系统调用)。
- 为什么容器内"以 root 运行"是危险的?
扩展信息
- 安全工具链:
- 镜像扫描:
Trivy、Clair、Grype、Anchore - 签名:
cosign(Sigstore)、Notary - 准入/策略:
OPA Gatekeeper、Kyverno、PodSecurity Admission - 运行时:
Falco、云 CWPP(容器安全平台) - 基线:
kube-bench(CISK8s基线)、DockerCIS 基线
- 镜像扫描:
- CIS
Docker/K8sBenchmark:容器与集群安全基线参考
- 安全工具链:
🤔 云原生可观测性第一步你认为该怎么做?
云原生可观测性建设第一步应从"统一指标采集 + 核心服务接入"入手,而非一上来追求全栈:①明确目标(先解决核心业务的"能否用/问题定位")②选基础工具(
Prometheus指标优先,成本低见效快)③先接核心服务(指标/健康/日志)④建立基础告警 ⑤再逐步扩展(日志/链路/关联)。核心:小步快跑、先打底、再深入。第一步:明确目标与范围(先想清楚)
- 目标:先解决"核心业务是否可用 + 故障能否快速定位"
- 范围:先接核心服务(高流量/关键链路),不要一次性全量
- 优先级:可用性 > 细节(先能看状态,再追求根因)
第二步:搭基础(指标优先,成本低见效快)
- 指标采集:
Prometheus+ 节点/应用 exporter(node_exporter、应用指标端点) - 可视化:
Grafana - 告警:
Alertmanager(基础告警:服务不可用、资源高、错误率高) K8s环境:用Kube-state-metrics+ 服务发现自动采集Pod/Service指标
- 指标采集:
第三步:核心服务接入(先打底)
- 核心服务接入指标端点(/metrics)+ 健康检查
- 统一标签(服务名/环境/命名空间)
- 建立基础仪表盘(服务可用性、资源、QPS、错误率)
第四步:渐进扩展(再加深)
- 加日志:集中日志(
Loki/ELK)——先核心服务日志 - 加链路:分布式追踪(
OTel/SkyWalking)——先核心调用链 - 关联:
TraceID贯穿日志+追踪,指标/日志/链路统一平台 - 加
SLO/告警优化、根因分析辅助
- 加日志:集中日志(
关键原则
- 小步快跑:先核心场景跑通,再扩展(避免一上来全栈建不好)
- 标准先行:尽量用开放标准(
OpenTelemetry),避免厂商锁定 - 关联为王:最终目标是三支柱能关联(
TraceID/标签)定位根因 - 可落地:从"能监控告警"到"能定位根因"渐进
协助记忆
- 第一步口诀:“先定目标(核心可用)、再打底(指标/告警)、后扩展(日志/链路)"。
- 原则:“小步快跑、标准先行、先指标后链路、先核心后全量”。
进阶思考
- 为什么要"指标优先"而不是链路优先?
- 指标:接入成本最低、见效最快(一个 exporter +
Grafana就能看)、且天然适合告警(能及时发现问题)。链路:需要埋点/Agent、采集开销、建设周期长。所以"先指标打底,再链路深入"是高效路径。
- 指标:接入成本最低、见效最快(一个 exporter +
- 如何避免可观测性建设"半途而废”?
- 关键是"和业务对齐 + 能落地":先选 1-2 个核心服务做出完整闭环(指标+日志+链路+告警都通),让团队看到价值,再推广。避免一次性铺太大导致做不完/没人用。
- 可观测性和"数据量大"的矛盾怎么处理?
- 分层策略:指标全量(轻量);日志/链路按需采样(日志可分级、链路抽样 1%~10%);控制存储成本(冷热分层、TTL、聚合降采样)。可观测性建设要考虑"成本与价值"平衡。
- 为什么要"指标优先"而不是链路优先?
扩展信息
- 落地清单(从零到可用):
- ①
Prometheus+Grafana部署 ② 接入核心服务指标 ③ 基础仪表盘 ④Alertmanager告警 ⑤ 核心服务日志(Loki/ELK)⑥ 核心链路(OTel/SkyWalking)⑦TraceID关联 ⑧SLO建立
- ①
- 参考方法:
- 按
RED(Rate/Error/Duration)或USE法设计核心指标 - 按"服务健康金字塔":可用性指标 → 性能指标 → 业务指标
- 按
- 工具推荐(入门栈):
Prometheus+Grafana+Alertmanager+Loki+OpenTelemetry+SkyWalkingK8s:kube-state-metrics、node_exporter、Prometheus Operator
- 落地清单(从零到可用):