服务网格 05:应用与代理如何启动和退出
容器在运行,不代表第一条请求能成功 前面 第 04 篇解释新 Pod 注入代理与网络捕获。应用和代理在同一 Pod 内启动时,即使 orders 进程已监听,也不能据此断言它依赖的代理 listener、cluster、证书或后端端点都已准备好。退出时也一样:Pod 开始终止不代表此前正在处理的库存请求自动完成;客户端超时更不说明服务端没有执行。需要在时间轴上分别记录应用状态、代理状态、端点状态和请求结果。 左侧先满足服务准备条件,右侧按终止顺序撤离新流量并给已开始的请求留时间。本篇实测只覆盖 Go 应用自身的 SIGTERM 和长请求;图中 Kubernetes readiness、EndpointSlice 和 Envoy drain 阶段是待在真实 sidecar Pod 验证的机制。 把可用性拆成四个状态 应用监听:socket 可接受连接。应用就绪:其 readiness 检查表达“应接收新业务请求”。代理就绪:相关 listener、上游配置及可用连接具备处理条件。Service 端点已更新:调用方所在节点可以把新连接送到此 Pod。这些状态不可能用一个容器的 Ru...
容器 E08:从容器交付到平台,还增加哪些责任
37把制品变成一次服务响应,38补上故障恢复。平台在这些节点路径之上,还要做跨节点放置、声明式控制、租户权限与流量治理;这些职责既不能让镜像 digest 自动可信,也不能代替节点上真实进程和网络的核验。 用一个最小控制/数据面案例划线 选择一份固定的 probe-app digest,在专用 kind 集群中声明 Deployment/Service。控制面根据声明维持副本,节点 kubelet 经 CRI 建立 sandbox 与进程,服务入口把真实请求发往 Ready 后端;如果加一条 Operator 自定义策略或服务网格流量规则,就要分别核对其 controller 是否改变对象,以及数据面是否实际对请求作了转发/拒绝。只存在 CRD 或策略 YAML 并不说明该 controller 已运行,也不说明路由规则已经生效。多租户还要求 RBAC、namespace、网络与节点权限一起审视;Kubernetes Namespace 是 API 组织维度,不等于 Linux user namespace 的安全边界。 正例先只用标准 Deployment/Service 把请...
服务网格 04:Sidecar 怎样接管流量
注入了代理,应用为何不必改 orders 的地址 第 03 篇把 orders 的库存地址显式改成了 Envoy listener。sidecar 模式希望应用继续访问原有 Service 地址,由同 Pod 的代理接管特定出入站流量。这里的“接管”不是 Istiod 替应用转发请求,而是 Pod 生命周期中添加代理并建立网络重定向规则;应用、代理和真正的目标 Pod 都需要从实际运行状态里核对。 图的左半段是 orders 的出站请求,右半段是 inventory 的入站请求。两个代理均在各自 Pod 附近工作;控制面向代理提供配置但通常不在业务连接中间。读者需先理解 Pod 多容器共享网络命名空间、Service 地址与 Envoy listener/cluster 的区别。 从 Pod 创建到一条连接被代理处理 Pod 被创建时,已配置且适用的注入机制可能修改新 Pod 的定义,加入代理容器以及代理启动所需配置。只给现存 namespace 打标签不会凭空改写已经运行的 Pod;必须检查新 Pod的容器列表和注入状态。控制面安装、webhook 匹配、Pod/namesp...
容器 E07:镜像按需读取是否真的缩短首个请求
34 的冷启动时间分为下载、快照准备、进程和就绪;远程 snapshotter 可能避免在进程启动前取回整份镜像,但把部分内容读取成本移到了首次访问文件时。不能只比较 `create` 的返回速度,就说一次 HTTP 请求更快。 两类成本都算入请求链 固定一个支持按需读取的 snapshotter 与镜像格式,记录启动前实际传输字节、读取文件时额外传输字节、首个请求的耗时、后续请求命中缓存情况。stargz-snapshotter 文档描述了远程按需读取与 eStargz 相关机制;具体实现是否选用了该插件、如何缓存,以及失败后如何回退,必须按实际节点版本和源码路径核对。正例预先设计“启动后只访问镜像中少数文件”的探针;边界例第一次访问未预取的大文件或在受控实验网络中断开远端,可能使首请求变慢/失败。断网仅作用于独立 VM 内的自建网络。 实验矩阵与恢复、统一探针源码允许对照常规 snapshotter;云端没有 containerd/snapshotter、没有真正的镜像按需网络路径,下载字节、缺页、首请求数据一律 `NOT_RUN`。不能把 10 的本地 OCI 布局静态校验...
容器 E06:Wasm 模块不是 Linux 容器进程
OCI 的制品分发与执行合约是不同层。10 的 descriptor/manifest可以组织非传统 rootfs 制品,但一个 Wasm 模块如何运行,依赖选定 Wasm runtime、WASI 版本与宿主接口,而不是把 .wasm 文件放进 OCI layer 就自动变成 Linux ELF 进程。 对比的是同一功能,不是同一执行模型 Linux probe-app 用 Python HTTP server,经内核的 socket 系统调用处理请求;WASI 提供的系统接口与实现能力随版本、runtime 而变。若要比较相同功能,必须选定能提供所需网络和文件能力的具体实现,明确编译目标和运行参数,再通过 OCI 制品把模块与运行配置交给支持该制品的 runtime;传统 runc 不会因此执行 Wasm 模块。正例在独立 VM 选定一个明确支持该 WASI 功能的 runtime,实现与 probe-app 可对照的简单响应;反例去掉相应 WASI 能力或选用不支持的 runtime,记录制品能被下载但无法执行的错误。版本与具体源码调用路径须按安装后实际情况核查。...
容器 E05:GPU 设备可见为什么不等于能计算
08 的设备权限只是前提:GPU 工作还依赖真实设备、宿主驱动、用户空间库、设备节点与 runtime 注入路径。CDI(Container Device Interface)提供描述第三方设备怎样被运行时注入的接口;一个 CDI 名称或 Pod 请求字段存在,不证明容器已获得可用的驱动堆栈。 将注入分解成四个核对点 先记录宿主 GPU 型号/驱动与设备节点,再查看 CDI 描述是否指向实际设备以及需要哪些 mount/env/permissions,运行时是否把这些要求应用到进程,最后运行一个小规模受控功能请求并保存错误/成功。Kubernetes 设备插件宣告的 allocatable 资源也不能代替容器内驱动库可加载证据。正例应在专用 GPU 节点固定驱动、CUDA/runtime/CDI spec 版本,使用同一探针只做设备可见和最小调用;边界案例撤去自建 CDI 描述的一项库挂载或让设备权限拒绝,定位失败层。不可卸载共享节点驱动或抢占他人的 GPU。 设备、驱动与清理表、应用侧探针包仅是素材;本机尚未发现 GPU/运行时、没有执行过设备注入与 CUDA 调用,吞吐、隔离...
服务网格 03:Envoy 怎样转发请求
从应用的上游地址移到代理监听端口 此前 orders 直连 inventory-v1。第 02 篇说明 Service 地址、端点和连接并不等价。若把 orders 的库存 URL 指向本地 Envoy listener,代理必须回答两个问题:收到一个 HTTP 请求时匹配哪条路由?挑选哪个实际后端建立上游连接?本篇先用独立 Envoy 进程解释这些步骤;它没有 Pod 注入,也没有 Istiod 或 xDS 下发。 图上方的监听地址接收下游连接,图右侧的两个 inventory 进程是候选上游。业务请求并非每次都到后端:没有匹配路由可以由代理直接返回错误,选中 cluster 但后端不可连接则失败在建立上游连接阶段。用同一个 HTTP 状态码反推故障层级会丢失信息。 将五层选择映射到一次请求 Listener 接受指定地址与端口上的连接;这是“谁能够连上代理”,还没选业务后端。多个 listener 或传输套接字会改变入口形态。 Filter chain 根据连接属性选择网络过滤器链;可以有 TLS 处理与匹配条件。本篇明文 HTTP 样例只有一条过滤器链,不推论 SNI、...
容器 E04:Windows 容器不能照搬 Linux namespace 模型
00 的进程共享内核描述 Linux 容器与 Linux VM 的边界。Windows 容器同样要考虑内核兼容,但 Windows 进程隔离与 Hyper-V 隔离的前提、实现对象和版本配对并不是 Linux userns/cgroup/OverlayFS 的别名。把 Linux 镜像 index 的 `os=windows` 字符串改一改,更不可能让 ELF 在 Windows 内核上直接执行。 两种隔离与一个版本矩阵 微软官方资料区分 Windows Server containers 的进程隔离,以及借助 Hyper-V 实现的隔离模式。进程隔离复用兼容的主机内核,Hyper-V 模式引入独立的虚拟化边界;宿主/基础镜像版本兼容、镜像架构和运行时支持需要按官方矩阵与真实系统确认。网络驱动、卷和账号语义也不能从 Linux 名称直接套用。 正例要在专用 Windows VM 固定主机与基础镜像版本,运行相同 HTTP 功能的 Windows 构建探针,分别记下隔离模式、进程/VM 状态与请求结果;反例强制不兼容镜像/宿主组合,保存构建与启动错误,不能把 Windows VM ...
容器 E03:eBPF 事件属于哪一个容器
eBPF 程序在内核钩子看到的是事件时刻的进程和内核对象,不会自动附赠“这一定属于 Pod A”的可靠标签。31 的身份链需要把 PID、cgroup、namespace inode、容器 ID 与 Pod UID 在时间窗口内对齐,尤其要考虑容器退出后 PID 被重用。 先判定事件是什么 选择一个自编 probe-app 可控的事件,例如打开自己的状态文件;在 eBPF 程序里采集时间戳、PID/TGID 与 cgroup 标识,在用户态按同一时刻运行时映射关联到容器 ID、Pod UID。权限、内核 BPF 功能和事件丢失都应写进记录。若只装了探针、打印几行带 PID 的事件,却没有证明进程当时属于哪一代容器,就仍是错误归因风险。访问 /proc 获取当前 PID 的属性只能证明读取时的状态,不保证事件发生时该 PID 还属于同一进程。 正例在独立 kind VM 中对自有探针触发一次文件打开,核对事件、实际 PID、cgroup/namespace 与 Pod UID;边界例立即重建同名 Pod,检验新旧事件能否正确分组,即使宿主 PID 以后复用也不能并为一条轨迹。身份字...
容器 E02:checkpoint 和 restore 能保存哪些进程状态
21 的 restart通常重新启动程序,并不保存原来每个进程的地址空间与 FD。CRIU(Checkpoint/Restore In Userspace)尝试冻结受支持的 Linux 任务、保存状态,再在符合前提的环境恢复它们;能恢复简单计数进程并不意味着任何有外部连接的服务都能无感迁移。 保存对象必须与外部世界对齐 一个进程的内存映射、寄存器、打开 FD、namespace 关系和网络连接可能都参与恢复;磁盘卷的内容、对端 TCP 状态、文件路径与宿主内核功能却未必随检查点一起搬迁。因此先固定 kernel/CRIU 版本、进程树、挂载和网络,记录快照时刻的业务状态。恢复时检查 PID 对照、应用计数、FD 指向的文件和 /ready,不是仅看 CRIU 返回 0。 正常实验在专用 VM 中对自编简单循环进程做 checkpoint/restore,比较恢复前后的进度;边界例增加打开的自有文件或连接到自建 HTTP 端点,记录不支持的对象和精确失败条件,避免把尝试失败硬写为“透明迁移”。恢复前提和清理入口、自编探针源码可独立取得。本云端未安装 CRIU、无恢复环境,正反案例和...








