K8s 网络分层全景:OSI 七层视角下看清 Pod IP、Service、Ingress 与组件分工

为什么 K8s 网络这么难懂 因为 K8s 的"网络"根本不是一张网,而是多张网叠在一起,而且不同组件在不同的协议层各干各的。以本文的 kind 集群为例,从外到内是四层: 层 网段(本文 kind 集群实测) 谁的"地盘" 物理机/宿主机 192.168.8.26 (debian 宿主机) 真实网卡(kind 之外的真实世界) 节点容器(kind 特有) 172.18.0.0/16 (节点 IP:172.18.0.2/3/4) kind 节点 = Docker 容器,这是 Docker 网络分给节点容器的 IP,不是物理机 IP Pod 网段 10.244.0.0/16 (Pod IP:10.244.1.x、10.244.2.x) 集群内每个 Pod 一个 IP(CNI 的虚拟网) Service 网段 10.96.0.0/16 (ClusterIP:10.96.x.x) 虚拟的"服务名"入口 ⚠️ 新手提示:kind 里看到的 172.18.0.x 是"节点容器"的 IP,不是物理机 IP——kind 的"容器即节点"让节点本身就是 Docker 容器(网络栈因此多一层)。kubeadm/生产集群没有这一层:节点就是物理机/虚拟机,节点 IP = 物理机 IP(如 192.168.8.26)。看下面的图就清楚了。 再加上:CoreDNS 在 L7 解析服务名、kube-proxy 在 L4 做转发、kindnet/CNI 在 L3 管 Pod IP 和路由、Ingress 在 L7 做域名路由——初学者拿着传统网络的知识套进来,发现"Pod 的 IP 不是 DNS 服务器的 IP"、“Service 的 IP 没有网卡”,自然就绕晕了。 ...

五月 22, 2024 · 10 分钟 · 1921 字 · yaomingye

Gateway API 实战:ingress-nginx 归档后的新标准(kind + Envoy Gateway 全打通)

Ingress 归档了,流量入口的新标准长什么样 先说一个 2026 年的重要事实(本文写作时实测验证):kubernetes/ingress-nginx 仓库已于 2026 年 3 月归档——GitHub API 返回 archived: true ,最后 release 是 v1.15.1(2026-03-19)。标准 Ingress Controller 停止更新了,但存量集群里的 Ingress 资源不会消失(照常工作),只是新项目的流量入口应该选新标准:Gateway API(本文写作时最新 v1.6.1,2026-07 发布,活跃迭代中)。 系列前一篇《Service 与 Ingress 实战》学的 Ingress 并没有白学——Gateway API 的设计目标之一就是吸收 Ingress 的经验、补上它的短板,两者资源模型一一对应。这篇在 kind 上用 Envoy Gateway 把 Gateway API 全链路打通:原理(三级资源模型)→ 实践(全部命令)→ 真实踩坑 → 迁移对照。 1. 动机先行:为什么要有 Gateway API Ingress 的痛点 Gateway API 的回应 一个 IngressClass / Ingress 资源,表达力有限(只能按域名+路径路由) 拆分三级资源:GatewayClass → Gateway → HTTPRoute,每级各司其职、可独立复用 路由规则与暴露方式混在一个资源里 暴露(Gateway)与路由(HTTPRoute)解耦:同一个 Gateway 可以被多个 HTTPRoute 挂载 协议扩展靠注解( nginx.ingress.kubernetes.io/xxx ),非标准 资源模型原生支持 HTTP/TLS/TCP/UDP,扩展用标准 CRD 不同实现行为不一致(nginx/traefik/…) 规范定义了资源的状态语义(Accepted/Programmed),实现行为更一致 一句话:Ingress 是"路由规则 + 入口绑在一起"的早期设计,Gateway API 把它拆成"谁提供服务(GatewayClass)→ 入口长什么样(Gateway)→ 流量怎么路由(HTTPRoute)“三层——分层带来复用和表达力。 ...

五月 20, 2024 · 6 分钟 · 1127 字 · yaomingye

K8s 组件职责全景:一条 kubectl 命令背后的控制面与节点协作

谁在干活:kubectl 命令背后的组件分工 系列前十几篇,集群一直当"黑盒"用—— kubectl apply 一个清单,应用就起来了,至于是谁把这件事做完的,没拆开看过。对兼职运维来说,这个黑盒必须拆开:排障的第一问不是"怎么修",而是"哪一环出了问题、该看谁"——Pod 一直 Pending 是调度的问题还是资源的问题?探针失败是应用的问题还是 kubelet 的问题?服务访问不通是 Service 配置还是网络插件?组件职责 = 排障归属地图。 这篇用一条生产里每天都在用的命令( kubectl apply )当主线案例,把控制面四个组件和节点四个组件的职责、工作流程讲清楚,并用 kind 集群上的实测事件证明"谁在干活"。理论向,不做源码级剖析——兼职运维只需要知道"每个组件干什么、出了事找谁"。 1. 组件全景:控制面管"想",节点管"做" K8s 的所有组件分成两组,职责边界非常清晰: 控制面(control plane):负责决策——存状态、做调度、收敛声明,全在控制面; 节点(node):负责执行——拉镜像、起容器、转发流量、管网络,全在节点。 %% K8s 组件全景: 控制面 4 件套 + 节点 4 件套 flowchart TD subgraph CP["控制面(决策)"] API["kube-apiserver\n唯一入口 + 收费站"] ETCD[("etcd\n唯一真相存储")] SCH["kube-scheduler\n给新 Pod 找节点"] CM["kube-controller-manager\n控制器集合(把声明收敛成动作)"] end subgraph N1["节点 learn-worker"] KL1["kubelet\nPod 生命周期 + 探针"] KP1["kube-proxy\nService 转发规则"] CT1["containerd\n容器运行时"] CNI1["kindnet\nPod 网络 + IP"] end subgraph N2["节点 learn-worker2"] KL2["kubelet"] KP2["kube-proxy"] CT2["containerd"] CNI2["kindnet"] end API --> ETCD API <-->|"watch/上报"| KL1 API <-->|"watch/上报"| KL2 API <-->|"watch"| KP1 API <-->|"watch"| KP2 API <-->|"watch"| SCH API <-->|"watch"| CM style API fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style SCH fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style CM fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style ETCD fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style KL1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KL2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KP1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KP2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CT1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CT2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CNI1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CNI2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff 在 kind 里这些组件都是真实运行的 Pod(生产 K8s 同款,只是 kind 把它们跑在 Docker 里)。看它们: ...

二月 22, 2024 · 5 分钟 · 869 字 · yaomingye

K8s 破坏性练习:7 天把「会做」练成「会排障」

把环境弄坏再修好:排障能力是练出来的 前十六篇文章给了完整的概念和可复现的教程,但有个问题必须诚实回答:照着教程跑一遍,不等于会实战。教程给的每个坑都带答案(症状+解法),实战遇到的 90% 报错是没见过的——教程教的是"会做"(照着 recipe 做菜),实战考的是"会排障"(菜坏了知道哪不对)。 排障能力怎么练?等真实故障喂太慢,而且线上事故不敢乱动。有一个免费的、安全的、反馈极快的方法——破坏性练习:故意把环境弄坏,再自己修好。kind 集群里怎么炸都行,成本为零,几分钟一个循环。 这篇是 7 天训练营:每天一个破坏动作,全部在本系列集群上实测过(症状真实,非杜撰),做完你就从"会做"跨进"会排障"的门。 1. 原理:为什么破坏性练习有效 反馈循环极快:破坏 → 症状 → 假设 → 验证 → 修复,几分钟一圈(真实故障要等,事故不敢练); 症状库积累:排障快的人不是更聪明,是"见过的错误模式更多"——每个练习都在往你的模式库里存一个"症状→原因"映射; 安全失败:kind 里 Pod 随便炸、节点随便驱逐,没有任何生产代价——这是练习环境存在的全部意义。 %% 破坏性练习的反馈循环 flowchart LR A["① 破坏\n故意制造故障"] B["② 观察症状\n记录报错/状态"] C["③ 提出假设\n这个症状最可能是什么"] D["④ 验证\ndescribe / logs / 实验"] E["⑤ 修复\n恢复原状"] F["⑥ 复盘\n症状→原因 存入模式库"] A --> B --> C --> D --> E --> F F -.->|"下次见到同症状"| C style A fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style B fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style C fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style F fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style D fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style E fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold 排障黄金圈(所有练习共用): ...

二月 20, 2024 · 3 分钟 · 530 字 · yaomingye

K8s Helm 包管理实战:一套模板管所有环境与发布生命周期

YAML 堆成山之后:Helm 把清单变成包 系列前几课,我们一直用 kubectl apply -f xxx.yaml 部署应用——一个应用三四个清单文件,改环境就复制粘贴。这套姿势在小规模没问题,但想象一下真实场景:10 个微服务 × dev/staging/prod 三个环境 = 30 套 YAML,改一个端口要改 30 处,漏改一处就是环境事故,更别提回滚和复用。 Helm 就是来治这个病的——它是 K8s 的包管理器(类比 Java 的 Maven、Linux 的 apt):把一套应用清单打包成 Chart,用参数渲染出任意环境,顺带管好安装/升级/回滚的完整生命周期。这一课把 demo-app 从 kubectl 迁移到 Helm,全程实测。 1. 动机先行:没有 Helm 之前有多痛 痛点 没有 Helm 时 有 Helm 后 多环境维护 每个环境复制一套 YAML,手改差异 一套模板 + 参数(values 文件)渲染所有环境 参数化 改镜像 tag 要改 YAML 文件 --set image.tag=1.3 或改 values 版本管理 YAML 散落各处,无版本概念 Chart 有版本,release 有 revision 回滚 手动恢复旧 YAML(痛苦) helm rollback 一条命令 复用 复制整个目录 打包成 Chart 分发(像 npm 包) 依赖 手动装各组件 Chart 依赖声明(如依赖 ingress-nginx) 一句话:kubectl 是"我要这个资源",Helm 是"我要这套应用"——粒度从单资源提升到整个应用。 ...

二月 18, 2024 · 4 分钟 · 847 字 · yaomingye

为什么是 K8s:传统微服务运维痛点与 K8s 的设计回应

先回答为什么,再谈怎么用 这是系列的自我批评篇,也是全系列的导航页。回看前十三篇文章,我发现一个通病:每篇都把"K8s 怎么做"讲得很细——清单、命令、预期输出、踩坑,可复现性拉满;但"为什么必须这么做“几乎没讲——没有 K8s 之前,同样的流程是怎么跑的?痛点在哪?K8s 的机制到底回应了什么? 作为 Java 开发者,你手里握着最好的参照系:Spring Cloud 时代的微服务。Nacos 配置中心、Eureka 注册中心、停机发布、人工巡检——这些痛点我们亲历过。这篇就用它当镜子,逐话题对照 K8s 的设计回应,每个话题都附上对应教程的链接——先看这篇理解"为什么”,再点链接去"怎么做"。 📌 系列结构:环境搭建见 kind 集群实战,开发者总览见 Java 开发工程师的 K8s 职责清单。 1. 总设计思想:声明式 + 控制回路 K8s 所有机制的地基是两个思想,先立起来: 声明式(Declarative):你不说"怎么做到",只说"我要什么"。传统方式是命令式——“把包拷到这台机器、改这个配置、重启这个进程”;K8s 方式是"这是我想要的最终状态(YAML),你来实现"。 控制回路(Control Loop):K8s 的控制器永远在循环"当前状态 vs 期望状态"——不一致就动手收敛,一致就闲着。这跟空调温控一个原理:设定 26 度(期望),温度计(当前),制冷/制热(动作),周而复始。 %% K8s 核心设计思想: 声明式期望 + 控制回路收敛 flowchart LR DESIRED["期望状态\nkubectl apply 提交的 YAML"] CTRL["控制器\n对比 期望 vs 当前"] ACTUAL["当前状态\n集群里的实际情况"] ACT["执行动作\n创建/重启/扩容/摘流"] DESIRED --> CTRL ACTUAL -->|"读取"| CTRL CTRL -->|"不一致 →"| ACT ACT -->|"改变"| ACTUAL CTRL -.->|"一致 → 空闲"| CTRL style DESIRED fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style CTRL fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style ACTUAL fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style ACT fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold 这个思想替代了什么:传统运维的"巡检 + 手动修复"是人肉控制回路——人发现、人决策、人执行,慢且会忘。K8s 把回路自动化了。下面七个话题,全是这个思想的展开。 ...

二月 16, 2024 · 2 分钟 · 419 字 · yaomingye

K8s 状态化应用与存储实战:StatefulSet 三大保证与存储三层抽象

有状态应用上集群:名字、盘、顺序一个都不能乱 系列前七课全在讲无状态应用——Deployment 的 Pod 随便重建、随便换节点,名字是随机后缀,数据不留本地。这当然好,但现实里有状态的东西怎么办?数据库、Redis、Elasticsearch——它们要求"我是谁"固定不变、“我的数据"不能丢、初始化顺序不能乱。 这一课补齐工作负载的最后一块拼图:StatefulSet(有状态应用控制器)和它背后的存储抽象(PV / PVC / StorageClass)。全部在 kind 上实测,最后映射到 ACK 的云盘动态供应。 1. 目标与前置条件 目标:理解 StatefulSet 与 Deployment 的本质区别;掌握存储三层抽象与动态供应机制;亲手验证"稳定标识、专属存储、有序滚动"三大保证。 前置条件(沿用系列环境): 项 说明 kind 集群 learn ,1 主 2 从,K8s v1.36.1 StorageClass kind 自带 standard ( rancher.io/local-path , WaitForFirstConsumer ),无需安装任何组件 镜像 busybox:1.36 (测试写入)、 nginx:1.27/1.25 (滚动演示) kubectl get nodes kubectl get storageclass # 应看到 standard (default) 2. 原理先行:两个问题,两套机制 2.1 存储三层抽象:开发者只写"声明” K8s 的存储不是"挂一块盘"这么简单,它把存储拆成三层,让开发者与存储实现解耦: PV(PersistentVolume,持久卷):一块真实的存储——云上是一块云盘、物理机是一个目录。它属于集群,由管理员/系统创建; PVC(PersistentVolumeClaim,持久卷声明):开发者写的"我要 100Mi 的盘,可读写一次"——声明需求,不关心盘从哪来; StorageClass(存储类):动态供应的"模板"——定义了用哪种 provisioner(云盘/本地目录)、什么回收策略。PVC 指定存储类后,provisioner 自动创建 PV 并绑定,开发者全程不碰真实存储。 %% 存储三层抽象: 开发者只写 PVC, StorageClass 自动建 PV flowchart TD DEV["开发者\n写 PVC 声明: 我要 100Mi 可读写一次的盘"] PVC["PVC\nPersistentVolumeClaim"] SC["StorageClass standard\nrancher.io/local-path"] PV["PV\n自动创建的真实卷"] DISK["物理存储\nkind: 节点本地目录\nACK: 云盘"] DEV -->|"kubectl apply"| PVC PVC -->|"指定 storageClassName"| SC SC -->|"provisioner 动态供应"| PV PV --> DISK style DEV fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style PVC fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style PV fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style SC fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff WaitForFirstConsumer(本集群 storageclass 的绑定模式)值得单独说:PVC 创建后先 Pending ,等第一个使用它的 Pod 被调度到节点后,才在那个节点上创建卷并绑定——好处是卷落在"真正用它的节点"旁边,避免"卷在 A 节点、Pod 在 B 节点"的跨机访问。云上的云盘绑定也是这个模式。 ...

二月 14, 2024 · 4 分钟 · 801 字 · yaomingye

AWS EKS 与阿里云 ACK 托管对比:计费差异、产品线布局与中小企业选型

两大云托管 K8s 摆一起:差在哪,小公司怎么选 上一篇《Java 开发工程师的 K8s 职责清单》里用一小节对比了 AWS EKS 和阿里云 ACK,写的时候发现这个题目值得单独成篇——两家都在做"托管",但计费模型、产品线布局、生态绑定的差异直接决定学习成本和选型结果,尤其对预算敏感的中小企业。 这篇把两家云托管 K8s 摊开对比:先看产品线布局,再看计费模型(最影响选型的部分),然后是全维度差异表,最后给中小企业三档推荐配置。文末记录了本次调研的时间与文档版本,方便读者核对时效。 ⚠️ 声明:本文所有对比数据来自对两家官方文档的实际检索(检索时间见文末附录),不依赖二手资料。价格可能随时调整,实际以云厂商账单为准。 1. 产品线布局:两家各摆了几个形态 先说总览。两家都从"标准托管集群"出发,各自长出了一整条产品线: %% EKS 与 ACK 产品线对照 flowchart LR EKS["AWS EKS 家族"] ACK["阿里云 ACK 家族"] E1["标准 EKS\n控制面托管 + 自管/托管节点"] E2["EKS Auto Mode\n控制面+关键组件全托管"] E3["EKS Fargate\n无服务器, 按 Pod 计费"] E4["EKS Anywhere / Distro\n私有云/自建发行版"] A1["ACK 托管集群\nPro 版 / 基础版"] A2["ACK Auto Mode\n控制面+关键组件全托管"] A3["ACK Serverless (ASK)\nECI 弹性容器实例"] A4["ACK 专有集群\n已停止新建"] A5["ACK One / 边缘版\n多云统一 / 边缘节点"] EKS --> E1 EKS --> E2 EKS --> E3 EKS --> E4 ACK --> A1 ACK --> A2 ACK --> A3 ACK --> A4 ACK --> A5 style EKS fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style ACK fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style E1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style E2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style E3 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style A1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style A2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style A3 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style E4 fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style A4 fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style A5 fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold 几个值得注意的点: ...

二月 12, 2024 · 3 分钟 · 619 字 · yaomingye

Java 开发工程师的 K8s 职责清单:八项必修、三类免学、五个专属坑

开发背一半运维:你的 K8s 职责边界在哪 云原生时代,开发工程师的职责边界变了。以前是"写完代码扔给运维",现在是"应用怎么跑也写进代码"——Dockerfile、探针、资源申请、优雅停机,这些曾经属于运维的东西,现在都是开发要交付的代码的一部分。 但反过来,开发也不该全包运维:集群的节点、证书、网络插件,那不是你的活。这篇给 Java 开发工程师一张清单——必须会什么、不用学什么、Java 专属的坑有哪些、边界到底划在哪。本系列的十篇文章是这个清单的展开,这篇是入口。 1. 一句话框架:开发背一半运维 判断职责归属,用一条标准就够: “我写的这个应用,在集群里能不能健康地跑起来、出问题我自己能不能查”——这是开发的活;“集群本身能不能稳定运转”——这是平台的活。 应用的健康 = 镜像、探针、资源配置、优雅停机、指标暴露——开发用代码负责; 集群的稳定 = 节点、etcd、CNI、证书、升级——平台/运维负责,开发只需要知道它们存在。 至于中小公司没有专职运维、开发被迫全包——那是资源约束下的现实,不是理想的职责划分。能力可以全栈,但边界心里要有数:“运维的事"永远会挤占开发时间,不清边界就会被无限稀释。 2. 必须会:八项清单 每一项都标注了"怎么算会了”——能独立完成才算过关。 # 技能 一句话原理 验证标准 对应文章 1 镜像构建 多阶段 Dockerfile 把构建与运行分离,体积从 500MB 级压到 300MB 级 能写出 JRE 运行镜像,知道层缓存 课1:镜像构建 2 Deployment 声明式滚动更新,改清单而不是手工 docker run 能改镜像滚动升级、回滚 课1:Deployment 实战 3 配置注入 ConfigMap/Secret 让配置外部化,改配置不重建镜像 能注入环境变量和文件,知道 Secret 只是 base64 课3:配置注入 4 Service/Ingress ClusterIP 内部调用、NodePort/LB 对外暴露、Ingress 管域名路由 能说清三种类型各给谁用 课2:Service/Ingress 5 探针 readiness 摘流量、liveness 重启、startup 保护慢启动 能给 Spring Boot 配齐三件套 课4:探针 6 资源申请 requests 管调度、limits 管上限,不设就是裸奔 能给应用填合理数值并解释依据 课5:资源管理 7 优雅停机 readiness 摘流 + preStop 缓冲 + graceful 处理在途 发版时在途请求不断连 课5:优雅停机 8 可观测性 应用暴露指标端点,监控才有意义 能说出 /actuator/prometheus 暴露了什么 课6:可观测性 贯穿八项的还有一个基本功:排障—— kubectl logs 、 kubectl describe 、 kubectl exec 是开发者的手电筒,遇到问题第一反应是"进 Pod 看一眼"而不是"重启试试"。 ...

十二月 4, 2023 · 4 分钟 · 735 字 · yaomingye

监控接入三方案原理对比:SSH 隧道、堡垒机与云原生监控

三条路看监控:隧道、堡垒机,还是数据上云? 在之前的文章里,我们为了"看一眼监控面板"折腾过不少事:部署在内网的 Prometheus/Grafana 不能直接访问,要开 SSH 隧道;隧道会断,断了要重连;连上之后还有账号密码、端口、地址一堆细节。这些"问题太多"的感慨,根源其实是同一个问题——监控系统放在私有网络里,人在外面,怎么合法地看到它? 围绕这个问题,行业给出了三种主流答案,恰好代表三种完全不同的网络哲学: SSH 隧道(人带着加密通道进内网看数据) 堡垒机(把入口收敛到一台"守门员",人过安检后进内网) 云原生监控(数据送出来给人看,人根本不用进内网) 这篇把三种方案的原理讲透,再放到同一张对比表里,最后给一张决策地图。它们没有优劣,只有"你愿意把哪一边放到公网上"的选择。 1. 方案 A:SSH 隧道 + 自建内网监控 原理 监控组件(Prometheus/Grafana)部署在内网,监听地址是内网 IP,公网完全摸不到。运维人员通过 SSH 端口转发(本地转发 -L 或反向转发 -R )把内网端口"搬"到自己笔记本的 localhost 上,浏览器访问 localhost:32090 时,流量顺着 SSH 加密通道流到内网。 这套方案的核心组件: 中转机:一台有公网 IP 的机器作为唯一入口,只开 SSH; 反向隧道:内网服务器主动用 autossh (自动重连的 SSH)连到中转机,建立常驻加密通道——这样即使内网没有公网 IP、人在任何网络,通道都在; 本地转发:运维人员笔记本再 ssh -L 把通道接回 localhost。 %% 方案A: SSH 隧道 + 自建内网监控(本系列学习环境的真实形态) flowchart TD LAP["运维人员笔记本\n浏览器访问 localhost:32090"] ECS["中转机(公网 IP)\n唯一公网入口\n只开放 SSH"] DEB["内网服务器\n无公网 IP"] MON["Prometheus / Grafana\n仅监听内网地址"] AUT["autossh 反向隧道\n常驻 + 自动重连"] LAP -->|"SSH -L 本地转发\n(端口搬到 localhost)"| ECS ECS -->|"加密隧道字节流"| AUT AUT -->|"经 SSH 通道"| DEB DEB --> MON LAP -.->|"浏览器流量实际路径"| MON style LAP fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style ECS fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style DEB fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style AUT fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style MON fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold 特性 数据全程在内网:指标、日志不出内网,只有加密隧道里流动的"查看请求"; 暴露面最小化:公网只有中转机一个 SSH 端口,内网零暴露; 零新增组件:复用系统自带的 SSH,不需要额外部署任何产品; 认证模型:SSH 密钥对,个人密钥直连。 真实的坑(来自本系列实践) 隧道是这条链路上最脆弱的环节。SSH 双重跳转(笔记本 → 中转机 → 内网)空闲一段时间后,中转机侧可能重置连接,症状是 Read from remote host: Connection reset by peer ,浏览器打开看板立刻 HTTP 000 。解法是 autossh 保活 + 心跳参数,但自动重连只解决内网侧的反向隧道,笔记本侧的本地转发断了还是得手动拉起——这就是"单点"的代价。 ...

十二月 2, 2023 · 3 分钟 · 539 字 · yaomingye
Cat Radio