当前位置: 首页 > news >正文

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

深入掌握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.hskmm.com/?act=detail&tid=10970

相关文章:

  • 详细介绍:jeecg-boot3.7.0对接钉钉登录(OAuth2.0)
  • C++编程软件 Dev-C++ 安装及使用流程
  • DLL植入漏洞分类与微软安全响应指南
  • 4980:拯救行动
  • java03-wxj
  • 题解:P13969 [VKOSHP 2024] Exchange and Deletion
  • 市场交易反心理特征之二:忽视热点切换的苗头
  • Linux服务器上安装配置GitLab的步骤
  • 贪心算法应用:投资组合再平衡问题详解 - 实践
  • MCP:Trae中集成Playwright 实现网页自动化测试
  • C语言中的字符、字符串及内存操作函数详细讲解
  • 06、訊息收集
  • 在Linux中设定账户密码的安全性策略
  • 精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具,助力轻松提升 Windows 系统性能与使用体验!
  • MySQL 32 为什么还有kill不掉的语句?
  • Axure RP 9 Mac 交互原型设计 - 实践
  • 深入解析:rook-ceph自定义添加osd流程
  • 1789:算24
  • 流行的 3D 文件格式及其用途指南
  • CentOS7.9上安装MySQL8.4
  • 铁头山羊stm32-HAL库 - 实践
  • 2025CSP-S初赛游记
  • JBoltAI框架:企业级AI开发的革新路径与行业实践 - 那年-冬季
  • JBoltAI:重塑视频创作,开启零门槛智能混剪新时代 - 那年-冬季
  • 深入解析:手搓一个 DELL EMC Unity存储系统健康检查清单
  • Vscode + Latex指南
  • 线程池未争取关闭导致的一个bug
  • kafka创建topic
  • WPS 2025最新版EXE
  • OpenCV-图像通道提取与处理