Kubernetes 系列总结:两台服务器的资产清点与六课收获

八篇博客、两台服务器:K8s 学习资产清点 这个系列写到这里,第八篇了。从一台退役的笔记本服务器(i3 双核、7.6G 内存)搭起 kind 集群开始,到 Prometheus 抓出第一根指标曲线、Grafana 画出第一张仪表盘结束——六课实战、八篇博客,一路踩的坑全记在了文章里。 这篇不教新东西,做三件事:清点两台服务器上现在跑着的资产(写文章时我重新登服务器核实过,不是凭记忆)、按课时梳理"看+复现"分别能学到什么、把整个系列的复现成本交代清楚。想入坑的读者可以从这篇倒着挑文章看。 1. 资产清点:两台服务器,各司其职 先说分工:一台云服务器(有公网 IP)当唯一公网入口——跑博客站点、接收反向隧道;一台内网笔记本服务器(没有公网 IP)当学习环境主力——跑 kind 集群和全套监控。本机(开发机)通过 SSH 经云服务器中转,随时能进内网服务器干活。 %% 全局拓扑: 本机 -> 云服务器(入口) -> 内网 debian(学习主力) flowchart TD LAP["本机 Windows + WSL2\n开发写作 + SSH 运维入口"] ECS["云服务器 ECS\n唯一公网入口"] DEB["debian 笔记本服务器\n内网, 学习环境主力"] BLOG["blog-nginx 容器\nyaocat.cloud 博客站点"] MIH["mihomo 代理\n7890/7891/9090"] KIND["kind 集群 learn\n1 主 2 从 v1.36.1"] LAP -->|"SSH 经云服务器中转"| DEB DEB -->|"autossh 常驻加密隧道"| ECS ECS -->|"公网 80/443"| BLOG DEB -->|"拉镜像走代理"| MIH DEB --> KIND 1.1 内网笔记本服务器(学习主力) 写这篇时登上去核实过的真实清单: ...

十一月 30, 2023 · 5 分钟 · 875 字 · yaomingye

Kubernetes 可观测性实战:把 Prometheus+Grafana 装进 kind,一次踩满四个坑

四个坑,一条可观测性链路 上一篇文章(探针三兄弟)结尾我留了个预告:Prometheus 是和应用同源的"观察回路",探针负责让 kubelet 直接干预,Prometheus 负责把应用的运行状态变成数值曲线。这篇就是兑现——给 demo-app 装上指标端点,在 kind 集群里部署 Prometheus 抓取,再用 Grafana 把指标画成面板。 我原本以为最花时间的会是写 PromQL 查询,结果真正花时间的是一连串"我以为能访问、实际不能"的报错。四个坑踩下来,反而把 kind 的网络模型、集群内 DNS 的边界、ConfigMap 挂载的机制全摸了一遍。这篇文章就按踩坑的顺序写——坑是主线,知识点是副产品。 先把坑亮出来 # 坑 症状一句话 背后的机制 ① NodePort 端口超出合法区间 Service 创建被 API 拒绝 NodePort 默认只允许 30000-32767 ② 宿主机访问不到 NodePort 127.0.0.1:31090 连接被拒 kind 节点是独立网络命名空间的容器,NodePort 绑在节点 eth0 上 ③ 集群外解析不了 Service 域名 宿主机 curl demo-app-svc 直接失败 ClusterIP 的 DNS 由集群内 CoreDNS 提供,只服务集群内的 Pod ④ Grafana 预置数据源不生效 数据源列表为空 provisioning 只扫描 datasources/ 、 dashboards/ 子目录,ConfigMap 整卷挂载是扁平的 四个坑的共同点是:一切看起来都部署成功了,直到访问/验证那一刻才发现不对劲。所以每踩一个坑,我都会把"症状长什么样、我查了什么、怎么解决"完整记下来,方便对号入座。 ...

十一月 28, 2023 · 10 分钟 · 2008 字 · yaomingye

Kubernetes 优雅停机与资源管理:发版不断连 + 防 OOM 实战

让应用体面地死,别被 OOM 悄悄杀 上一篇的探针解决了"应用是死是活"的自动判定,这一篇解决剩下的两个生产问题:发版/缩容时正在处理的请求怎么办(优雅停机),以及节点资源怎么科学分配、应用怎么不被内存杀掉(资源管理)。前者让应用"体面地死",后者让应用"活着且不挤爆别人"。两件事都是 Java 应用上 K8s 后事故率最高的场景。 📌 前置知识:本文是 kind 系列第 6 篇,需要已完成前 5 篇——kind 集群、 k8s-demo-app 已部署(本文用 1.1 版,新增了 /api/slow 慢接口用于演示)、探针已配置。 这次要做什么 目标1: 配置优雅停机, 验证 Pod 被删时在途请求存活 目标2: 理解 requests/limits 资源账本, 实测 Pending 与 OOMKilled 产出: 生产级 YAML + 两组可复现演示 + 一个诚实的对照组分析 第一部分:优雅停机 原理:Pod 被删除时发生了什么 Kubernetes 删除 Pod 的完整时序(每个环节都有讲究): flowchart TD A["kubectl delete pod"] --> B["Pod 标记 Terminating"] B --> C["① Endpoints 立即摘除新流量不再进来"] C --> D["② preStop 钩子执行(本文 sleep 5s, 给摘流留时间)"] D --> E["③ kubelet 发送 SIGTERM应用开始优雅停机"] E --> F["④ 应用处理完在途请求(Spring graceful 最多等 30s)"] F --> G["⑤ 应用退出, 容器停止"] G --> H["⑥ 超过 terminationGracePeriodSeconds则 SIGKILL 强杀"] style A fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style B fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style C fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style D fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style E fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style F fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style G fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold style H fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold 三个保护机制配合(缺一不可): ...

十一月 26, 2023 · 5 分钟 · 979 字 · yaomingye

Kubernetes 探针三兄弟:readiness / liveness / startup 的生产级实战

让集群知道你的应用是死是活:探针三兄弟实战 应用部署进集群只是第一步——K8s 号称"自愈",但它怎么知道你的应用是死是活?答案就是探针(Probe)。三个探针分别回答三个问题:启动好了没?能不能接客?还活着吗? 这一篇用上一篇文章构建的 Spring Boot 应用,把三个探针逐一配上并现场演示它们的工作机制:readiness 如何拦住流量、liveness 如何自动救活假死的应用、startup 如何防止"启动慢被误杀"。 📌 前置知识:本文是 kind 系列第 5 篇,需要已完成前 4 篇的环境——kind 集群、 k8s-demo-app 应用已部署(含 ConfigMap 注入)、 demo-app-svc Service 已创建。应用已内置 Actuator 探针端点(上篇预埋的 management.endpoint.health.probes.enabled=true )。 这次要做什么 目标:给 demo-app 配置三种探针,并亲眼验证三种机制 产出:生产级探针 YAML + 三个可复现的演示 + 探针与 Prometheus 的定位对比 主角:k8s-demo-app(Spring Boot 3.3.5,Actuator 已暴露探针端点) 原理:三个探针各管什么 探针 回答的问题 失败后果 生产意义 startup 应用启动好了没? 容器被重启 给 JVM 冷启动免死金牌,治"启动慢被误杀" readiness 能接客了吗? 只摘流量,不杀容器 发版不断服、依赖故障自动摘流 liveness 还活着吗? 容器被杀重启 死锁/假死自动恢复 三个探针的配合时序: flowchart LR A["容器启动"] --> B["startupProbe成功前不启动其他探针"] B -->|"成功"| C["readinessProbe决定流量是否接入"] C -->|"持续"| D["livenessProbe决定容器是否存活"] D -->|"失败3次"| A style A fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style B fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style C fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style D fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style reject fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold ⚠️ 新手提示:最容易混淆的是 readiness 和 liveness 的失败后果——readiness 失败只摘流量(Pod 还在),liveness 失败会杀容器。生产事故里"DB 抖动引发雪崩"的根源,就是 liveness 探针错误地检查了数据库:DB 挂 30 秒 → liveness 失败 → 所有实例被反复杀。liveness 只该查进程级健康(如 JVM 活着),下游依赖的健康交给 readiness。 ...

十一月 24, 2023 · 5 分钟 · 942 字 · yaomingye

Spring Boot 容器化与配置注入:多阶段构建 + ConfigMap/Secret 实战

Spring Boot 上 K8s 的第一课:打包镜像,注入配置 前面三篇用 nginx 把集群、Deployment、Service/Ingress 都打通了,但从这一篇开始,画风要变——主角换成真实的 Spring Boot 应用。毕竟我们是 Java 开发者,最终上云(ACK/AWS)跑的是自己的微服务,不是 nginx。这篇完成两件事:把 Spring Boot 应用容器化(多阶段构建 + 瘦身),再把配置从代码里搬到集群里(ConfigMap/Secret 注入)。学完你就掌握了"镜像一份,配置到处变"的核心玩法。 📌 前置知识:建议先读本系列前三篇(kind 集群搭建、Deployment 实战、Service/Ingress 实战),本文的操作都在同一套 kind 集群上进行,镜像预载( kind load )的原理不再展开。 这次要做什么 目标:把一个真实 Spring Boot 应用部署进 kind 集群,配置由集群注入 产出:多阶段构建的镜像 + ConfigMap/Secret 注入的配置 + 验证"配置覆盖代码默认值" 主角:k8s-demo-app(Spring Boot 3.3.5 / Java 17) 主角应用很小但五脏俱全:/api/hello 返回配置值和当前 Pod 名,Actuator 暴露健康检查端点(为下篇探针做准备),内置优雅停机配置(为下下篇做准备)。 前置条件 项 本次实测 集群 kind learn (1 主 2 从,K8s v1.36.1) 工具 docker + kubectl,宿主机 Docker 已配代理 网络 国内环境:构建期依赖下载走代理,镜像预载用 kind load 第1步:一个真实的 Spring Boot 应用 工程结构: ...

十一月 22, 2023 · 4 分钟 · 683 字 · yaomingye

Kubernetes Service 与 Ingress 实战:四种暴露方式从内到外全打通

让集群里的应用被外面访问到:Service 与 Ingress 四连击 应用部署进集群只是第一步——怎么让"别人"访问到它才是日常。这个"别人"可能是集群里的另一个服务(微服务互调),可能是集群外的机器,也可能是互联网上的用户。K8s 用四种递进的暴露方式回答这个问题:ClusterIP → NodePort → LoadBalancer → Ingress。 这篇文章完整记录在 kind 一主二从集群上把这四种方式逐一打通的实战过程:每个阶段的命令、预期输出、原理,以及真实踩过的五个坑。跟着做一遍,你对"服务发现和流量入口"的理解就成型了——这也是日后上阿里云 ACK 时每天都要面对的东西。 📌 前置知识:需要已有一个 kind 集群,并且集群里有一个跑着的 Deployment(本文沿用上一篇实战部署的 nginx-demo ,5 副本,镜像 nginx:1.27)。国内网络环境需要宿主机 Docker 配好代理(见本系列第一篇)。 这次要做什么 目标:把 nginx-demo 从"只有集群内可见"逐步暴露到"域名可访问" 阶段:ClusterIP(集群内) → NodePort(节点) → LoadBalancer(模拟公网) → Ingress(域名路由) 收获:理解 Service 的选择器/Endpoints/负载均衡,以及 Ingress 的 L7 路由 概念热身:四种方式各解决什么(先建立直觉再看图) 读者此刻一定会问:ClusterIP、NodePort 是什么?为什么要四种方式?——一句话:一个服务从"集群内可见"到"公网域名可访问",每向外暴露一层,就多一种方式。顺着"我想让谁访问"这个需求递进,四个概念就都有了: 需求递进 方式 一句话(它是干嘛的) ① 服务在 Pod 里,Pod IP 会变(重启就换),集群内其他服务怎么稳定找到它? ClusterIP 给一组 Pod 一个集群内固定"虚拟 IP"(VIP)+ 名字,别人用名字访问,不关心 Pod 换没换 ② 我想从集群外访问(浏览器、外部系统)? NodePort 在每个节点上开一个端口(如 32613),外部访问 节点IP:端口 就能打到 Service ③ 生产流量大,想要一个统一的公网入口? LoadBalancer 云负载均衡器(本文用 metallb 模拟),分配一个对外 IP,流量先到它再进集群 ④ 有多个服务,想按域名/路径分发? Ingress L7 网关:按 域名 + 路径 路由到不同 Service(如 api.xxx.com → A 服务,www.xxx.com → B 服务) 记住递进关系:ClusterIP 是基础(所有方式最终都打到它)→ NodePort 是"集群外访问"的最简实现 → LoadBalancer 是"统一对外入口" → Ingress 是"按域名路由"。后面每个阶段都会细讲原理和实操。 ...

十一月 20, 2023 · 7 分钟 · 1336 字 · yaomingye

Kubernetes Deployment 实战:部署、滚动更新与回滚的完整演示

把应用跑上集群:Deployment 的一堂实战课 上一篇搭好了 kind 三节点集群,但这只是"系统盘"——真正的 K8s 学习从把应用跑上去才刚开始。这篇文章用一次完整的实战演示:部署 3 副本 nginx、观察调度器怎么分配节点、扩容、滚动更新发新版、故意发布坏版本看集群卡死、最后回滚救回来。全程真实操作和真实输出,每个环节都解释"为什么是这样"。 📌 前置知识:建议先读过本系列前一篇(kind 搭建一主二从集群),至少知道控制面/工作节点/kubelet 是什么。这篇文章的操作都在那个集群上进行。 这次要做什么 目标:在 kind 一主二从集群上,跑通 Deployment 的完整生命周期 流程:部署 → 观察调度 → 查看对象层级 → 扩容 → 滚动更新 → 坏版本发布 → 回滚 收获:亲眼验证"期望状态/控制器循环/调度器/滚动更新"这些概念 前置条件与环境准备 项 本次实测 集群 kind learn ,1 控制面 + 2 工作节点,K8s v1.36.1 工具 kubectl v1.36.4 镜像 nginx:1.25 与 nginx:1.27(预载入节点) 关键一步:镜像怎么进节点 kind 集群里拉镜像有个容易忽略的坑:节点内部的 containerd 不走宿主机 Docker 的代理配置,直接从 Docker Hub 拉。国内网络直连大概率超时。所以先把镜像拉到宿主机(走代理),再一次性导入所有节点: # 宿主机拉镜像(Docker daemon 已配代理) docker pull nginx:1.25 docker pull nginx:1.27 # 导入集群所有节点(等价于"把镜像送进每个节点") kind load docker-image nginx:1.25 nginx:1.27 --name learn “加载进入每个节点"到底是什么意思? kind 的"容器即节点"是嵌套结构:节点是一个 Docker 容器,容器内跑着 containerd(节点自己的容器运行时)——kubelet 只认 containerd。于是镜像存储有两层、互不相通: ...

十一月 18, 2023 · 6 分钟 · 1152 字 · yaomingye

kind 一主二从集群搭建全记录:代理配置、多集群切换与踩坑实录

一主二从的 K8s,kind 半小时就位 想学 Kubernetes,第一道坎不是概念,是环境:三台物理机?买不起。云厂商的托管集群?按小时计费,练手都心疼。直到某开发者把 kind(Kubernetes IN Docker)跑起来——一条命令,一台普通服务器,1 主 2 从三节点集群直接立起来,用完 kind delete cluster 一键销毁,成本几乎为零。 这篇文章完整记录这次实操:硬件要什么配置、国内网络怎么绕过、kind / kubectl / k9s 怎么装、那个 9 行的 YAML 到底在说什么、以及集群里跑起来的每个组件是什么。跟着走一遍,你也能拥有一套属于自己的 K8s 练手环境。 这次要做什么 目标:在一台 Linux 服务器上,用 kind 创建一个 1 控制面 + 2 工作节点的 Kubernetes 集群 产出:kind + kubectl + k9s 三件套,集群可通过 kubectl 正常管理 用途:本地化学习 K8s,为日后云 ECS(阿里云等)快速上手打底 📌 前置知识:需要会用 Linux 基础命令(curl、systemctl、docker)、知道容器是什么。K8s 概念零基础也可以,本文会讲清楚每个装好的组件是干嘛的。 开始之前,先把丑话说在前头——kind 的边界: flowchart LR A["kind 能学"] --> A1["API 对象 / 编排逻辑"] A --> A2["多节点调度 / 污点亲和"] A --> A3["Service / Ingress / 存储抽象"] B["kind 学不到"] --> B1["kubeadm 安装流程"] B --> B2["CNI 插件选型与安装"] B --> B3["证书 / etcd 集群 / HA 高可用"] style A fill:#1e1e24,stroke:#9ca3af,stroke-width:2px,color:#ffffff style A1 fill:#1e1e24,stroke:#9ca3af,stroke-width:2px,color:#ffffff style A2 fill:#1e1e24,stroke:#9ca3af,stroke-width:2px,color:#ffffff style A3 fill:#1e1e24,stroke:#9ca3af,stroke-width:2px,color:#ffffff style B fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold style B1 fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold style B2 fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold style B3 fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#ffffff,font-weight:bold style startEnd fill:#701a4c,stroke:#e11d48,stroke-width:2.5px,color:#ffffff,font-weight:bold kind 是用 Docker 模拟节点(每个"节点"是一个跑着完整 Linux 的容器),所以它教不会你"怎么在裸机上装出 K8s"——那些是上云前的功课,本文不展开。先把 kind 能教的部分学扎实。 ...

十一月 14, 2023 · 10 分钟 · 2068 字 · yaomingye

给 1核2G 的阿里云 ECS 换上免费 HTTPS:从装证书到踩坑全记录

博客裸奔 HTTP 大半年,我给它上了个免费锁 第 1 步:目标——让博客地址栏出现小锁 事情是这样的。某开发者的博客在阿里云 1核2G 的小 ECS 上跑了大半年,一直用 http://yaocat.cloud 裸奔。也不是没想过上 HTTPS,但总觉得"麻烦"、“要花钱”、“反正没人看”。 直到有天朋友发来一个链接,浏览器地址栏赫然一个大红叉:“不安全”。虽然博客确实没什么人看,但顶着这个红叉自己心里也膈应。 查了一圈发现:HTTPS 现在完全免费,Let’s Encrypt 发的证书不要钱,还能自动续期。那还等什么,搞它。 目标拆一下: 事项 说明 ① 申请免费证书 Let’s Encrypt,用 acme.sh 工具 ② nginx 配置挂载 配置从容器里挪出来,重建不丢 ③ HTTPS 配置 443 端口 + HTTP 自动跳转 ④ 顺带优化 gzip 压缩 + 静态缓存 第 2 步:前置条件——这台机器长什么样 先交代一下环境: 项 值 服务器 阿里云 ECS,1核2G,Debian 11 (bullseye) 网站 Docker 容器跑 nginx:alpine,挂载 /var/www/blog 域名 yaocat.cloud,已解析到服务器公网 IP 端口 80 已开(HTTP 正常访问) 动手前先确认两件事能不能通: ...

十一月 8, 2023 · 4 分钟 · 681 字 · yaomingye

Sentinel Dashboard 容器化部署踩坑全记录:从端口映射到认证配置的血泪史

被一个社区镜像折磨的 24 小时 目标说明 这篇博客的目标很朴素:让读者用 10 分钟把 Sentinel Dashboard 跑起来,而不是花一整天跟一个社区镜像死磕。 某开发者在搭建微服务治理平台时,需要部署 Sentinel Dashboard 作为流量治理控制台。本以为 docker run 一把梭,结果被 bladex/sentinel-dashboard:1.8.6 这个社区镜像折腾了整整一天——端口改不掉、环境变量传了等于没传、配置文件挂载不生效、启动就崩溃、浏览器打开 401……踩了个遍。 本文将完整记录这 7 个坑的根因、排查过程和最终解决方案。所有配置已在 Debian 13 + Docker 26+ 下验证通过。 📌 前置知识:需要了解基本 Docker 操作和 Spring Boot 配置文件概念。 前置条件 项目 要求 操作系统 Linux(本文基于 Debian 13 WSL2) Docker 26+ Docker Compose v2+ 目标端口 9903(按需调整) 验证命令: docker --version # Docker version 26.x.x docker compose version # Docker Compose version v2.x.x 环境搭建 创建一个部署目录,后续所有文件都在此目录下操作: mkdir -p ~/dev-env/sentinel && cd ~/dev-env/sentinel 先简单拉个镜像试试水: ...

三月 4, 2023 · 5 分钟 · 855 字 · yaomingye
Cat Radio