Luckyxyz - Kubernetes
type: channel
link: https://xyzttt.xyz/tag/Kubernetes/
items: 【Kubernetes】工作负载整体操作逻辑
items: openFuyao v25.09 部署实践
items: 快速上手 Kubernetes 管理平台的方法论
items: 【Pod】Pod 容器共享 Volume
items: 【Pod】Pod 定义与基本用法
items: 【Pod】静态 Pod
items: 【Kubernetes】kubectl 命令行工具用法
items: 【Kubernetes】Job、Volume、PV、Namespace、Annotation、ConfigMap
items: 【Kubernetes】Service
items: 【Kubernetes】StatefulSet

【Kubernetes】工作负载整体操作逻辑
type: item
date: 2025-11-24T16:38:00+08:00
description: 在做算力容器平台的过程中，遇到哪些需要做页面功能、哪些不需要的困惑，经过调研和学习，目前整理出关于工作负载：Pod、Deployment、StatefulSet、DaemonSet、Job、CronJob 的逻辑关系如下，在此进行梳理，以便自己理解进行定义设计： # 工作负载整体操作逻辑 ## 核心逻辑 ![核心逻辑](https://cdn-imagehost.xyzttt.xyz/image/2025/11/21/raoziv.webp) ## 树形图 ![树形图](https://cdn-imagehost.xyzttt.xyz/image/2025/11/24/qymh3v.webp) ## 流程图 ![流程图](https://cdn-imagehost.xyzttt.xyz/image/2025/11/24/o4830h.webp) # References - claude sonnet 4.5

openFuyao v25.09 部署实践
type: item
date: 2025-11-19T13:36:00+08:00
description: # 安装须知 详见连接：https://docs.openfuyao.cn/docs/Cluster_API_Installation/Before_You_Start # 安装包完整性校验 https://docs.openfuyao.cn/docs/Cluster_API_Installation/Installation_Package_Integrity_Verification # 环境准备 本次实践使用虚拟机作为节点进行部署配置 ## 引导节点 创建一个 4c8g 512GiB 的虚拟机 vm-1318 deployment 并安装系统 DHCPv4 10.17.36.49/22 ## 业务集群节点 创建一个 8c16g 512GiB 的虚拟机 vm-1319 master 并安装系统 DCHPv4 10.17.36.50/22 # 安装准备 ## 在引导节点上，下载并自动化安装 BKE 工具 ```bash curl -sfL https://openfuyao.obs.cn-north-4.myhuaweicloud.com/openFuyao/bkeadm/releases/download/v25.09/download.sh | bash ``` 可能会没有操作权限，使用 `sudo` 命令可以解决 ```bash curl -sfL https://openfuyao.obs.cn-north-4.myhuaweicloud.com/openFuyao/bkeadm/releases/download/v25.09/download.sh | sudo bash ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qhfm9i.webp) ## 初始化引导集群 该步骤会在引导节点上部署一个轻量级的 K3s 集群，集群会部署 cluster-api、provider-bke 以及 openFuyao 安装部署相关的 Pod ```bash bke init --otherRepo cr.openfuyao.cn/openfuyao/bke-online-installed:v25.09 ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qigwav.webp) 老问题，还是要 `sudo` ```bash sudo bke init --otherRepo cr.openfuyao.cn/openfuyao/bke-online-installed:v25.09 ``` ## 查看引导集群上部署的 Pod ```bash sudo kubectl get pod -A ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qkwi40.webp) 所有 Pod 状态正常后，则引导集群安装完毕，可以继续登录openFuyao引导节点的管理面进行[业务集群的安装](https://docs.openfuyao.cn/docs/Cluster_API_Installation/Service_Cluster_Installation_on_the_Management_Plane)。 # 登录引导节点的 openFuyao 管理面 ## 引导节点登录 https:// 引导节点 IP 地址: 30010 **说明：** > - 首次登录时，用户名为 admin，密码为 test@1234。首次登录后需要修改用户名和密码。 > - 引导节点的 openFuyao 管理面使用 https 协议，web 服务端口默认为 30010 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qn994b.webp) ## 新增集群 ### 集群基本信息配置 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qs35n3.webp) ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qs65k7.webp) - 单击右下角的【一键校验】 - 校验成功后，单击下方的【创建】，单击【创建】即可下发业务集群的创建任务。 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/11/18/qsqi9a.webp) 日志滚动完成，集群部署失败 ![image](https…

快速上手 Kubernetes 管理平台的方法论
type: item
date: 2025-11-13T10:21:00+08:00
description: 最近准备调研一个 Kubernetes 管理平台，所以找 claude 帮我整理了一下架构。以下为 Claude 返回的内容，因为不想一直停留在 Cluade 的页面，所以以下内容仅供我本人参考。 --- 根据你提供的侧边栏结构，我给你一个系统化的调研方案： ## 一、建立知识体系框架（先理解 K8s 本身） 在深入平台前，需要理解 Kubernetes 的核心概念： ``` 资源层次关系： 集群 → 命名空间 → 工作负载/服务/配置 → Pod/容器 ``` ## 二、模块分层梳理法 ### 1️⃣ **第一层：资源管理（核心）** 这是平台的主体功能，按照以下顺序理解： ``` 工作负载（计算资源） ├─ Pod（最小单元） ├─ Deployment（无状态应用）⭐ ├─ StatefulSet（有状态应用）⭐ ├─ DaemonSet（节点守护进程） ├─ Job/CronJob（任务调度） 网络（服务访问） ├─ Service（服务发现）⭐ └─ Ingress（外部访问入口）⭐ 存储（数据持久化） ├─ PV（持久卷） ├─ PVC（持久卷声明）⭐ └─ StorageClass（存储类） 配置与密钥（配置管理） ├─ ConfigMap（配置文件）⭐ └─ Secret（敏感信息）⭐ 命名空间（资源隔离）⭐ ├─ Namespace ├─ LimitRange（资源限制） └─ ResourceQuota（配额管理） ``` ### 2️⃣ **第二层：应用市场/管理** - **应用市场**：应用模板/Helm Chart 管理 - **应用管理**：应用生命周期管理 - **扩展组件管理**：插件/附加组件 ### 3️⃣ **第三层：运维功能** - **监控中心**：指标监控、自定义面板 - **告警**：告警规则配置 - **事件**：集群事件日志 - **算力优化中心**（NUMA亲和调度等） ## 三、核心关联关系图 ![mermaid-diagram-2025-11-13-102843](https://cdn-imagehost.xyzttt.xyz/image/2025/11/13/h0ywwj.webp) ## 四、快速上手实操路径 ### 🎯 第一周：核心功能实操 1. **创建命名空间** → 理解资源隔离 2. **部署 Deployment** → 理解无状态应用 3. **创建 Service** → 理解服务暴露 4. **配置 Ingress** → 理解外部访问 5. **使用 ConfigMap** → 理解配置分离 ### 🎯 第二周：进阶功能 6. **部署 StatefulSet + PVC** → 理解有状态应用 7. **配置资源配额** → 理解资源管理 8. **查看监控和日志** → 理解可观测性 9. **尝试应用市场** → 理解快速部署 ### 🎯 第三周：联动关系 10. 追踪一个完整应用的部署链路 11. 修改配置观察联动效果 12. 模拟故障观察自愈机制 ## 五、整理平台架构的具体方法 ### 📋 方法1：功能清单法 创建表格记录： | 模块 | 子功能 | 对应K8s资源 | 关联模块 | 核心程度 | |------|--------|-------------|----------|----------| | 工作负载 | Deployment | Deployment | Service, ConfigMap, PVC | ⭐⭐⭐ | | 网络 | Service | Service | Pod, Ingress | ⭐⭐⭐ | ### 📋 方法2：流程图法 针对核心场景绘制流程： - **应用部署流程** - **服务访问流程** - **存储挂载流程** - **配置更新流程** ### 📋 方法3：思维导图法 以"资源类型"为中心节点，扩展： - 创建方式 - 配置项 - 关联资源 - 常见问题 ### 📋 方法4：对比学习法 | 功能 | Kuboard实现 | 原生kubectl命令 | Dashboard实现 | |------|------------|----------------|--------------| | 创建Deployment | 表单化 | `kubectl create` | 可视化 | ## 六、核心联动关系重点 ### 🔗 强关联（必须配合使用） 1. **Deployment → Pod** （控制关系） 2. **Service → Pod** （通过 Label Selector） 3. **Ingress → Service** （路由规则） 4. **Pod → ConfigMap…

【Pod】Pod 容器共享 Volume
type: item
date: 2025-03-17T16:13:00+08:00
description: 同一个 Pod 中的多个容器能够共享 Pod 级别的存储卷 Volume。Volume 可以被定义为各种类型，多个容器各自进行挂载操作，将一个 Volume 挂载为容器内部需要的目录 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/03/14/nqed5a.webp) # 多容器协作实践解析 Pod 内包含两个容器：tomcat 和 busybox，在 Pod 级别设置 Volume"apps-logs"，用于 tomcat 向其中写日志文件，busybox 读日志文件 ```yaml apiVersion: v1 kind: Pod metadata: name: volume-pod spec: containers: - name: tomcat # 第一个容器（主容器）tomcat image: tomcat # 使用 tomcat 镜像 ports: - containerPort: 8080 # 容器内部端口 volumeMounts: - name: app-logs # 挂载的卷名称 mountPath: /usr/local/tomcat/logs # 挂载到容器内的路径（tomecat 的日志目录 - name: busybox # 第二个容器（sidecar 容器）busybox image: busybox # 使用 busybox 镜像 command: ["sh", "-c", "tail -f /logs/catalina*.log"] # 持续监控日志文件 volumeMounts: - name: app-logs # 挂载同名卷 mountPath: /logs # 挂载到容器内的路径 volumes: - name: app-logs # 卷名称 emptyDir: {} # 使用 emptyDir 类型的卷 ``` ## 配置的主要功能和特点 ### 多容器协作 - 一个 Pod 中运行两个容器：tomcat 和 busybox - 两个容器通过共享卷进行通信 ### 日志收集方案 - tomcat 容器产生日志 - busybox 容器实时读取这些日志 ### 数据共享 - 使用 `emptyDir` 卷类型 - 这是一个临时存储，如果 Pod 删除 数据会丢失 - 两个容器可以同时访问这个共享存储 ### 实际应用场景 - 典型的 日志收集模式 - 用于监控、调试或日志转发 ## 角色定位（读写关系如何确定的） 发出一个疑问，为什么是 tomcat 写入，busybox 读取，为什么不能是 busybox 写入，tomcat 读取。 是因为 tomcat 是一个 Web 应用服务器，在运行的过程中自然会产生日志文件（如 catalina.ouot、localhost_access_log 等），这是 tomcat 的固有功能 busybox 在这个例子中，使用 `tail -f` 命令，这是一个读取命令，用于实时查看文件内容。 实际上从技术上讲确实可以反过来，但这不符合容器的设计目的： - tomcat 容器的主要职责是运行 Web 应用并自动生成日志 - busybox 容器在这里扮演一个工具容器的角色，用于监控日志 这种设计遵循 “单一职责原则”： - tomcat 容器专注于运行 web 应用 - busybox 容器专注于日志监控 - 每个容器都在做最适合他的事情

【Pod】Pod 定义与基本用法
type: item
date: 2025-03-14T14:12:00+08:00
description: # Pod 定义 YAML 格式的 Pod 定义文件完整内容如下： ```yaml apiVersion: v1 # Pod API 版本，v1 是稳定版，String，必选 kind: Pod # 资源类型为 Pod，String，必选 metadata: # 元数据定义，Object，必选 name: string # Pod 的名称，必选，命名规范需要符合 RFC 1035 规范，metadata.name namespace: string # Pod 所属的命名空间，默认值为 default，必选，metadata.namespace labels: # 标签定义 key: value # 标签是 key-value 格式 annotations: # 注解定义 key: value # 注解是 key-value 格式 spec: # Pod 规格定义，object，必选 containers: # 容器定义，是一个数组，必选，spec.containers[] - name: string # 容器名称，必选，spec.containers[].name image: string # 容器镜像，必选，spec.containers[].image imagePullPolicy: Always # 镜像拉取策略：Always、Never、IfNotPresent # Always：每次都尝试重新拉取镜像 # IfNotPresent：如果本地有该镜像，则使用本地的镜像，本地不存在时拉取镜像 # Never：仅使用本地镜像 # 如果包含以下设置，系统将默认设置 imagePullPolicy=Always： # 不设置 imagePullPolicy，也未指定镜像的 tag # 不设置 imagePullPolicy，镜像 tag 为 latest # 启用名为 AlwaysPullImages 的准入控制器（Admission Controller） command: ["string"] # 容器启动命令，如果不指定则使用镜像打包时使用的启动命令 args: ["string"] # 容器的启动命令参数列表 workdingDir: string # 容器的工作目录 volumeMounts: # 卷挂载定义，挂载到容器内部的存储卷配置 - name: string # 挂载卷名称，引用 Pod 定义的共享存储卷的名称，需要使用 volumes[]部分定义的共享存储卷名称 mountPath: string # 挂载路径，存储卷在容器内 Mount 的绝对路径，应少于 512 个字符 readOnly: false # 是否为只读模式，默认为读写 ports: # 端口定义，容器需要暴露的端口号列表 - name: string # 端口名称 containerPort: 80 # 容器需要监听的端口号 hostPort: 80 # 主机端口，容器所在主机需要监听的端口号，默认与 containerPort 想通，设置 hostPath 时，同一台宿主机将无法启动该容器的第 2 份副本 protocol: TCP # 端口协议，TCP/UDP/SCTP，默认值为 TCP env: # 环境变量定义 - name: string # 环境变量名 value: string # 环境变量值 resources: # 资源限制和资源请求的设置 limits: # 资源限制的设置（资源上限） cpu: "1" # CPU 限制，单位为 core 数，将用于 docker run --cpu-shares 参数 memory: "256Mi" # 内存限制，单位可以为 MiB、GiB 等，将用于 docker run -- memory 参数 requeests: # 资源请求 cpu: "500m" # CPU 请求，单位为 core 数，容器启动的初始可用数量 memory: "128Mi" # 内存请求，单位可以为 MiB、GiB 等，容器启动的初始可用数量 livenessProbe: # 存活探针 exec: # 执行命令检查，对 Pod 内各容器健康检查的设置，exec 方式 command: ["string"] # exec 方式需要指定的命令或者脚本 httpGet: # HTTP GET 检查，object， path: string port: 80 host: string scheme: HTTP # HTTP/HTTPS httpHeaders: # HTTP 同 - name: string value: string topSocket: # TCP 端口检查，对 Pod 内各容器健康检…

【Pod】静态 Pod
type: item
date: 2025-03-14T14:12:00+08:00
description: 静态 Pod 由 kubelet 管理的仅存在于特定 Node 上的 Pod。他们不能通过 API Server 进行管理，无法与 RC、Deployment 或者 DaemonSet 进行关联，并且 kubelet 无法对他们进行健康检查。 静态 Pod 是 由 kubectl 创建，并总在 kubelet 所在的 Node 上运行。 # 创建静态 Pod - 配置文件方式 设置 kubelet 的启动参数 `--config`，指定 kubelet 需要监控的配置文件所在的目录，kubelet 会定期扫描该目录，并根据该目录下的 `.yaml` 或 `.json` 文件进行创建操作。 假设配置目录为 `/etc/kubelet.d`，配置启动参数为 `--config=/etc/kubelet.d/` ，然后重启 kubelet 服务。 `--config=/etc/kubelet.d/` 适用于指定 kubelet 配置文件的参数，不是静态 Pod 的配置文件内容。kubelet 会从该目录中读取配置文件来启动和管理 Pod，这个参数通常用于配置 kubelet 的行为，而不是直接管理静态 Pod ## 静态 Pod 实践 ### 检查 kubelet 启动参数 确保 kubelet 启动时指定了 `--pod-manifest-path` 参数，该参数指向静态 Pod 的配置文件目录（/etc/kubelet.d/） 查看 kubelet 启动参数： ```bash ps aux | grep kubelet ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/03/13/nxr5y3.webp) 从上面的参数中可以看到，kubelet 使用了 `--config=/etc/kubernetes/kubelet-confg.yaml` 来指定配置文件，而不是直接通过命令行参数配置静态 Pod 的路径。因为需要在 `kubelet-config.yaml` 文件中配置静态 Pod 的路径。 但是目前不想要更改目录，所以不更改 kubelet-config.yaml 的配置内容。 ### 创建静态 Pod 的配置文件 在 `/etc/kubernetes/manifests/` 目录中创建静态 Pod 的 YAML 文件。 ```bash sudo vim /etc/kubernetes/manifests/static-web.yaml ``` 配置文件内容： ```yaml apiVersion: v1 kind: Pod metadata: name: static-web labels: name: static-web spec: containers: - name: static-web image: dockerio.vkus1.skybyte.me/library/nginx ports: - name: web containerPort: 80 ``` 执行 `kubectl get pods` 可以看到 刚刚创建的 Pod static-web。 ### 静态 Pod 命名规则 `-` 静态 Pod 无法通过 API Server 直接管理，所以在 Master 上尝试删除这个 Pod 时，会使其变成 `Pending` 且不会被删除。 删除该 Pod 的操作只能到期所在的 Node 上 将其定义文件 static-web.yaml 从 目录中删除 # 创建静态 Pod - HTTP 方式 通过设置 kubelet 的启动参数 `--manifest-url`，kubelet 将会定期从该 URL 地址下载 Pod 的定义文件，并以 `.yaml` 或 `.json` 文件的格式进行解析，然后创建 Pod。 其实现方式与配置文件方式是一致的 # References - claude 3.5 sonnet - DeepSeek-V3 - Kubernetes 权威指南：从 Docker 到 Kubernetes 实践全接触（第 4 版）

【Kubernetes】kubectl 命令行工具用法
type: item
date: 2025-03-12T13:39:00+08:00
description: # kubectl 用法概述 kubectl 命令行的语法如下： ```bash kubectl [command] [TYPE] [NAME] [flags] ``` - `command`：子命令，用于操作 Kubernetes 集群资源对象的命令，如 create、delete、describe、get、apply 等 - `TYPE`：资源对象的类型，区分大小写，能以单数。复数或简写形式表示，如，以下三种 TYPE 是等价的： ```bash kubectl get pod pod1 kubectl get pods pod1 kubectl get po pod1 ``` - `NAME`：资源对象的名称，区分大小写，如果不指定名称，系统则将返回属于 TYPE 的全部对象的列表 - `flags`：kubectl 子命令的可选参数，如使用 `-s` 指定 API Server 的 URL 地址而不用默认值 # kubectl 可操作的资源对象类型 及其缩写 | 资源对象类型 | 缩写 | 资源对象类型 | 缩写 | | ------------------------ | ------ | ---------------------- | ----- | | cluster | | statefulsets | | | componentstatuses | cs | persistentvolumeclaims | pvc | | configmaps | cm | persistentvolumes | pv | | daemonsets | ds | pods | po | | deployments | deploy | podsecuritypolicies | psp | | endpoints | ep | podtemplates | | | events | eb | replicasets | rs | | horizontalpodautoscalers | hpa | replicationcontrollers | rc | | ingresses | ing | resourcequotas | quota | | Jobs | | cronjob | | | limitranges | limits | secrets | | | nodes | no | serviceaccounts | | | namespaces | ns | services | svc | | networkpolicies | | storageclasses | sc | | nodes | no | thirdpartyresources | | 在一个命令行中也可以同时对多个资源对象进行操作，以多个 TYPE 和 NAME 的组合表示，eg. 获取多个 Pod 的信息： ```bash kubectl get pods pod1 pod2 ``` 获取多种对象的信息： ```bash kubectl get pod/pod1 rc/rc1 ``` 同时应用多个 YAML 文件，以多个 `-f file` 参数表示： ```bash kubectl get pod -f pod1.yaml -f pod2.yaml kubectl create -f pod1.yaml -f rcl.yaml -f servicel.yaml ``` # kubectl 子命令详解 常用的 kubectl 子命令： | 子命令 | 语法 | 说明 | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | | apply | kubectl apply -f FILENAME [flags] | 从配置文件或 stdin 中对资源对象进行配置更新 | | get | kubectl get [资源类型] [NAME] [flags] | 显示一个或多个资源的信息 | | describe | kubectl describe [资源类型] [NAME] [flags] | 显示特定资源或资源组的详细信息 | | delete | kubectl delete [资源类型] [NAME] [flags] | 从文件、stdin 或指定标签选…

【Kubernetes】Job、Volume、PV、Namespace、Annotation、ConfigMap
type: item
date: 2025-03-11T15:59:00+08:00
description: # Job 批处理任务通常并行（或者串行）启动多个计算机进程去处理一批工作项（work item），在处理完成后，整个批处理任务结束。 Kubernetes 支持批处理类型的应用，可以通过 Kubernetes Job 这种新的资源对象定义并启动一个 批处理任务 Job。 与 RC、Deployment、RS、DaemonSet 类似，Job 也控制一组 Pod 容器。Job 也是一种特殊的 Pod 副本自动控制器，同时 Job 控制 Pod 副本与 RC 等控制器工作机制有以下差别 ## Job 控制的 Pod 副本是短暂运行的 可以将 Job 视为一组 Docker 容器，其中的每个 Docker 容器都仅仅运行一次，当 Job 控制的所有 Pod 副本都运行结束时，对应的Job 也就结束了。 Job 生成的 Pod 副本是不能自动重启的，对应 Pod 副本的 RestartPoliy 都被设置为 `Never` 当对应 Pod 副本都执行完时，相应的 Job 也就完成了控制使命，即 Job 生成的 Pod 在 Kubernetes 中是短暂存在的。 ### 定时任务 CronJob 在 1.5 版本之后，提供了类似 crontab 的定时任务，CronJob，解决了某些批处理任务需要定时反复执行的问题。 ## Job 控制的 Pod 副本的工作模式能够多实例并行计算 如 TensorFlow 框架，可以将一个机器学习的计算任务分布到 10 台机器上，在每台机器上都运行一个 worker 执行计算任务。 ## Job 的常见使用场景 - 数据处理 / 迁移 - 批量计算 - CI/CD 流水线任务 - 一次性初始化工作 - 数据库架构更新 # Volume 存储卷 Volume 是 Pod 中能够被多个容器访问的共享目录。 Kubernetes 中的 Volume 被定义在 Pod 上，然后被一个 Pod 里的多个容器挂载到具体的文件目录下； Kubernetes 中的 Volume 与 Pod 的生命周期相同，但与容器的生命周期不相关，当容器终止或者重启时，Volume 中的数据也不会丢失； Kubernetes 支持多种类型的 Volume，如 GlusterFS、Ceph 等分布式文件系统。 ## Volume 的使用 现在 Pod 上生命一个 Volume，然后再容器里引用该 Volume 并挂载（Mount）到容器里的某个目录上。 ## Volume 实践 给之前的 Tomcat Pod 增加一个名为 datavol 的Volume，并且挂载到容器的 `/mydata-data/` 目录上。 可以追溯到之前创建 tomcat 的 deployment 配置文件是 tomcat-deployment.yaml ，使用 vim 进入配置文件编辑如下内容： ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: kubeguide/tomcat-app:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 resources: requests: cpu: "200m" memory: "256Mi" limits: cpu: "500m" memory: "512Mi" volumeMounts: # volumeMounts 在 container 层级下 - name: datavol mountPath: /mydata-data volumes: # volumes 在 spec 层级下，跟 containers 同级 - name: datavol emptyDir: {} ``` 更新deployment ```bash kubectl apply -f tomcat-deployment.yaml ``` 配置文件解析： - 在容器配置中添加了 `volumeMounts` 部分，指定挂载点 - 在 Pod 规格中添加了 `volumes` 部分，定义了一个 `emptyDir` 类型的卷。 - 这是一个临时存储，Pod 删除后数据会丢失，如果需要持久化存储，可以考虑使用 PersistentVolumeClaim（PVC） 和 Persis…

【Kubernetes】Service
type: item
date: 2025-03-10T14:45:00+08:00
description: # 概述 Service 服务是 Kubernetes 里的核心资源对象之一，Kubernetes 里的每个 Service 其实就是我们经常提到的 **微服务架构** 中的一个 **微服务**。 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/03/07/iqwl3j.webp) 如上图所示： - Kubernetes 的 Service 定义了一个服务的访问入口地址 - 前端的应用（Pod）通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例 - Service 与其后端 Pod 副本集群之间是通过 Label Selector 来实现无缝对接的 - RC 的作用是保证 Service 的服务能力 和 服务质量始终符合预期标准 # 简单来说 Service 是一个联通，一个 Pod 通过 Service 来找到应该对应的另一个 Pod # 网络通信 通过分析、识别并建模系统中的所有服务为微服务 -- Kubernetes Service，系统最终由多个提供不同业务能力而又彼此独立的微服务单元组成，服务之间通过 TCP/IP 进行通信，从而形成了强大而又灵活的弹性网格，拥有强大的分布式能力、弹性伸缩能力、容错能力，程序架构也变得简单和直观 ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/03/07/j0b5e0.webp) 既然每个 Pod 都会被分一个单独的 IP 地址，而且每个 Pod 都提供了一个独立的 Endpoint（Pod IP + ContainerPort）以被客户端访问，多个 Pod 副本组成了一个集群来提供服务。 ↓客户端访问方式↓ 部署一个负载均衡器（软件或硬件），为这组 Pod 开启一个对外的服务端口如 8000 端口，将这些 Pod 的 Endpoint 列表加入 8000 端口的转发列表，客户端就可以通过负载均衡器的对外 IP 地址 + 服务端口 来访问此服务 客户端的请求最后会被转发到哪个 Pod，由负载均衡器的算法所决定。 运行在每个 Node 上的 `kube-proxy` 进程其实就是一个智能的软件负载均衡器，负责对把 Service 的请求转发到后端的某个 Pod 实例上，并在内部实现服务的负载均衡与会话保持机制。 Service 没有共用一个负载均衡器的 IP 地址，每个 Service 都被分配了一个全局唯一的 `虚拟 IP 地址`，这个虚拟 IP 地址被称为 `Cluster IP`。 每个服务就变成了具备唯一 IP 地址的通信节点，服务调用就变成了最基础的 TCP 网络通信问题。 # 服务发现问题 Pod 的 Endpoint 地址会随着 Pod 的销毁和重新创建而发生改变，因为新的 Pod 的 IP 地址与之前旧的 Pod 的不同。 而 Service 一旦被创建，Kubernetes 就会自动为它分配一个可用的 Cluster IP，而在 Service 的整个生命周期内，他的 Cluster IP 不会改变。 只要用 Service 的 Name 与 Service 的 Cluster IP 地址做一个 DNS 域名映射，即可完美解决问题。 # Service 实践 ## 创建 Service 定义文件 ```bash touch tomcat-service.yaml ``` 配置文件内容如下： ```yaml apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 # 服务端口为 8080 selector: tier: frontend # 拥有 “tier=frontend” 这个 Label 的 所有 Pod 实例都属于他 ``` ## 创建 Service ```bash kubectl create -f tomcat-server.yaml ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/2025/03/07/qn5gny.webp) 在之前的实践中的 `tomcat-deployment.yaml` 里定义的 Tomcat 的 Pod 刚好拥有这个标签，所以刚才创建的 tomcat-service 已经对应一个 Pod 实例了。 ## 查看 tomcat-service 的 Endpoint 列表 ```bash kubectl get endpoints ``` ![image](https://cdn-imagehost.xyzttt.xyz/image/20…

【Kubernetes】StatefulSet
type: item
date: 2025-03-06T17:54:00+08:00
description: 在 Kubernetes 系统中， Pod 的管理对象 RC、Deployment、DaemonSet 和 Job 都面向 **无状态的服务**。 但现实中很多服务是有状态的，特别是一些复杂的中间件集群，例如 MySQL 集群、MongoDB 集群、Akka 集群、ZooKeeper 集群等，这些 **应用集群** 有 4 个共同点： - 每个节点都有固定的身份 ID，通过这个 ID，集群中的成员可以相互发现并通信； - 集群的规模是比较固定的，集群规模不能随意变动 - 集群中的每个节点都是有状态的，通常会持久化数据到永久存储中 - 如果磁盘损坏，则集群里的某个节点无法正常运行，集群功能受损。 # Pod 命名规则 注意，通过 RC 或者 Deployment 创建的 Pod 不是完全固定的： ## 通过 RC 创建的 Pod 命名为：`-xxxx` - RC 名称是固定部分 - xxxx 是随机生成的字符串 - 当 Pod 被删除重建时，随机字符串会改变 ## 通过 Deployment 创建的 Pod 命名为：`--xxxx` - deployment-name shi guding d bufen - replicaset-hash 是基于 Pod template 生成的哈希值 - xxxx 是随机生成的字符串 也可以在 YAML 中定义 Pod 的名称： ```yaml apiVersion: v1 kind: Pod metadata: name: my-pod-name # 直接定义 Pod 名称 ``` 所以，如果通过 RC 或 Deployment 控制 Pod 副本数量来实现上述有状态的集群，就会发现第一点无法满足，因为 Pod 的名称是随机产生的， Pod 的 IP 地址也是在运行期才确定且有可能改变的，所以无法事先为每个 Pod 都确定唯一不变的 ID。 为了能够在其他节点上恢复某个失败的节点，这种集群中的 Pod 需要挂载某种共享存储，所以从 Kubernetes 1.4 版本开始引入了 PetSet 这个新的资源对象，并在 1.5 版本时更名为 StatefulSet。 所以 StatefulSet 从本质上来说，可以看做 Deployment / RC 的一个特殊变种。 # StatefulSet 特性 - StatefulSet 里的每个 Pod 都有`稳定`、`唯一`的`网络标识`，可以用来`发现集群内的其他成员`。eg. StatefulSet 的名称为 kakfa，那么第一个 Pod 叫 `kafka-0`、第二个叫 `kafka-1` - StatefulSet 控制的 Pod 副本的`启停顺序是受控`的，操作第 n 个 Pod 时，前 n-1 个 Pod 已经是运行且准备好的状态 - StatefulSet 里的 Pod 采用`稳定的` `持久化存储卷`，通过 PV 或者 PVC 来实现，删除 Pod 时默认不会删除与 StatefulSet 相关的存储卷 # Headless Service StatefulSet 除了要与 PV 卷捆绑使用以存储 Pod 的状态数据，还要与 Headless Service 配合使用，即 在每个 StatefulSet 定义中都要生命它属于哪个 Headless Service。 Headless Service 与 普通 Service 的关键区别在于，它没有 Cluster IP，如果解析 Headless Service 的 DNS 域名，则返回的是该 Service 对应的全部 Pod 的 Endpoint 列表。 StatefulSet 在 Headless Service 的基础上又为 StatefulSet 控制的每个 Pod 实例都创建了一个 DNS 域名，这个域名的格式为 `$(podname).$(headless service name)` 比如一个 3 节点的 Kafka 的 StatefulSet 集群对应的 Headless Service 的名称为 kafka，StatefulSet 的名称为 kafka，则 StatefulSet 里的 3 个 Pod 的 DNS 名称分别为 kafka-0.kafka、kafka-1.kafka、kafka-3.kafka，这些 DNS 名称可以直接在集群的配置文件中固定下来。 ## Headless Service 定义文件 ```yaml apiVersion: v1 kind: Service metadata: name: mysql spec: clusterIP: None # 关键点：设置为 None 使其成为 Headless selector: app: mys…