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

【一起来学kubernetes】24、Service使用详解


Kubernetes 中的 Service 是用于暴露应用服务的核心抽象,为 Pod 提供稳定的访问入口、负载均衡和服务发现机制。Service在Kubernetes中代表了一组Pod的逻辑集合,通过创建一个Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端的各个容器应用上。


一、Service 的核心作用

  1. 服务发现

    • 为一组动态变化的 Pod(通过标签选择器)提供固定的访问地址(IP/DNS)。
    • 客户端无需关心 Pod 的具体位置和数量。
  2. 负载均衡

    • 将请求均匀分发到后端 Pod,支持多种负载均衡策略(如轮询、会话保持等)。
  3. 抽象网络访问

    • 屏蔽 Pod 的动态变化(扩缩容、重启、迁移),对外提供稳定的服务入口。

二、Service 的类型

Kubernetes 支持多种 Service 类型,适用于不同场景:

类型说明适用场景
ClusterIP默认类型,为 Service 分配集群内部的虚拟 IP(仅集群内可访问)。内部服务通信(如微服务间调用)
NodePort在每个节点上开放一个固定端口(默认范围 30000-32767),通过 节点IP:端口 访问。允许外部通过节点 IP 访问服务
LoadBalancer集成云厂商的负载均衡器(如 AWS ALB、GCP LB),自动分配外部 IP。公有云环境下的外部服务暴露
ExternalName将 Service 映射到外部 DNS 名称(如数据库域名),实现外部服务代理。代理集群外服务(如云数据库)
Headless无 ClusterIP,直接返回 Pod IP 列表(需设置 clusterIP: None)。有状态服务(如 StatefulSet 的 DNS 记录)

三、Service 的架构与关键组件

1. 核心概念
  • Label Selector
    通过标签(如 app: web)选择后端 Pod。只有匹配标签的 Pod 会被 Service 纳入负载均衡池。

  • Endpoints
    Service 的后端 Pod IP 列表,自动维护(由 Endpoints Controller 管理)。

  • kube-proxy
    负责实现 Service 的负载均衡规则,支持以下模式:

  • iptables(默认):通过 iptables 规则转发流量。

  • IPVS:基于内核的 IP Virtual Server,性能更高。

  • userspace(已弃用):用户态代理,性能较差。

2. 流量转发流程
  1. 客户端访问 Service 的 ClusterIP 或 DNS 名称。
  2. kube-proxy 根据 Service 规则将请求转发到后端 Pod。
  3. 请求到达 Pod 后由应用处理。

四、Service 的 YAML 示例

1. ClusterIP 类型
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web   # 选择标签为 app=web 的 Pod
  ports:
    - protocol: TCP
      port: 80       # Service 暴露的端口
      targetPort: 80 # Pod 监听的端口
2. NodePort 类型
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
      nodePort: 31000  # 手动指定节点端口(可选)

3. LoadBalancer类型
  • . 定义YAML文件
    首先,你需要定义一个YAML文件来描述Service的属性。以下是一个示例YAML文件,用于创建一个LoadBalancer类型的Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: my-loadbalancer-service
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
      type: LoadBalancer
    

    在这个示例中:

    • apiVersion 指定了Kubernetes API的版本。
    • kind 指定了资源类型为Service。
    • metadata.name 指定了Service的名称。
    • spec.selector 用于选择哪些Pod将被此Service暴露。这里选择的是标签为app: my-app的Pod。
    • spec.ports 定义了Service监听的端口以及目标Pod的端口。这里Service监听的端口是80,目标Pod的端口是8080。
    • spec.type 指定了Service的类型为LoadBalancer。
  • . 应用YAML文件
    使用kubectl apply命令将YAML文件应用到Kubernetes集群中:

    kubectl apply -f my-loadbalancer-service.yaml
    
  • . 等待外部IP分配
    LoadBalancer类型的Service是异步创建的。创建后,Kubernetes会请求云提供商创建一个外部负载均衡器,并将流量路由到后端Pod。这个过程可能需要一些时间。你可以使用kubectl get service命令查看Service的状态,并等待EXTERNAL-IP列显示一个有效的IP地址:

    kubectl get service my-loadbalancer-service
    

    一旦EXTERNAL-IP列显示了一个IP地址,就意味着外部负载均衡器已经创建成功,你可以通过这个IP地址访问你的Service。


4. ExternalName类型

在Kubernetes(k8s)中,创建一个ExternalName类型的Service可以让你将集群内部的服务通过DNS CNAME机制映射到一个外部域名上。这样,集群内部的Pod就可以通过内部服务名访问外部服务,而无需知道外部服务的真实域名。以下是创建ExternalName类型Service的步骤:

  • 定义YAML文件

首先,你需要定义一个YAML文件来描述Service的属性。以下是一个示例YAML文件,用于创建一个ExternalName类型的Service:

apiVersion: v1
kind: Service
metadata:
  name: my-externalname-service
  namespace: default # 或者你指定的其他命名空间
spec:
  type: ExternalName
  externalName: www.example.com # 外部服务的域名

在这个示例中:

  1. apiVersion 指定了Kubernetes API的版本。
  2. kind 指定了资源类型为Service。
  3. metadata.name 指定了Service的名称。
  4. metadata.namespace 指定了Service所在的命名空间(可选,默认为default)。
  5. spec.type 指定了Service的类型为ExternalName。
  6. spec.externalName 指定了外部服务的域名。
  • 应用YAML文件

使用kubectl apply命令将YAML文件应用到Kubernetes集群中:

kubectl apply -f my-externalname-service.yaml
  • 验证Service

创建完成后,你可以使用kubectl get service命令查看Service的状态:

kubectl get service my-externalname-service -n default # 如果指定了命名空间,则加上-n参数

你应该会看到类似以下的输出:

NAME                 TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
my-externalname-service   ExternalName   <none>       www.example.com   <none>    <age>

此时,Service已经成功创建,并且已经通过DNS CNAME机制映射到了外部域名www.example.com上。

  • 访问外部服务

在集群内部的Pod中,你可以通过以下方式访问外部服务:

curl http://my-externalname-service.default.svc.cluster.local # 如果指定了命名空间,则使用对应的命名空间名;否则,默认使用default

或者,如果你没有指定命名空间或者使用的是默认命名空间,并且DNS配置正确,你也可以直接通过以下方式访问:

curl http://my-externalname-service

这样,你就可以通过内部服务名my-externalname-service来访问外部服务www.example.com了。

  • 注意事项
  1. DNS解析:确保集群内部的DNS配置正确,能够解析my-externalname-service.default.svc.cluster.local(或你指定的命名空间名)到外部域名www.example.com
  2. 安全性:访问外部服务时,请注意安全性问题,如SSL/TLS证书验证、身份验证和授权等。
  3. 可用性:ExternalName类型的Service不依赖于Kubernetes集群内部的负载均衡器或代理,因此外部服务的可用性将直接影响集群内部Pod的访问。

五、Service 的生命周期管理

1. 创建与验证
# 创建 Service
kubectl apply -f service.yaml

# 查看 Service 状态
kubectl get svc web-service

# 查看关联的 Endpoints
kubectl get endpoints web-service

# 通过 DNS 访问(集群内)
curl http://web-service.default.svc.cluster.local
2. 更新与删除
# 更新 Service(如修改端口)
kubectl edit svc web-service

# 删除 Service
kubectl delete svc web-service

六、典型应用场景

  1. 微服务间通信
    通过 ClusterIP 实现服务间的内部调用(如前端调用后端 API)。

  2. 数据库服务暴露
    使用 ClusterIP 或 Headless Service 暴露数据库实例(如 MySQL Pod)。

  3. 外部流量接入
    结合 LoadBalancer 或 NodePort 暴露 Web 服务到公网。

  4. 灰度发布
    通过多个 Service 和标签选择器实现流量分流。


七、注意事项与最佳实践

  1. 命名规范
    Service 名称需符合 DNS 命名规则(小写字母、数字、-)。

  2. 标签管理
    确保 Pod 的标签与 Service 的 selector 严格匹配。

  3. 避免使用短 DNS
    集群内访问 Service 时,使用完整 DNS 名称(如 web-service.default.svc.cluster.local)。

  4. 会话保持
    若需会话保持(Session Affinity),配置 sessionAffinity: ClientIP

  5. 监控与调试
    • 检查 Endpoints 是否包含预期 Pod:kubectl describe svc <service-name>
    • 查看 kube-proxy 日志:kubectl logs -n kube-system <kube-proxy-pod>


八、与其他资源的对比

资源作用与 Service 的关系
Ingress管理 HTTP/HTTPS 路由,提供域名和 TLS 支持Service 的上一层代理,需绑定后端 Service
EndpointSlice替代 Endpoints,支持大规模集群的分片管理Service 的后端地址集合的扩展实现
ExternalName代理外部服务一种特殊类型的 Service

九、常见问题

  • Q: ClusterIP 无法访问?
    A: 检查 Pod 是否正常运行、标签是否匹配、kube-proxy 是否正常工作。

  • Q: NodePort 端口不通?
    A: 检查节点防火墙规则、kube-proxy 是否监听端口、Pod 是否就绪。

  • Q: DNS 解析失败?
    A: 检查 CoreDNS 是否运行正常、Service 名称是否合法。

  • Q: 如何实现跨命名空间访问?
    A: 使用完整的 DNS 名称(如 web-service.other-ns.svc.cluster.local)。


十、总结

Service 是 Kubernetes 中实现服务暴露和负载均衡的核心机制,通过 ClusterIP、NodePort、LoadBalancer 等类型满足不同场景需求。理解其工作原理和配置方法,是构建稳定、可扩展的云原生应用的关键步骤。

十一、拓展

【一起来学kubernetes】23、Namespace使用详解

【一起来学kubernetes】10、CoreDNS的作用原理与Pod间的调用

【一起来学kubernetes】12、k8s中的Endpoint详解


http://www.kler.cn/a/611786.html

相关文章:

  • 进程通信 system V共享内存 ─── linux第25课
  • 【漏洞修复】Android 10 系统源码中的 glibc、curl、openssl、cups、zlib 更新到最新版本
  • ECharts各类炫酷图表/3D柱形图
  • HTML之内联样式
  • 用WSL安装Ubuntu(Windows11)
  • 计算机二级(C语言)考试高频考点总汇(三)—— 结构体和共用体、结构体对齐规则、联合体大小计算
  • 力扣DAY29 | 热100 | 删除链表的倒数第N个结点
  • JumpServer:一款企业级开源堡垒机
  • Spring:Bean的作用域、循环依赖和事务
  • Docker-清理容器空间prune
  • 【sql优化】where 1=1
  • 实测:C++ 重构神经网络组件,神经网络内存占用降低
  • SQL Server安装过程中提示 .NET Framework 4.8 缺失
  • 2025年成都市双流区农业科技试验示范基地建设方案申报条件材料和补贴程序、时间安排
  • PySimpleGUI安装老版本,给软件链接,免费用,教程
  • 使用集成过滤插件在 Logstash 中处理来自 Elastic 集成的数据
  • RAG技术的进化:RQ-RAG查询优化/化繁为简Adaptive-RAG智能分类/精准出击
  • Skynet 框架中 gateserver、gate、watchdog 的关系
  • 数据仓库getter的应用
  • Qemu-STM32(十二):STM32F103 框架代码添加