<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>K8s :: Ay Docs</title>
    <link>https://ops.docs.72602.space/using/k8s/index.html</link>
    <description>K8s的理解 Cgroup在K8S中起什么作用 Headless VS ClusterIP Creating A Pod Deleting A Pod Deployment VS ReplicaSet Endpoint VS EndpointSlice ETCD如何调优 Flannel VS Calico Headless Service VS ClusterIP Helm Principle HPA More than 1k Nodes Network Policy Node NotReady Pause 容器 Pod在K8S中DNS解析流程和顺序 当执行kubectl exec 命令时，发生了什么？ QoS 详解 Scheduler 服务发现 Service VS Endpoint StatefulSet StatefulSet 2 Talk between 2 pods in different nodes Talk with API Server</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Thu, 07 Mar 2024 15:00:59 +0800</lastBuildDate>
    <atom:link href="https://ops.docs.72602.space/using/k8s/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>K8s的理解</title>
      <link>https://ops.docs.72602.space/using/k8s/brief/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/brief/index.html</guid>
      <description>一、核心定位：云时代的操作系统 我对 K8s 最根本的理解是：它正在成为数据中心/云环境的“操作系统”。&#xA;传统操作系统（如 Windows、Linux）：管理的是单台计算机的硬件资源（CPU、内存、硬盘、网络），并为应用程序（进程）提供运行环境。 Kubernetes：管理的是一个集群（由多台计算机组成）的资源，并将这些物理机/虚拟机抽象成一个巨大的“资源池”。它在这个池子上调度和运行的不再是简单的进程，而是容器化了的应用程序。 所以，你可以把 K8s 看作是一个分布式的、面向云原生应用的操作系统。&#xA;二、要解决的核心问题：从“动物园”到“牧场” 在 K8s 出现之前，微服务和容器化架构带来了新的挑战：&#xA;编排混乱：我有成百上千个容器，应该在哪台机器上启动？如何知道它们是否健康？挂了怎么办？如何扩容缩容？ 网络复杂：容器之间如何发现和通信？如何实现负载均衡？ 存储管理：有状态应用的数据如何持久化？容器漂移后数据怎么跟走？ 部署麻烦：如何实现蓝绿部署、金丝雀发布？如何回滚？ 这个时期被称为“集装箱革命”后的“编排战争”时期，各种工具（如 Docker Swarm, Mesos, Nomad）就像是一个混乱的“动物园”。&#xA;K8s 的诞生（源于 Google 内部系统 Borg 的经验）就是为了系统地解决这些问题，它将混乱的“动物园”管理成了一个井然有序的“牧场”。它的核心能力可以概括为：声明式 API 和控制器模式。&#xA;三、核心架构与工作模型：大脑与肢体 K8s 集群主要由控制平面 和工作节点 组成。&#xA;控制平面：集群的大脑&#xA;kube-apiserver：整个系统的唯一入口，所有组件都必须通过它来操作集群状态。它是“前台总机”。 etcd：一个高可用的键值数据库，持久化存储集群的所有状态数据。它是“集群的记忆中心”。 kube-scheduler：负责调度，决定 Pod 应该在哪个节点上运行。它是“人力资源部”。 kube-controller-manager：运行着各种控制器，不断检查当前状态是否与期望状态一致，并努力驱使其一致。例如，节点控制器、副本控制器等。它是“自动化的管理团队”。 工作节点：干活的肢体&#xA;kubelet：节点上的“监工”，负责与控制平面通信，管理本节点上 Pod 的生命周期，确保容器健康运行。 kube-proxy：负责节点上的网络规则，实现 Service 的负载均衡和网络代理。 容器运行时：如 containerd 或 CRI-O，负责真正拉取镜像和运行容器。 工作模型的核心：声明式 API 与控制器模式&#xA;你向 kube-apiserver 提交一个 YAML/JSON 文件，声明你期望的应用状态（例如：我要运行 3 个 Nginx 实例）。 etcd 记录下这个期望状态。 各种控制器会持续地“观察”当前状态，并与 etcd 中的期望状态进行对比。 如果发现不一致（例如，只有一个 Nginx 实例在运行），控制器就会主动采取行动（例如，再创建两个 Pod），直到当前状态与期望状态一致。 这个过程是自愈的、自动的。 四、关键对象与抽象：乐高积木 K8s 通过一系列抽象对象来建模应用，这些对象就像乐高积木：</description>
    </item>
    <item>
      <title>Cgroup在K8S中起什么作用</title>
      <link>https://ops.docs.72602.space/using/k8s/cgroup/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/cgroup/index.html</guid>
      <description>Kubernetes 深度集成 cgroup 来实现容器资源管理和隔离。以下是 cgroup 与 K8s 结合的详细方式：&#xA;1. K8s 资源模型与 cgroup 映射 1.1 资源请求和限制 apiVersion: v1 kind: Pod spec: containers: - name: app resources: requests: memory: &#34;64Mi&#34; cpu: &#34;250m&#34; limits: memory: &#34;128Mi&#34; cpu: &#34;500m&#34; ephemeral-storage: &#34;2Gi&#34; 对应 cgroup 配置：&#xA;cpu.shares = 256 (250m × 1024 / 1000) cpu.cfs_quota_us = 50000 (500m × 100000 / 1000) memory.limit_in_bytes = 134217728 (128Mi) 2. K8s cgroup 驱动 2.1 cgroupfs 驱动 # kubelet 配置 --cgroup-driver=cgroupfs --cgroup-root=/sys/fs/cgroup 2.2 systemd 驱动（推荐） # kubelet 配置 --cgroup-driver=systemd --cgroup-root=/sys/fs/cgroup 3. K8s cgroup 层级结构 3.1 cgroup v1 层级 /sys/fs/cgroup/ ├── cpu,cpuacct/kubepods/ │ ├── burstable/pod-uid-1/ │ │ ├── container-1/ │ │ └── container-2/ │ └── guaranteed/pod-uid-2/ │ └── container-1/ ├── memory/kubepods/ └── pids/kubepods/ 3.2 cgroup v2 统一层级 /sys/fs/cgroup/kubepods/ ├── pod-uid-1/ │ ├── container-1/ │ └── container-2/ └── pod-uid-2/ └── container-1/ 4. QoS 等级与 cgroup 配置 4.1 Guaranteed (最高优先级) resources: limits: cpu: &#34;500m&#34; memory: &#34;128Mi&#34; requests: cpu: &#34;500m&#34; memory: &#34;128Mi&#34; cgroup 配置：</description>
    </item>
    <item>
      <title>Headless VS ClusterIP</title>
      <link>https://ops.docs.72602.space/using/k8s/clusterip/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/clusterip/index.html</guid>
      <description>Q: headless service 和 普通的service 有什么区别？ 只是有没有clusterIP? “有没有 ClusterIP” 只是表面现象，其背后是根本不同的服务发现模式和适用场景。&#xA;核心区别：服务发现模式 普通 Service：提供的是 “负载均衡” 式的服务发现。 它抽象了一组 Pod，你访问的是这个抽象的、稳定的 VIP（ClusterIP），然后由 kube-proxy 将流量转发到后端的某个 Pod。 客户端不知道、也不关心具体是哪个 Pod 在处理请求。 Headless Service：提供的是 “直接 Pod IP” 式的服务发现。 它不会给你一个统一的 VIP，而是直接返回后端所有 Pod 的 IP 地址。 客户端可以直接与任何一个 Pod 通信，并且知道它正在和哪个具体的 Pod 对话。 详细对比 特性 普通 Service Headless Service clusterIP 字段 自动分配一个 VIP（如 10.96.123.456），或设置为 None。 必须设置为 None。这是定义 Headless Service 的标志。 核心功能 负载均衡。作为流量的代理和分发器。 服务发现。作为 Pod 的 DNS 记录注册器，不负责流量转发。 DNS 解析结果 解析到 Service 的 ClusterIP。 解析到所有与 Selector 匹配的 Pod 的 IP 地址。 网络拓扑 客户端 -&gt; ClusterIP (VIP) -&gt; (由 kube-proxy 负载均衡) -&gt; 某个 Pod 客户端 -&gt; Pod IP 适用场景 标准的微服务、Web 前端/后端 API，任何需要负载均衡的场景。 有状态应用集群（如 MySQL, MongoDB, Kafka, Redis Cluster）、需要直接连接特定 Pod 的场景（如 gRPC 长连接、游戏服务器）。 DNS 解析行为的深入理解 这是理解两者差异的最直观方式。</description>
    </item>
    <item>
      <title>Creating A Pod</title>
      <link>https://ops.docs.72602.space/using/k8s/create_a_pod/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/create_a_pod/index.html</guid>
      <description>描述 Kubernetes 中一个 Pod 的创建过程，可以清晰地展示了 K8s 各个核心组件是如何协同工作的。&#xA;我们可以将整个过程分为两个主要阶段：控制平面的决策阶段 和 工作节点的执行阶段。&#xA;第一阶段：控制平面决策（大脑决策） 用户提交请求&#xA;用户使用 kubectl apply -f pod.yaml 向 kube-apiserver 提交一个 Pod 定义文件。 kubectl 会验证配置并将其转换为 JSON 格式，通过 REST API 调用发送给 kube-apiserver。 API Server 处理与验证&#xA;kube-apiserver 接收到请求后，会进行一系列操作： 身份认证：验证用户身份。 授权：检查用户是否有权限创建 Pod。 准入控制：可能调用一些准入控制器来修改或验证 Pod 对象（例如，注入 Sidecar 容器、设置默认资源限制等）。 所有验证通过后，kube-apiserver 将 Pod 的元数据对象写入 etcd 数据库。此时，Pod 在 etcd 中的状态被标记为 Pending。 至此，Pod 的创建请求已被记录，但还未被调度到任何节点。 调度器决策&#xA;kube-scheduler 作为一个控制器，通过 watch 机制持续监听 kube-apiserver，发现有一个新的 Pod 被创建且其 nodeName 为空。 调度器开始为这个 Pod 选择一个最合适的节点，它执行两阶段操作： 过滤：根据节点资源（CPU、内存）、污点、节点选择器、存储、镜像拉取等因素过滤掉不合适的节点。 评分：对剩下的节点进行打分（例如，考虑资源均衡、亲和性等），选择得分最高的节点。 做出决策后，kube-scheduler 补丁 的方式更新 kube-apiserver 中该 Pod 的定义，将其 nodeName 字段设置为选定的节点名称。 kube-apiserver 再次将这个更新后的信息写入 etcd。 第二阶段：工作节点执行（肢体行动） kubelet 监听到任务</description>
    </item>
    <item>
      <title>Deleting A Pod</title>
      <link>https://ops.docs.72602.space/using/k8s/delete_a_pod/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/delete_a_pod/index.html</guid>
      <description>删除一个 Pod 的流程与创建过程相对应，但它更侧重于如何优雅地、安全地终止一个运行中的实例。这个过程同样涉及多个组件的协同。&#xA;下面是一个 Pod 的删除流程，但它的核心是体现 Kubernetes 的优雅终止机制。&#xA;删除流程的核心阶段 阶段一：用户发起删除指令 用户执行命令：用户执行 kubectl delete pod &lt;pod-name&gt;。 API Server 接收请求： kubectl 向 kube-apiserver 发送一个 DELETE 请求。 kube-apiserver 会进行认证、授权等验证。 “标记为删除”：验证通过后，kube-apiserver 不会立即从 etcd 中删除该 Pod 对象，而是会执行一个关键操作：为 Pod 对象设置一个“删除时间戳”（deletionTimestamp）并将其标记为 Terminating 状态。这个状态会更新到 etcd 中。 阶段二：控制平面与节点的通知 组件感知变化： 所有监听 kube-apiserver 的组件（如 kube-scheduler, 各个节点的 kubelet）都会立刻感知到这个 Pod 的状态已变为 Terminating。 Endpoint Controller 会立刻将这个 Pod 的 IP 从关联的 Service 的 Endpoints（或 EndpointSlice）列表中移除。这意味着新的流量不会再被负载均衡到这个 Pod 上。 阶段三：节点上的优雅终止 这是最关键的阶段，发生在 Pod 所在的工作节点上。&#xA;kubelet 监听到状态变化：目标节点上的 kubelet 通过 watch 机制发现它管理的某个 Pod 被标记为 Terminating。</description>
    </item>
    <item>
      <title>Deployment VS ReplicaSet</title>
      <link>https://ops.docs.72602.space/using/k8s/deployment_vs_replicaset/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/deployment_vs_replicaset/index.html</guid>
      <description>下面我会从 架构、工作流、控制循环、数据结构与事件链 等层面详细说明它们是怎么工作的。&#xA;🧩 一、核心概念层次关系 先看一下层级：&#xA;Deployment → ReplicaSet → Pod 层级 职责 控制器类型 Deployment 负责声明“应用版本”和“滚动更新策略” 高级控制器（managing controller） ReplicaSet 保证指定数量的 Pod 副本数 基础控制器（ensuring controller） Pod 最小可调度单元，运行实际容器 工作负载对象 可以理解为：&#xA;Deployment 是策略控制器，ReplicaSet 是数量控制器，Pod 是执行单元。&#xA;⚙️ 二、Deployment 的工作原理（上层控制器） 1️⃣ Deployment 对象定义 你在创建一个 Deployment 时，例如：&#xA;apiVersion: apps/v1 kind: Deployment metadata: name: webapp spec: replicas: 3 selector: matchLabels: app: webapp template: metadata: labels: app: webapp spec: containers: - name: nginx image: nginx:1.25 这会创建一个 Deployment 对象并写入 etcd。</description>
    </item>
    <item>
      <title>Endpoint VS EndpointSlice</title>
      <link>https://ops.docs.72602.space/using/k8s/endpointslice/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/endpointslice/index.html</guid>
      <description>Endpoint 和 EndpointSlice 都是 Kubernetes 中用于管理服务后端端点的资源，但 EndpointSlice 是更现代、更高效的解决方案。以下是它们的详细区别：&#xA;一、基本概念对比 Endpoint（传统方式） apiVersion: v1 kind: Endpoints metadata: name: my-service subsets: - addresses: - ip: 10.244.1.5 targetRef: kind: Pod name: pod-1 - ip: 10.244.1.6 targetRef: kind: Pod name: pod-2 ports: - port: 8080 protocol: TCP EndpointSlice（现代方式） apiVersion: discovery.k8s.io/v1 kind: EndpointSlice metadata: name: my-service-abc123 labels: kubernetes.io/service-name: my-service addressType: IPv4 ports: - name: http protocol: TCP port: 8080 endpoints: - addresses: - &#34;10.244.1.5&#34; conditions: ready: true targetRef: kind: Pod name: pod-1 zone: us-west-2a - addresses: - &#34;10.244.1.6&#34; conditions: ready: true targetRef: kind: Pod name: pod-2 zone: us-west-2b 二、核心架构差异 1. 数据模型设计 特性 Endpoint EndpointSlice 存储结构 单个大对象 多个分片对象 规模限制 所有端点在一个对象中 自动分片（默认最多100个端点/片） 更新粒度 全量更新 增量更新 2. 性能影响对比 # Endpoint 的问题：单个大对象 # 当有 1000 个 Pod 时： kubectl get endpoints my-service -o yaml # 返回一个包含 1000 个地址的庞大 YAML # EndpointSlice 的解决方案：自动分片 # 当有 1000 个 Pod 时： kubectl get endpointslices -l kubernetes.io/service-name=my-service # 返回 10 个 EndpointSlice，每个包含 100 个端点 三、详细功能区别 1. 地址类型支持 Endpoint：</description>
    </item>
    <item>
      <title>ETCD如何调优</title>
      <link>https://ops.docs.72602.space/using/k8s/etcd/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/etcd/index.html</guid>
      <description>好的，Kubernetes 集群的稳定性和性能极大地依赖于其数据存储组件 etcd。对 etcd 进行调优是保障生产环境 K8s 集群高效、稳定运行的关键步骤。&#xA;下面我将从核心原则、性能调优参数、操作系统调优、Kubernetes 相关配置、监控与维护等多个维度，详细讲解如何对 K8s 上的 etcd 进行调优。&#xA;一、核心原则与前提 硬件是基础：在考虑软件参数调优前，必须确保硬件资源充足且高性能。&#xA;CPU：需要足够的计算能力，特别是在高负载下进行压缩、序列化等操作时。 内存：etcd 的内存消耗与总键值对数量和大小正相关。足够的内存是保证性能的关键。建议至少 8GB，生产环境推荐 16GB 或以上。 磁盘：这是最重要的因素。必须使用高性能的 SSD（NVMe SSD 最佳）。etcd 的每次写入都需持久化到磁盘，磁盘的写入延迟（Write Latency）直接决定了 etcd 的写入性能。避免使用网络存储（如 NFS）。 网络：低延迟、高带宽的网络对于 etcd 节点间同步至关重要。如果 etcd 以集群模式运行，所有节点应位于同一个数据中心或低延迟的可用区。 备份！备份！备份！：在进行任何调优或配置更改之前，务必对 etcd 数据进行完整备份。误操作可能导致数据损坏或集群不可用。&#xA;二、etcd 命令行参数调优 etcd 主要通过其启动时的命令行参数进行调优。如果你使用 kubeadm 部署，这些参数通常配置在 /etc/kubernetes/manifests/etcd.yaml 静态 Pod 清单中。&#xA;1. 存储配额与压缩 为了防止磁盘耗尽，etcd 设有存储配额。一旦超过配额，它将进入维护模式，只能读不能写，并触发告警。&#xA;--quota-backend-bytes：设置 etcd 数据库的后端存储大小上限。默认是 2GB。对于生产环境，建议设置为 8GB 到 16GB（例如 8589934592 表示 8GB）。设置过大会影响备份和恢复时间。 --auto-compaction-mode 和 --auto-compaction-retention：etcd 会累积历史版本，需要定期压缩来回收空间。 --auto-compaction-mode：通常设置为 periodic（按时间周期）。 --auto-compaction-retention：设置保留多长时间的历史数据。例如 &#34;1h&#34; 表示保留 1 小时，&#34;10m&#34; 表示保留 10 分钟。对于频繁变更的集群（如 running many CronJobs），建议设置为较短的周期，如 &#34;10m&#34; 或 &#34;30m&#34;。 示例配置片段（在 etcd.yaml 中）：</description>
    </item>
    <item>
      <title>Flannel VS Calico</title>
      <link>https://ops.docs.72602.space/using/k8s/flannel_vs_calico/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/flannel_vs_calico/index.html</guid>
      <description>Calico 和 Flannel 是 Kubernetes 中最著名和最常见的两种网络插件（CNI），但它们的设计哲学、实现方式和能力有显著区别。&#xA;简单来说：&#xA;Flannel 追求的是简单和易用，提供足够的基础网络功能。 Calico 追求的是性能和功能，提供强大的网络策略和高性能网络。 下面我们从多个维度进行详细对比。&#xA;核心对比一览表 特性 Flannel Calico 核心设计哲学 简单、最小化 高性能、功能丰富 网络模型 Overlay 网络 纯三层路由（可选 Overlay） 数据平面 VXLAN（推荐）、Host-gw、UDP BGP（推荐）、VXLAN、Windows 性能 较好（VXLAN有封装开销） 极高（BGP模式下无封装开销） 网络策略 不支持（需安装Cilium等） 原生支持（强大的网络策略） 安全性 基础 高级（基于标签的微隔离） 配置与维护 非常简单，几乎无需配置 相对复杂，功能多配置项也多 适用场景 学习、测试、中小型集群，需求简单 生产环境、大型集群、对性能和安全要求高 深入剖析 1. 网络模型与工作原理 这是最根本的区别。&#xA;Flannel (Overlay Network)：&#xA;工作原理：它在底层物理网络之上再构建一个虚拟的“覆盖网络”。当数据包从一个节点的Pod发送到另一个节点的Pod时，Flannel会将它封装在一个新的网络包中（如VXLAN）。 类比：就像在一封普通信件（Pod的原始数据包）外面套了一个标准快递袋（VXLAN封装），快递系统（底层网络）只关心快递袋上的地址（节点IP），不关心里面的内容。到达目标节点后，再拆开快递袋，取出里面的信。 优势：对底层网络要求低，只要节点之间IP能通即可，兼容性好。 劣势：封装和解封装有额外的CPU开销，并且会增加数据包的大小（ overhead），导致性能略有下降。 Calico (Pure Layer 3)：&#xA;工作原理（BGP模式）：它不使用封装，而是使用BGP路由协议。每个K8s节点都像一个路由器，它通过BGP协议向集群中的其他节点宣告：“发往这些Pod IP的流量，请送到我这里来”。 类比：就像整个数据中心是一个大的邮政系统，每个邮局（节点）都知道去往任何地址（Pod IP）的最短路径，信件（数据包）可以直接投递，无需额外包装。 优势：性能高，无封装开销，延迟低，吞吐量高。 劣势：要求底层网络必须支持BGP或者支持主机路由（某些云平台或网络设备可能需要特定配置）。 注意：Calico也支持VXLAN模式（通常用于网络策略要求BGP但底层网络不支持的场景），但其最佳性能是在BGP模式下实现的。&#xA;2. 网络策略 这是两者功能性的一个巨大分水岭。&#xA;Flannel：本身不提供任何网络策略能力。它只负责打通网络，让所有Pod默认可以相互通信。如果你需要实现Pod之间的访问控制（微隔离），你必须额外安装一个网络策略控制器，如 Cilium 或 Calico本身（可以只使用其策略部分，与Flannel叠加使用）。</description>
    </item>
    <item>
      <title>Headless Service VS ClusterIP</title>
      <link>https://ops.docs.72602.space/using/k8s/headless/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/headless/index.html</guid>
      <description>Headless Service vs ClusterIP 详解 这是 Kubernetes 中两种常见的 Service 类型,它们在服务发现和负载均衡方面有本质区别。&#xA;🎯 核心区别总结 维度 ClusterIP Headless Service ClusterIP 值 有固定的虚拟 IP None (无 ClusterIP) DNS 解析 返回 Service IP 直接返回 Pod IP 列表 负载均衡 ✅ kube-proxy 自动负载均衡 ❌ 客户端自行选择 Pod 适用场景 无状态服务 有状态服务、服务发现 典型用例 Web 应用、API 服务 数据库集群、Kafka、Zookeeper 📋 ClusterIP Service (默认类型) 定义 ClusterIP 是 Kubernetes 默认的 Service 类型,会分配一个虚拟 IP(Cluster IP),作为访问后端 Pod 的统一入口。&#xA;YAML 示例 apiVersion: v1 kind: Service metadata: name: my-web-service spec: type: ClusterIP # 默认类型,可以省略 selector: app: web ports: - protocol: TCP port: 80 # Service 端口 targetPort: 8080 # Pod 端口 工作原理 ┌─────────────────────────────────────────┐ │ ClusterIP Service │ │ (虚拟 IP: 10.96.100.50) │ └────────────┬────────────────────────────┘ │ kube-proxy 负载均衡 │ ┌───────┴───────┬──────────┐ ▼ ▼ ▼ Pod-1 Pod-2 Pod-3 10.244.1.5 10.244.2.8 10.244.3.12 (app=web) (app=web) (app=web) DNS 解析行为 # 在集群内部查询 DNS nslookup my-web-service.default.svc.cluster.local # 输出: # Name: my-web-service.default.svc.cluster.local # Address: 10.96.100.50 ← 返回 Service 的虚拟 IP # 客户端访问这个 IP curl http://my-web-service:80 # 请求会被 kube-proxy 自动转发到后端 Pod # 默认使用 iptables 或 IPVS 做负载均衡 特点 ✅ 统一入口:客户端只需知道 Service IP,不关心后端 Pod&#xA;✅ 自动负载均衡:kube-proxy 自动在多个 Pod 间分发流量&#xA;✅ 服务发现简单:通过 DNS 获取稳定的 Service IP&#xA;✅ 屏蔽 Pod 变化:Pod 重启或扩缩容,Service IP 不变&#xA;✅ 会话保持:可配置 sessionAffinity: ClientIP</description>
    </item>
    <item>
      <title>Helm Principle</title>
      <link>https://ops.docs.72602.space/using/k8s/helm/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/helm/index.html</guid>
      <description>Helm 是 Kubernetes 的包管理工具，类似于 Linux 的 apt/yum 或 Python 的 pip，它的核心作用是： 👉 用模板化的方式定义、安装和升级 Kubernetes 应用。&#xA;🧩 一、Helm 的核心概念 在理解原理前，先明确 Helm 的几个关键对象：&#xA;概念 说明 Chart 一个 Helm 包，描述一组 Kubernetes 资源的模板集合（即一个应用的安装包） Values.yaml Chart 的参数配置文件，用于填充模板变量 Release Helm 将 Chart 安装到某个命名空间后的实例，每次安装或升级都是一个 release Repository 存放打包后 chart (.tgz) 的仓库，可以是 HTTP/OCI 类型（如 Harbor, Artifactory） ⚙️ 二、Helm 的工作原理流程 从用户角度来看，Helm Client 发出命令（如 helm install），Helm 会通过一系列步骤在集群中生成 Kubernetes 资源。&#xA;下面是核心流程图概念（文字版）：&#xA;┌────────────┐ │ helm client│ └─────┬──────┘ │ ▼ 1. 解析Chart与Values │ ▼ 2. 模板渲染（Helm Template Engine） │ ▼ 3. 生成纯YAML清单 │ ▼ 4. 调用Kubernetes API │ ▼ 5. 创建/更新资源（Deployment、Service等） │ ▼ 6. 记录Release历史（ConfigMap/Secret） 🔍 三、Helm 工作机制分解 1️⃣ Chart 渲染阶段 Helm 使用 Go 的 text/template 模板引擎 + Sprig 函数库，将模板与 values.yaml 合并生成 Kubernetes YAML 清单。</description>
    </item>
    <item>
      <title>HPA</title>
      <link>https://ops.docs.72602.space/using/k8s/hpa/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/hpa/index.html</guid>
      <description>HPA（Horizontal Pod Autoscaler）是 Kubernetes 中实现自动水平扩缩容的核心组件。它的实现涉及多个 Kubernetes 组件和复杂的控制逻辑。&#xA;一、HPA 架构组成 1. 核心组件 ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ HPA Controller │ ◄──│ Metrics API │ ◄──│ Metrics Server │ │ (kube-controller)│ │ (聚合层) │ │ (cAdvisor) │ └─────────────────┘ └──────────────────┘ └─────────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ Deployment/ │ │ Custom Metrics │ │ External │ │ StatefulSet │ │ Adapter │ │ Metrics │ └─────────────────┘ └──────────────────┘ └─────────────────┘ 二、HPA 工作流程 1. 完整的控制循环 // 简化的 HPA 控制逻辑 for { // 1. 获取 HPA 对象 hpa := client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Get(name) // 2. 获取缩放目标（Deployment/StatefulSet等） scaleTarget := hpa.Spec.ScaleTargetRef target := client.AppsV1().Deployments(namespace).Get(scaleTarget.Name) // 3. 查询指标 metrics := []autoscalingv2.MetricStatus{} for _, metricSpec := range hpa.Spec.Metrics { metricValue := getMetricValue(metricSpec, target) metrics = append(metrics, metricValue) } // 4. 计算期望副本数 desiredReplicas := calculateDesiredReplicas(hpa, metrics, currentReplicas) // 5. 执行缩放 if desiredReplicas != currentReplicas { scaleTarget.Spec.Replicas = &amp;desiredReplicas client.AppsV1().Deployments(namespace).UpdateScale(scaleTarget.Name, scaleTarget) } time.Sleep(15 * time.Second) // 默认扫描间隔 } 2. 详细步骤分解 步骤 1：指标收集</description>
    </item>
    <item>
      <title>More than 1k Nodes</title>
      <link>https://ops.docs.72602.space/using/k8s/more_than_1k_nodes/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/more_than_1k_nodes/index.html</guid>
      <description>在这个量级上，K8s 不再只是“能跑就行”，而是进入可扩展性、稳定性、可观测性和资源效率的工程化挑战。下面我从架构、控制面、节点管理、网络、存储、安全和运维几个方面系统讲解。&#xA;🧠 一、总体思路：大规模集群的本质挑战 当节点规模超过 500～1000 时，Kubernetes 的瓶颈通常出现在：&#xA;控制平面（API Server / etcd）压力过大； 调度器吞吐不足； 资源对象（Pod / Node / Secret / ConfigMap 等）过多，导致 List/Watch 延迟； 网络和 CNI 插件在高并发下性能下降； 监控、日志、事件系统的数据量爆炸； 维护和升级变得极度复杂。 所以，大规模集群的重点是：&#xA;控制平面分层、节点池分区、流量隔离、观测与调优。&#xA;🏗️ 二、控制平面（Control Plane） 1. etcd 优化 独立部署：不要和 kube-apiserver 混布，最好是独立的高性能节点（NVMe SSD、本地盘）。 使用 etcd v3.5+（性能改进明显），并开启压缩和快照机制。 调大 --max-request-bytes 和 --quota-backend-bytes，避免过载。 定期 defrag：可用 CronJob 自动化。 不要存放短生命周期对象（例如频繁更新的 CRD 状态），可以考虑用外部缓存系统（如 Redis 或 SQL）。 2. API Server 扩展与保护 使用 负载均衡（HAProxy、NGINX、ELB）在多 API Server 之间分流；&#xA;调整：&#xA;--max-mutating-requests-inflight --max-requests-inflight --target-ram-mb 合理设置 --request-timeout，防止 watch 卡死；</description>
    </item>
    <item>
      <title>Network Policy</title>
      <link>https://ops.docs.72602.space/using/k8s/network_policy/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/network_policy/index.html</guid>
      <description>1. Network Policy 的设计原理 Kubernetes Network Policy 的设计核心思想是：在默认允许的集群网络中，引入一个“默认拒绝”的、声明式的、基于标签的防火墙。&#xA;让我们来分解这个核心思想：&#xA;从“默认允许”到“默认拒绝”&#xA;默认行为：在没有任何 Network Policy 的情况下，Kubernetes 集群内的 Pod 之间是可以自由通信的（取决于 CNI 插件），甚至来自外部的流量也可能直接访问到 Pod。这就像在一个没有防火墙的开放网络里。 Network Policy 的作用：一旦在某个 Namespace 中创建了一个 Network Policy，它就会像一个“开关”，将这个 Namespace 或特定 Pod 的默认行为变为 “默认拒绝”。之后，只有策略中明确允许的流量才能通过。 声明式模型&#xA;和其他的 Kubernetes 资源（如 Deployment、Service）一样，Network Policy 也是声明式的。你只需要告诉 Kubernetes“你期望的网络状态是什么”（例如，“允许来自带有 role=frontend 标签的 Pod 的流量访问带有 role=backend 标签的 Pod 的 6379 端口”），而不需要关心如何通过 iptables 或 eBPF 命令去实现它。Kubernetes 和其下的 CNI 插件会负责实现你的声明。 基于标签的选择机制&#xA;这是 Kubernetes 的核心设计模式。Network Policy 不关心 Pod 的 IP 地址，因为 IP 是动态且易变的。它通过 标签 来选择一组 Pod。 podSelector： 选择策略所应用的 Pod（即目标 Pod）。 namespaceSelector： 根据命名空间的标签来选择来源或目标命名空间。 namespaceSelector 和 podSelector 可以组合使用，实现非常精细的访问控制。 策略是叠加的</description>
    </item>
    <item>
      <title>Node NotReady</title>
      <link>https://ops.docs.72602.space/using/k8s/node_not_ready/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/node_not_ready/index.html</guid>
      <description>当 Kubernetes 中某些 Node 节点状态变为 NotReady 时，这往往意味着 kubelet 无法与控制平面（API Server）正常通信，或该节点上某些关键组件/资源异常。&#xA;我们可以从以下两个层面来分析： 1️⃣ 导致节点 NotReady 的常见原因 2️⃣ NotReady 状态对整个集群和业务的影响&#xA;🧩 一、Node NotReady 的常见原因分类 kubelet 每 10 秒（默认）向 API Server 报告一次心跳（NodeStatus）。 如果连续 40 秒（默认 --node-monitor-grace-period=40s）没有收到更新，Controller Manager 会将节点标记为 NotReady。&#xA;下面按类别详细分析👇&#xA;🖧 1. 网络层异常（最常见） 症状：节点能 ping 通外网，但与 control plane 交互超时。 原因包括：&#xA;节点与 kube-apiserver 之间的网络中断（如防火墙、路由异常、VPC 问题）； API Server 负载均衡异常（L4/L7 LB 停止转发流量）； Pod 网络插件（CNI）崩溃，kubelet 无法汇报 Pod 状态； 节点 DNS 解析异常（影响 kubelet 访问 API Server）。 排查方式：&#xA;# 在节点上检查 API Server 可达性 curl -k https://&lt;apiserver-ip&gt;:6443/healthz # 检查 kubelet 日志 journalctl -u kubelet | grep -E &#34;error|fail|timeout&#34; ⚙️ 2. kubelet 本身异常 症状：节点长时间 NotReady，重启 kubelet 后恢复。</description>
    </item>
    <item>
      <title>Pause 容器</title>
      <link>https://ops.docs.72602.space/using/k8s/pause/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/pause/index.html</guid>
      <description>Kubernetes Pause 容器的用途 Pause 容器是 Kubernetes 中一个非常小但极其重要的基础设施容器。很多人会忽略它,但它是 Pod 网络和命名空间共享的核心。&#xA;🎯 核心作用 1. 作为 Pod 的&#34;根容器&#34;(Infrastructure Container) Pause 容器是每个 Pod 中第一个启动的容器,它的生命周期代表整个 Pod 的生命周期。&#xA;Pod 生命周期: 创建 Pod → 启动 Pause 容器 → 启动业务容器 → ... → 业务容器结束 → 删除 Pause 容器 → Pod 销毁 2. 持有和共享 Linux 命名空间 Pause 容器创建并持有以下命名空间,供 Pod 内其他容器共享:&#xA;Network Namespace (网络命名空间) - 最重要! IPC Namespace (进程间通信) UTS Namespace (主机名) # 查看 Pod 中的容器 docker ps | grep pause # 你会看到类似输出: # k8s_POD_mypod_default_xxx k8s.gcr.io/pause:3.9 # k8s_app_mypod_default_xxx myapp:latest 🌐 网络命名空间共享(最关键的用途) 工作原理 ┌─────────────────── Pod ───────────────────┐ │ │ │ ┌─────────────┐ │ │ │ Pause │ ← 创建网络命名空间 │ │ │ Container │ ← 拥有 Pod IP │ │ └──────┬──────┘ │ │ │ (共享网络栈) │ │ ┌──────┴──────┬──────────┬──────────┐ │ │ │ Container A │Container B│Container C│ │ │ │ (业务容器) │ (业务容器)│ (业务容器) │ │ │ └─────────────┴──────────┴──────────┘ │ │ │ │ 所有容器共享: │ │ - 同一个 IP 地址 (Pod IP) │ │ - 同一个网络接口 │ │ - 同一个端口空间 │ │ - 可以通过 localhost 互相访问 │ └────────────────────────────────────────────┘ 实际效果 # 示例 Pod apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: nginx image: nginx ports: - containerPort: 80 - name: sidecar image: busybox command: [&#39;sh&#39;, &#39;-c&#39;, &#39;while true; do wget -O- localhost:80; sleep 5; done&#39;] 在这个例子中:</description>
    </item>
    <item>
      <title>Pod在K8S中DNS解析流程和顺序</title>
      <link>https://ops.docs.72602.space/using/k8s/pod_dns_route/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/pod_dns_route/index.html</guid>
      <description>核心概念 CoreDNS： 从Kubernetes 1.11开始，CoreDNS是默认的DNS服务。它作为一个或多个Pod运行在kube-system命名空间下，并配有一个Kubernetes Service（通常叫kube-dns）。 resolv.conf 文件： 每个Pod的/etc/resolv.conf文件是DNS解析的蓝图。Kubelet会自动生成这个文件并挂载到Pod中。 DNS策略： 你可以通过Pod Spec中的dnsPolicy字段来配置DNS策略。 Pod 的 /etc/resolv.conf 解析 这是一个典型的Pod内的/etc/resolv.conf文件内容：&#xA;nameserver 10.96.0.10 search &lt;namespace&gt;.svc.cluster.local svc.cluster.local cluster.local options ndots:5 让我们逐行分析：&#xA;1. nameserver 10.96.0.10 这是CoreDNS Service的集群IP地址。所有Pod的DNS查询默认都会发送到这个地址。 这个IP来自kubelet的--cluster-dns标志，在启动时确定。 2. search &lt;namespace&gt;.svc.cluster.local svc.cluster.local cluster.local 搜索域列表。当你使用不完整的域名（即不是FQDN）时，系统会按照这个列表的顺序，依次将搜索域附加到主机名后面，直到找到匹配的记录。 &lt;namespace&gt;是你的Pod所在的命名空间，例如default。 搜索顺序： &lt;pod-namespace&gt;.svc.cluster.local svc.cluster.local cluster.local 3. options ndots:5 这是一个关键的优化/控制选项。 规则： 如果一个域名中的点（.）数量大于或等于这个值（这里是5），系统会将其视为绝对域名（FQDN），并首先尝试直接解析，不会走搜索域列表。 反之，如果点数少于5，系统会先依次尝试搜索域，如果都失败了，最后再尝试名称本身。 DNS 解析流程与顺序（详解） 假设你的Pod在default命名空间，并且resolv.conf如上所示。&#xA;场景1：解析Kubernetes Service（短名称） 你想解析同一个命名空间下的Service：my-svc。&#xA;应用程序请求解析 my-svc。 系统检查名称 my-svc，点数（0） &lt; 5。 进入搜索流程： 第一次尝试： my-svc.default.svc.cluster.local -&gt; 成功！ 返回ClusterIP。 解析结束。 场景2：解析不同命名空间的Service 你想解析另一个命名空间prod下的Service：my-svc.prod。</description>
    </item>
    <item>
      <title>当执行kubectl exec 命令时，发生了什么？</title>
      <link>https://ops.docs.72602.space/using/k8s/pod_exec/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/pod_exec/index.html</guid>
      <description>kubectl exec 的实现原理涉及多个组件协同工作，以下是详细原理分析：&#xA;1. 整体架构流程 用户 -&gt; kubectl -&gt; API Server -&gt; Kubelet -&gt; 容器运行时 -&gt; 目标容器 2. 详细执行步骤 步骤1：kubectl 客户端处理 kubectl exec -it &lt;pod-name&gt; -- /bin/bash kubectl 解析命令参数 构造 Exec API 请求 建立与 API Server 的长连接 步骤2：API Server 处理 // API 路径示例 POST /api/v1/namespaces/{namespace}/pods/{name}/exec 认证和授权检查 验证用户是否有 exec 权限 查找目标 Pod 所在节点 将请求代理到对应节点的 Kubelet 步骤3：Kubelet 处理 // Kubelet 的 exec 处理逻辑 func (h *ExecHandler) serveExec(w http.ResponseWriter, req *http.Request) { // 获取容器信息 // 调用容器运行时接口 // 建立数据流传输 } 通过 CRI（Container Runtime Interface）调用容器运行时 创建到容器的连接 管理标准输入、输出、错误流 步骤4：容器运行时执行 // CRI 接口定义 service RuntimeService { rpc Exec(ExecRequest) returns (ExecResponse) {} } Docker: 使用 docker exec 底层机制 Containerd: 通过 task 执行命令 CRI-O: 通过 conmon 管理执行会话 3. 关键技术机制 3.1 流式传输协议 // 使用 SPDY 或 WebSocket 协议 // 支持多路复用的数据流 type StreamProtocol interface { Stream(stdin io.Reader, stdout, stderr io.Writer) error } 3.2 终端处理（TTY） // 伪终端配置 type ExecOptions struct { Stdin io.Reader Stdout io.Writer Stderr io.Writer TTY bool ptyMaster *os.File } 3.3 会话管理 // ExecSession 管理执行会话 type ExecSession struct { id string stdinPipe io.WriteCloser stdoutPipe io.ReadCloser stderrPipe io.ReadCloser done chan struct{} } 4. 网络通信流程 客户端 (kubectl) ↓ HTTPS with SPDY/WebSocket API Server ↓ 代理连接 Kubelet (节点) ↓ CRI gRPC 容器运行时 ↓ 容器命名空间 目标容器进程 5. 安全机制 5.1 认证授权 # RBAC 配置示例 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-exec rules: - apiGroups: [&#34;&#34;] resources: [&#34;pods/exec&#34;] verbs: [&#34;create&#34;] 5.2 安全上下文 // 安全配置 securityContext := &amp;v1.SecurityContext{ RunAsUser: &amp;uid, RunAsGroup: &amp;gid, Capabilities: &amp;v1.Capabilities{ Drop: []v1.Capability{&#34;ALL&#34;}, }, } 6. 实际代码示例 kubectl 端实现 func (o *ExecOptions) Run() error { // 建立与 API Server 的连接 executor, err := remotecommand.NewSPDYExecutor( o.Config, &#34;POST&#34;, req.URL()) // 执行命令 return executor.Stream(remotecommand.StreamOptions{ Stdin: o.In, Stdout: o.Out, Stderr: o.ErrOut, Tty: o.TTY, }) } Kubelet 端处理 func (h *ExecHandler) serveExec(w http.ResponseWriter, req *http.Request) { // 获取容器 ID containerID := podContainer.ContainerID // 通过 CRI 执行命令 execRequest := &amp;runtimeapi.ExecRequest{ ContainerId: containerID.ID, Cmd: cmd, Tty: tty, Stdin: stdin, Stdout: stdout, Stderr: stderr, } // 调用容器运行时 runtimeService.Exec(execRequest) } 7. 容器运行时差异 Docker // 使用 Docker Engine API client.ContainerExecCreate() client.ContainerExecAttach() Containerd // 使用 CRI 插件 task.Exec() 8. 故障排查要点 权限问题: 检查 RBAC 配置 网络连通性: API Server ↔ Kubelet 网络 容器状态: 目标容器必须处于 Running 状态 资源限制: 容器资源是否充足 安全策略: Pod Security Policies 限制 这种设计使得 kubectl exec 能够在分布式环境中安全、可靠地执行容器内命令，同时保持了良好的用户体验。</description>
    </item>
    <item>
      <title>QoS 详解</title>
      <link>https://ops.docs.72602.space/using/k8s/qos/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/qos/index.html</guid>
      <description>Kubernetes QoS (Quality of Service) 等级详解 QoS 等级是 Kubernetes 用来管理 Pod 资源和在资源不足时决定驱逐优先级的机制。&#xA;🎯 三种 QoS 等级 Kubernetes 根据 Pod 的资源配置自动分配 QoS 等级,共有三种:&#xA;1. Guaranteed (保证型) - 最高优先级 2. Burstable (突发型) - 中等优先级 3. BestEffort (尽力而为型) - 最低优先级 📊 QoS 等级详解 1️⃣ Guaranteed (保证型) 定义条件(必须同时满足) Pod 中每个容器(包括 Init 容器)都必须设置 requests 和 limits 对于每个容器,CPU 和内存的 requests 必须等于 limits YAML 示例 apiVersion: v1 kind: Pod metadata: name: guaranteed-pod spec: containers: - name: app image: nginx resources: requests: memory: &#34;200Mi&#34; cpu: &#34;500m&#34; limits: memory: &#34;200Mi&#34; # 必须等于 requests cpu: &#34;500m&#34; # 必须等于 requests 特点 ✅ 资源保证:Pod 获得请求的全部资源,不会被其他 Pod 抢占&#xA;✅ 最高优先级:资源不足时最后被驱逐&#xA;✅ 性能稳定:资源使用可预测,适合关键业务&#xA;✅ OOM 保护:不会因为节点内存压力被 Kill(除非超过自己的 limit)</description>
    </item>
    <item>
      <title>Scheduler</title>
      <link>https://ops.docs.72602.space/using/k8s/scheduler/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/scheduler/index.html</guid>
      <description>Kubernetes 调度器（kube-scheduler） 是整个系统中非常关键的组件，它负责决定 哪个 Pod 应该运行在哪个 Node 上。&#xA;下面我会分层、逐步详细说明 K8s 调度流程（以 v1.28+ 为例），并解释背后机制。&#xA;🌐 整体架构概览 Kubernetes 调度器主要完成以下职责：&#xA;监听待调度的 Pod（即 spec.nodeName 为空的 Pod） 为 Pod 选择最合适的 Node 将绑定结果写回到 apiserver 🧩 一、调度总体流程 Kubernetes 调度流程主要分为三个阶段：&#xA;[Pending Pod] --&gt; [Scheduling Queue] ↓ [PreFilter] → [Filter] → [PostFilter] → [Score] → [Reserve] → [Permit] → [Bind] 1️⃣ 调度入口：监听未绑定的 Pod Scheduler 通过 informer 监听所有 Pod 资源。 当发现 Pod 没有 spec.nodeName 时，认为它是待调度的。 Pod 被放入 调度队列（SchedulingQueue） 中。 🧮 二、调度核心阶段详解 🧩 1. PreFilter 阶段 在调度之前，对 Pod 进行一些准备性检查，例如：</description>
    </item>
    <item>
      <title>服务发现</title>
      <link>https://ops.docs.72602.space/using/k8s/service_discovery/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/service_discovery/index.html</guid>
      <description>最常见的说法是 “两种核心机制”，但这指的是服务发现的两种基本模式，而不是具体的实现方式。&#xA;维度一：两种核心模式 这是从服务发现的基本原理上划分的。&#xA;基于客户端服务发现&#xA;工作原理：客户端（服务消费者）通过查询一个中心化的服务注册中心（如 Consul、Eureka、Zookeeper）来获取所有可用服务实例的列表（通常是 IP 和端口），然后自己选择一个实例并直接向其发起请求。 类比：就像你去餐厅吃饭，先看门口的电子菜单（服务注册中心）了解所有菜品和价格，然后自己决定点什么，再告诉服务员。 特点：客户端需要内置服务发现逻辑，与服务注册中心耦合。这种方式更灵活，但增加了客户端的复杂性。 基于服务端服务发现&#xA;工作原理：客户端不关心具体的服务实例，它只需要向一个固定的访问端点（通常是 Load Balancer 或 Proxy，如 Kubernetes Service）发起请求。这个端点负责去服务注册中心查询可用实例，并进行负载均衡，将请求转发给其中一个。 类比：就像你去餐厅直接告诉服务员“来份招牌菜”，服务员（负载均衡器）帮你和后厨（服务实例）沟通，最后把菜端给你。 特点：客户端无需知道服务发现的具体细节，简化了客户端。这是 Kubernetes 默认采用的方式。 维度二：Kubernetes 中具体的实现方式 在 Kubernetes 内部，我们通常讨论以下几种具体的服务发现实现手段，它们共同构成了 Kubernetes 强大的服务发现能力。&#xA;1. 环境变量 当 Pod 被调度到某个节点上时，kubelet 会为当前集群中存在的每个 Service 添加一组环境变量到该 Pod 中。&#xA;格式：{SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT。 例子：一个名为 redis-master 的 Service 会生成 REDIS_MASTER_SERVICE_HOST=10.0.0.11 和 REDIS_MASTER_SERVICE_PORT=6379 这样的环境变量。 局限性：环境变量必须在 Pod 创建之前就存在。后创建的 Service 无法将环境变量注入到已运行的 Pod 中。因此，这通常作为辅助手段。 2. DNS（最核心、最推荐的方式） 这是 Kubernetes 最主要和最优雅的服务发现方式。&#xA;工作原理：Kubernetes 集群内置了一个 DNS 服务器（通常是 CoreDNS）。当你创建一个 Service 时，Kubernetes 会自动为这个 Service 注册一个 DNS 记录。 DNS 记录格式： 同一命名空间：&lt;service-name&gt;.&lt;namespace&gt;.svc.cluster.local -&gt; 指向 Service 的 Cluster IP。 在同一个命名空间内，你可以直接使用 &lt;service-name&gt; 来访问服务。例如，前端 Pod 访问后端服务，只需使用 http://backend-service。 不同命名空间：需要使用全限定域名，例如 backend-service.production.svc.cluster.local。 优点：行为符合标准，应用无需修改代码，直接使用域名即可访问其他服务。 3. Kubernetes Service Service 资源对象本身就是服务发现的载体。它提供了一个稳定的访问端点（VIP 或 DNS 名称），背后对应一组动态变化的 Pod。</description>
    </item>
    <item>
      <title>Service VS Endpoint</title>
      <link>https://ops.docs.72602.space/using/k8s/service_vs_endpoint/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/service_vs_endpoint/index.html</guid>
      <description>Service 和 Endpoint/EndpointSlice 在 Kubernetes 中有明确的功能分工，它们共同构成了服务发现和负载均衡的基础。以下是详细的区别分析：&#xA;一、核心功能定位 Service - 抽象服务层 apiVersion: v1 kind: Service metadata: name: web-service spec: selector: app: web-server ports: - protocol: TCP port: 80 # 服务端口 targetPort: 8080 # 后端 Pod 端口 type: ClusterIP # 服务类型 Service 的核心功能：&#xA;服务抽象：提供稳定的虚拟 IP 和 DNS 名称 访问入口：定义客户端如何访问服务 负载均衡策略：指定流量分发方式 服务类型：ClusterIP、NodePort、LoadBalancer、ExternalName Endpoint/EndpointSlice - 后端实现层 apiVersion: v1 kind: Endpoints metadata: name: web-service # 必须与 Service 同名 subsets: - addresses: - ip: 10.244.1.5 targetRef: kind: Pod name: web-pod-1 - ip: 10.244.1.6 targetRef: kind: Pod name: web-pod-2 ports: - port: 8080 protocol: TCP Endpoints 的核心功能：</description>
    </item>
    <item>
      <title>StatefulSet</title>
      <link>https://ops.docs.72602.space/using/k8s/sts/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/sts/index.html</guid>
      <description>StatefulSet 如何具体解决有状态应用的挑战&#xA;StatefulSet 的四大核心机制 StatefulSet 通过一系列精心设计的机制，为有状态应用提供了稳定性和可预测性。&#xA;1. 稳定的网络标识 解决的问题：有状态应用（如数据库节点）需要稳定的主机名来相互发现和通信，不能使用随机名称。&#xA;StatefulSet 的实现：&#xA;固定的 Pod 名称：Pod 名称遵循固定模式：&lt;statefulset-name&gt;-&lt;ordinal-index&gt;。 例如：redis-cluster-0，redis-cluster-1，redis-cluster-2 稳定的 DNS 记录：每个 Pod 都会自动获得一个唯一的、稳定的 DNS 记录： 格式：&lt;pod-name&gt;.&lt;svc-name&gt;.&lt;namespace&gt;.svc.cluster.local 例子：redis-cluster-0.redis-service.default.svc.cluster.local 应对场景：&#xA;在 Redis 集群中，redis-cluster-0 可以告诉 redis-cluster-1：“我的地址是 redis-cluster-0.redis-service&#34;，这个地址在 Pod 的一生中都不会改变，即使它被重新调度到其他节点。 2. 有序的部署与管理 解决的问题：像 Zookeeper、Etcd 这样的集群化应用，节点需要按顺序启动和加入集群，主从数据库也需要先启动主节点。&#xA;StatefulSet 的实现：&#xA;有序部署：当创建 StatefulSet 时，Pod 严格按照索引顺序（0, 1, 2…）依次创建。必须等 Pod-0 完全就绪（Ready）后，才会创建 Pod-1。 有序扩缩容： 扩容：按顺序创建新 Pod（如从 3 个扩展到 5 个，会先创建 pod-3，再 pod-4）。 缩容：按逆序终止 Pod（从 pod-4 开始，然后是 pod-3）。 有序滚动更新：同样遵循逆序策略，确保在更新过程中大部分节点保持可用。 应对场景：&#xA;部署 MySQL 主从集群时，StatefulSet 会确保 mysql-0（主节点）先启动并初始化完成，然后才启动 mysql-1（从节点），从节点在启动时就能正确连接到主节点进行数据同步。 3. 稳定的持久化存储 这是 StatefulSet 最核心的特性！</description>
    </item>
    <item>
      <title>StatefulSet 2</title>
      <link>https://ops.docs.72602.space/using/k8s/sts2/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/sts2/index.html</guid>
      <description>答案是：&#xA;❌ StatefulSet 不使用 ReplicaSet 来创建 Pod。 ✅ StatefulSet Controller 直接创建并管理 Pod 对象，而且每个 Pod 都是有序的、具名的、不可替代的。&#xA;接下来我会详细讲清楚 StatefulSet 与 Deployment 的架构差异、实现机制、核心控制循环，让你能在实现 Operator 或高可靠应用时真正理解它的行为。&#xA;🧩 一、StatefulSet 与 Deployment 的根本区别 项目 Deployment StatefulSet 控制下层对象 ReplicaSet → Pod 直接管理 Pod Pod 命名 随机 固定命名（有序索引） Pod 身份 可替换 唯一、持久身份（Stable Identity） 更新策略 滚动更新（无序） 有序更新（从 0 开始逐个） 存储 通常无状态 绑定 PVC，数据与 Pod 一一对应 常见场景 Web 服务、API、Job 数据库、Zookeeper、Kafka、Etcd 等 ⚙️ 二、StatefulSet 控制器工作原理 StatefulSet Controller 运行在 kube-controller-manager 中。 它同样是一个典型的 Controller + Informer + WorkQueue + Reconcile Loop 架构。</description>
    </item>
    <item>
      <title>Talk between 2 pods in different nodes</title>
      <link>https://ops.docs.72602.space/using/k8s/talk_between_2_pods/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/talk_between_2_pods/index.html</guid>
      <description>好的，这是一个非常核心的 Kubernetes 网络问题。不同 Node 上的 Pod 之间的通信过程，清晰地展示了 Kubernetes 网络模型的核心思想：每个 Pod 都拥有一个独立的、扁平的 IP 地址空间，无论它运行在哪个节点上，Pod 之间都可以直接通过这个 IP 进行通信，而无需使用 NAT。&#xA;这个过程的实现完全依赖于容器网络接口（CNI）插件，如 Calico、Flannel、Weave Net 等。下面我们以最经典的 Flannel (VXLAN 模式) 和 Calico (BGP 模式) 为例，来阐述这个通信过程。&#xA;核心原则 Pod IP 可达性：Kubernetes 网络模型要求，任何 Pod 的 IP 地址都能被任何其他 Pod 直接访问，无论它们是否在同一个节点上。 无 NAT：Pod 到 Pod 的通信不应该经过源地址转换（SNAT）或目的地址转换（DNAT）。Pod 看到的源 IP 和目标 IP 就是真实的 Pod IP。 通用通信流程（抽象模型） 假设有两个 Pod：&#xA;Pod A：在 Node 1 上，IP 为 10.244.1.10 Pod B：在 Node 2 上，IP 为 10.244.2.20 当 Pod A 试图 ping Pod B 的 IP (10.244.2.20) 时，过程如下：</description>
    </item>
    <item>
      <title>Talk with API Server</title>
      <link>https://ops.docs.72602.space/using/k8s/talk_with_api-server/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/using/k8s/talk_with_api-server/index.html</guid>
      <description>Kubernetes 各模块与 API Server 通信详解 这是理解 Kubernetes 架构的核心问题。API Server 是整个集群的&#34;大脑&#34;,所有组件都通过它进行通信。&#xA;🎯 Kubernetes 通信架构总览 ┌─────────────────────────────────────────────────────────┐ │ API Server (核心) │ │ - RESTful API (HTTP/HTTPS) │ │ - 认证、授权、准入控制 │ │ - etcd 唯一入口 │ └───────┬─────────────────┬─────────────────┬─────────────┘ │ │ │ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐ │Kubelet│ │Scheduler│ │Controller│ │(Node) │ │ │ │ Manager │ └───────┘ └─────────┘ └──────────┘ │ ┌───▼────┐ │kube-proxy│ └────────┘ 🔐 通信基础:认证、授权、准入 1. 认证 (Authentication) 所有组件访问 API Server 必须先通过认证。&#xA;常见认证方式 认证方式 使用场景 实现方式 X.509 证书 集群组件(kubelet/scheduler) 客户端证书 ServiceAccount Token Pod 内应用 JWT Token Bootstrap Token 节点加入集群 临时 Token 静态 Token 文件 简单测试 不推荐生产 OIDC 用户认证 外部身份提供商 X.509 证书认证示例 # 1. API Server 启动参数包含 CA 证书 kube-apiserver \ --client-ca-file=/etc/kubernetes/pki/ca.crt \ --tls-cert-file=/etc/kubernetes/pki/apiserver.crt \ --tls-private-key-file=/etc/kubernetes/pki/apiserver.key # 2. Kubelet 使用客户端证书 kubelet \ --kubeconfig=/etc/kubernetes/kubelet.conf \ --client-ca-file=/etc/kubernetes/pki/ca.crt # 3. kubeconfig 文件内容 apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: /etc/kubernetes/pki/ca.crt # CA 证书 server: https://192.168.1.10:6443 # API Server 地址 name: kubernetes users: - name: system:node:worker-1 user: client-certificate: /var/lib/kubelet/pki/kubelet-client.crt # 客户端证书 client-key: /var/lib/kubelet/pki/kubelet-client.key # 客户端密钥 contexts: - context: cluster: kubernetes user: system:node:worker-1 name: default current-context: default ServiceAccount Token 认证 # Pod 内自动挂载的 Token cat /var/run/secrets/kubernetes.io/serviceaccount/token # eyJhbGciOiJSUzI1NiIsImtpZCI6Ij... # 使用 Token 访问 API Server TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) curl -k -H &#34;Authorization: Bearer $TOKEN&#34; \ https://kubernetes.default.svc/api/v1/namespaces/default/pods 2. 授权 (Authorization) 认证通过后,检查是否有权限执行操作。</description>
    </item>
  </channel>
</rss>