Kubernetes权威指南-深入理解Pod Service

news/2025/9/20 19:21:00/文章来源:https://www.cnblogs.com/marlon1475/p/19102751

深入掌握Pod

Pod的基本概念与本质

  • “逻辑主机”模型

    • 核心思想:Pod的设计源于一个简单的观察:在现实应用中,多个进程往往需要紧密协作才能提供一个完整的服务。例如,一个主应用进程和一个日志收集进程、或者一个主Web服务器和一个同步本地文件的内容管理进程。

    • 解决问题:Docker提倡“一个容器一个进程”,但紧密协作的进程需要共享某些资源(如网络、存储空间)。如果将它们强行分散到多个隔离的容器中,共享和通信会变得非常复杂。

    • Pod的解决方案:Pod就像一个逻辑主机,它模拟了一个传统的虚拟机环境。在这个环境里,多个“进程”(由容器实现) 可以:

      共享同一个IP地址和端口空间:它们可以通过localhost直接通信,不会发生端口冲突。

      共享相同的网络命名空间:它们看到的网络设备、路由表完全相同。

      共享存储卷:Pod级别的Volume可以挂载到所有容器中,使它们能够共享文件。

  • Pod vs. 容器

    • 容器:是镜像的运行实例,是隔离和打包的单元。
    • Pod:是Kubernetes的调度和管理的单元,是一个或多个容器的分组。Kubernetes不直接调度容器,而是调度整个Pod。
  • Pod的实现机制

    • Pod本身只是一个逻辑概念,在节点上,Pod的实现依赖于一个基础的“基础设施容器”(在早期使用Docker时,是pause容器)。这个容器非常轻量,它只负责持有Pod的网络命名空间IPC命名空间,并提供Pod的IP地址
    • 用户定义的业务容器则通过Docker的--net=container:<id>参数加入到这个基础设施容器的网络空间中。

Pod的定义详解(YAML/JSON)

apiVersion: v1       # Kubernetes API的版本,Pod是v1核心API
kind: Pod            # 资源类型,这里是Pod
metadata:            # 元数据,描述Pod本身的信息name: nginx-fa35fx # Pod的名称,在同一命名空间内必须唯一namespace: depart  # 所属的命名空间,默认是defaultlabels:            # 标签,用于标识和选择Podapp: nginxenv: productionannotations:       # 注解,存储非标识性元数据(如构建信息、配置说明),可供工具使用description: "Our main website backend"
spec:                # 规约,这是Pod的核心,描述了期望的状态containers:        # 容器列表,定义Pod中包含的一个或多个容器- name: nginx      # 容器的名称image: nginx:1.19-alpine # 容器镜像imagePullPolicy: IfNotPresent # 镜像拉取策略(Always, Never, IfNotPresent)ports:- containerPort: 80       # 容器暴露的端口(主要是文档性作用,实际暴露取决于镜像)protocol: TCPenv:                      # 注入到容器的环境变量- name: LOG_LEVELvalue: "debug"resources:                # 资源请求和限制,是调度和运维的关键requests:               # 请求的资源,调度器根据此值选择节点cpu: "250m"           # 250 milliCPU cores (0.25 cores)memory: "64Mi"        # 64 Mebibyteslimits:                 # 资源上限,超过此限制容器会被终止或重启cpu: "500m"memory: "128Mi"volumeMounts:             # 将Pod级别的卷挂载到容器内的特定路径- name: html-volumemountPath: /usr/share/nginx/html- name: log-sync            # 第二个容器:日志收集Sidecarimage: busyboxcommand: ['sh', '-c', 'tail -f /var/log/nginx/access.log'] # 覆盖默认的启动命令volumeMounts:- name: log-volumemountPath: /var/log/nginxvolumes:                    # 定义在Pod级别的存储卷,可供所有容器挂载- name: html-volume         # 卷名称emptyDir: {}              # 卷类型:临时空目录,生命周期与Pod一致- name: log-volumeemptyDir: {}restartPolicy: Always       # 容器失败时的重启策略(Always, OnFailure, Never)nodeSelector:               # 节点选择器,将Pod调度到带有特定标签的节点上disktype: ssdschedulerName: default-scheduler # 指定调度器

Pod的核心使用模式与高级特性

  • 静态Pod

    • 概念:由特定节点上的kubelet直接管理的Pod,不通过API Server进行管理。
    • 用途:常用于部署Kubernetes自身的核心组件,如API Server、Scheduler等(它们本身也是以Pod形式运行)。kubelet会监视一个静态Pod文件目录(如/etc/kubernetes/manifests),并自动创建和运行其中的Pod定义。
    • 与DaemonSet的区别:DaemonSet由Controller Manager管理,是集群级别的;静态Pod由节点级别的kubelet管理。
  • Pod的配置管理

    • ConfigMap:将配置数据(如配置文件、环境变量)与Pod定义解耦,Pod可以通过环境变量或卷挂载的方式使用ConfigMap。
    • Secret:以安全的方式(Base64编码)存储敏感信息(如密码、令牌),用法与ConfigMap类似。
  • Downward API

    • 问题:容器内的进程有时需要知道自身运行环境的信息(如Pod的IP、名称、所在节点名称、资源限制等)。
    • 解决方案:Downward API允许容器以环境变量或文件(通过Volume)的方式向下获取Pod自身的元数据信息。
  • Pod的生命周期与重启策略

    • 生命周期阶段Pending -> Running -> Succeeded/Failed

    • 重启策略:由spec.restartPolicy控制,决定了容器退出后是否重启。

      Always:总是重启(最适合长期运行的Web服务)。

      OnFailure:仅在失败(非0退出码)时重启(适合Job)。

      Never:从不重启。

  • Pod的健康检查:这是保障应用稳定性的最关键机制,Kubernetes通过探针来检查容器的健康状态。

    • 存活探针:检查容器是否还在正常运行,如果检查失败,kubelet会杀死并重启容器。用于解决应用程序运行但已死锁的情况。

    • 就绪探针:检查容器是否已准备就绪,可以接收流量,如果检查失败,Pod会被从Service的负载均衡端点列表中移除。用于解决应用程序正在启动、负载过高或依赖服务未就绪等情况。

    • 启动探针:检查容器内的应用程序是否已启动完成。在启动探针成功之前,其他所有探针都会被禁用。用于保护慢启动容器。

    • 探针的检查机制

      exec:在容器内执行命令,看退出码是否为0。

      httpGet:对容器的IP和端口发送HTTP GET请求,看状态码是否为2xx/3xx。

      tcpSocket:尝试与容器的指定端口建立TCP连接,看是否成功。

  • Init Containers

    • 概念:在应用容器(spec.containers)启动之前必须运行并完成的一个或多个初始化容器。
    • 特性:它们按顺序执行,只有前一个成功完成后,下一个才会启动,如果任何Init Container失败,Pod会根据restartPolicy重启,直到所有Init Container都成功。
    • 典型用途:等待其他依赖服务就绪,从远程仓库或安全工具中下载配置或密钥,为应用容器预先生成配置文件或进行数据迁移。

Pod的调度

  • NodeSelector:最简单的调度方式,将Pod调度到带有指定标签的节点上。
  • 资源请求与限制:调度器根据spec.containers[].resources.requests来计算节点剩余资源,并决定Pod放在哪个节点上,limits则由节点上的kubelet执行,防止容器耗尽资源。

深入掌握Service

Service的核心价值与要解决的问题

  • 问题:Pod的动态性与不可靠性
    • 动态IP:Pod的IP地址不是固定的,当一个Pod被重新调度或替换时,它会获得一个新的IP地址。
    • 多个副本:一个应用通常由多个Pod副本(Deployment管理)组成,客户端需要与所有这些Pod通信,而不是只盯着某一个。
  • 解决方案:Service的引入
    • 稳定的IP地址:Service会获得一个在整个集群内唯一的、固定的虚拟IP(VIP),也称为ClusterIP。客户端只需要记住这个IP(或对应的DNS名称),无需关心后端有多少个Pod或它们的IP是什么。
    • 稳定的DNS名称:集群内的DNS服务(如CoreDNS)会为Service自动创建一个DNS记录,格式为<service-name>.<namespace>.svc.cluster.local。集群内其他Pod只需通过服务名即可访问。
    • 负载均衡:Service自动将发送到其虚拟IP的请求,以负载均衡的方式分发到所有健康的后端Pod上。

Service的定义与工作机制

  • Service的定义(YAML)详解

    apiVersion: v1
    kind: Service       # 资源类型为Service
    metadata:name: my-service  # Service的名称,用于DNS解析namespace: default
    spec:selector:         # 标签选择器!这是Service与Pod关联的核心app: MyApp      # 选择所有具有标签`app: MyApp`的Podports:- protocol: TCP # 协议类型(TCP, UDP, SCTP)port: 80      # Service自身暴露的端口targetPort: 9376 # 后端Pod监听的端口(也可以是端口名称)type: ClusterIP   # Service的类型,默认是ClusterIP
    
    • spec.selector:这是Service的灵魂。它通过标签(Label)来识别哪些Pod属于它的后端端点。Service控制器会持续监控与选择器匹配的Pod列表的变化。
    • ports.port:Service的虚拟IP上暴露的端口。
    • ports.targetPort:请求被转发到Pod上的目标端口,如果targetPort是字符串,则引用Pod定义中containerPort名称
  • 核心工作机制:kube-proxy与Endpoints

    • Endpoints对象:当你创建一个Service时,Kubernetes会自动创建一个同名的Endpoints对象。这个对象是一个动态列表,包含了所有匹配selector的、状态为Ready的Pod的IP地址和端口,可以kubectl get endpoints <service-name>查看。

    • kube-proxy:每个Node上都运行着一个kube-proxy守护进程,它负责实现Service的虚拟IP功能,它监视API Server上Service和Endpoints的变化,并动态更新本机的网络规则,确保发往Service VIP的流量能被正确转发到后端的Pod。

    • 流量转发模式kube-proxy有三种工作模式,决定了流量如何被路由:

      iptables模式(默认):使用Linux内核的iptables规则配置负载均衡,高性能、高可靠,但规则多了之后排查复杂。

      ipvs模式:使用Linux内核的IP Virtual Server功能。为大型集群提供了更好的可扩展性和性能,支持更多的负载均衡算法。

      userspace模式(已弃用):流量在用户空间被代理,性能较差,仅用于历史兼容。

Service的类型(Type)及其应用场景

  • ClusterIP(默认类型)

    • 暴露范围:仅在Kubernetes集群内部可访问。
    • IP地址:分配一个集群内部的虚拟IP。
    • 用途:这是最常用的类型,用于让集群内部的其他Pod(如前端Pod访问后端API)访问服务,它是微服务间内部通信的基础。
  • NodePort

    • 暴露范围:暴露到集群每个节点的特定端口上,因此可以从集群外部通过<任何节点的IP>:<NodePort>访问。

    • 工作机制:NodePort建立在ClusterIP之上,它会在每个Node上打开一个静态端口(30000-32767范围),并将访问该端口的流量路由到背后的ClusterIP Service,最终再到Pod。

    • YAML示例

      spec:type: NodePortports:- port: 80     # Service的ClusterIP端口targetPort: 9376nodePort: 30007 # 可选:手动指定节点端口,必须在范围内。不指定则随机分配。
      
    • 用途:用于开发测试环境,或者让外部系统(如无法使用Ingress的传统系统)直接访问服务,不适合生产环境直接暴露服务

  • LoadBalancer

    • 暴露范围:暴露到集群外部,通常是公有云提供的网络负载均衡器(如AWS的ELB/ALB、GCP的Load Balancer、Azure的LB)。
    • 工作机制:当声明一个type: LoadBalancer的Service时,Kubernetes会向云提供商发起API调用,自动创建并配置一个外部的负载均衡器,这个负载均衡器会将流量引导到集群各个节点的NodePort,最终再到Pod。
    • 用途:在公有云上暴露服务的最直接、最标准的方式,云负载均衡器自带健康检查、高可用、SSL终止等企业级功能,但每个Service都会创建一个独立的云LB,成本较高。
  • ExternalName

    • 暴露范围:集群内部。
    • 工作机制:它不选择任何Pod,而是通过返回一个CNAME记录,将集群内部的Service映射到一个外部域名
    • 用途:让集群内的Pod能够通过Kubernetes Service的DNS机制访问集群外部的服务,实现解耦。

高级模式与服务发现机制

  • Headless Service(无头服务)

    • 定义:将Service的spec.clusterIP设置为None

    • 行为:它不会分配ClusterIP,也不会提供负载均衡代理。

    • DNS解析

      对Headless Service的DNS查询会返回所有后端Pod的IP地址列表(而不是一个Service的VIP)。

      如果Service定义了标签选择器,则返回的是所有被选中的Pod的IP。

      如果Service没有定义标签选择器,但手动配置了Endpoints,则返回这些Endpoints的IP。

    • StatefulSet的最佳搭档:用于StatefulSet中,每个Pod会有稳定的DNS名称(<pod-name>.<headless-svc-name>),非常适合有状态应用如ZooKeeper、Etcd、MySQL主从,它们需要直接互相发现和通信。

    • 自定义服务发现:客户端可以自己获取所有后端地址,并实现自己的负载均衡策略。

  • 服务发现机制

    • 环境变量:kubelet在启动Pod时,会将当前命名空间下所有活跃Service的IP和端口信息以环境变量的形式注入到Pod中。
    • DNS(推荐):集群的CoreDNS服务会为每个Service创建DNS记录。这是最主流和最推荐的方式。应用程序只需通过服务名即可访问,实现了完全的松耦合。

Ingress - 超越Service的7层流量管理

  • 与Service的关系:Ingress不是Service的一种类型。它位于多个Service之前,充当智能的7层(HTTP/HTTPS)路由器和入口点
  • 工作原理:你需要部署一个Ingress Controller,它本身通常通过LoadBalancerNodePort类型的Service暴露,然后创建Ingress资源来定义路由规则。
  • 优势:一个Ingress Controller(一个LoadBalancer IP)可以代理成百上千个不同的内部Service,极大地节省成本和简化管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/908514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍:jeecg-boot3.7.0对接钉钉登录(OAuth2.0)

详细介绍:jeecg-boot3.7.0对接钉钉登录(OAuth2.0)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&quo…

C++编程软件 Dev-C++ 安装及使用流程

目录第 1 步:下载 Dev-C++第 2 步:安装 Dev-C++第 3 步:第一次打开 Dev-C++ 时的配置第4步:编写一个 C++ 程序 第 1 步:下载 Dev-C++ 首先,我们需要找一个地方下载 Dev-C++ 软件。 可以直接点击 这个链接 下载。…

DLL植入漏洞分类与微软安全响应指南

本文详细解析微软对DLL植入漏洞的分类方法,涵盖应用程序目录、当前工作目录和PATH目录三种场景的威胁评估标准,并说明微软针对不同场景的安全响应策略与修复优先级。DLL植入漏洞的分类 | MSRC博客 本文章翻译自Secur…

4980:拯救行动

题目 总时间限制: 1000ms 内存限制: 65536kB 描述 公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。 英勇的骑士(r)决定…

java03-wxj

好的,我们来逐一详细解答这些问题。1. 什么样的方法应该用static修饰?不用static修饰的方法往往具有什么特性? 应该使用 static 修饰的方法:工具方法(Utility Methods): 执行一个与任何特定对象实例无关的通用任…

题解:P13969 [VKOSHP 2024] Exchange and Deletion

题面: 我们考虑从图论意义计数,把 swap 改成连边,由于交换完前面的点直接被删了,所以只保留从后向前的连边。 那么最后连到 \(n-k\) 前的点的数值等于链头,而 \(n-k\) 后的点和链上非链头的点实际上都被删了。手玩…

基于MATLAB的车牌识别系统 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

市场交易反心理特征之二:忽视热点切换的苗头

案例:2017年8月18日,万科A。2017年8月18日,万科A 万科A小波段延续万科A一个波段完成​情况描述:从第一次触及无穷成本线止跌后大资金进入开始,连续2-3次出现买点,都能选出。但是都直接鼠标滑过,没有过脑子,显然…

Linux服务器上安装配置GitLab的步骤

在Linux服务器上安装GitLab是一个涉及多个步骤的过程。以下是详细的步骤,遵从GitLab官方推荐的做法以确保系统的稳定性和性能。 服务器要求和前提条件:一台运行支持的Linux操作系统的服务器,建议使用CentOS 7。 至少…

贪心算法应用:投资组合再平衡问题详解 - 实践

贪心算法应用:投资组合再平衡问题详解 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

MCP:Trae中集成Playwright 实现网页自动化测试

Trae IDE 可以通过智能问答的形式补齐代码,纠正程序中的错误,根据用户的自然语言,实现AI自动编程。近期使用了一下Trae,发现很强大。我把一个有前后端的项目导入Trae IDE,当时还有一些报错,但是很快在Trae 的提示…

C语言中的字符、字符串及内存操作函数详细讲解

在C语言中,字符和字符串的处理是基本且重要的概念。字符在C中通常由 char类型表示,而字符串则是以 null终止的字符数组。内存操作函数则提供了基本的内存处理能力,如复制、设置、比较等内存块。 字符操作 字符使用 …

06、訊息收集

1、使用nmap探测magedu.com开放的端口号和服务指纹 2、使用指纹识别工具探测magedu.com采用的建站模板 3、搜集magedu.com的子域名有哪些

AI 智能体与 Coze 工作流实践:小红书对标账号采集 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

在Linux中设定账户密码的安全性策略

在Linux环境下,确保账户密码的安全性是保护系统安全的重要环节。要设置强健的密码策略,需要从多个层面制定规则,这些包括密码复杂性、长度、有效期限、历史记录限制和尝试次数限制等方面。 密码复杂性设定和管理:密…

对比六种JavaScript全文搜索库 fuse.js 、 lunr 、 flexsearch 、 minisearch 、 search-index 、 js-sea

以下是针对六种JavaScript全文搜索库的对比分析,综合功能特性、性能表现及适用场景: 核心特性对比‌Fuse.js‌‌算法‌:基于Bitap算法的模糊搜索,支持拼写容错和多种匹配模式(前缀、后缀、逻辑组合等)7。 ‌配置…

精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具,助力轻松提升 Windows 系统性能与使用体验!

前言 今天大姚给大家推荐 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具,希望可以帮助你轻松提升 Windows 系统性能与使用体验。 Optimizer Optimizer 是一款基于 .NET 开源(GPL-3.0 license)、功能强大的 …

从零开始: c#纯代码实现完整Json解析器的全过程及注释与自定义格式的支持实现

从零开始: c#纯代码实现完整Json解析器的全过程及注释与自定义格式的支持实现大家好!我们要深入探讨一个非常常用的技术:JSON反序列化。别小看这个技术,它可是现代编程中不可或缺的一部。JSON解析不仅仅是简单的数据…

MySQL 32 为什么还有kill不掉的语句?

MySQL有两个kill命令:kill query+线程id,表示终止该线程正在执行的语句;kill (connection)+线程id,表示断开这个线程的连接,如果线程有语句正在执行,会先停止正在执行的语句。有时候可能会遇到:使用了kill,却没…

Axure RP 9 Mac 交互原型设计 - 实践

Axure RP 9 Mac 交互原型设计 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…