深入kubernetes掌握核心概念--Service

深入解析service

一、概念

Service主要用于提供网络服务,通过Service的定义,能够为客户端

应用提供稳定的访问地址(域名或IP地址)和负载均衡功能,以及屏蔽

后端Endpoint的变化,它是Kubernetes实现微服务的核心资源。

本章对Service的概念、负载均衡机制、多端口号、外部服务、暴露到集群外、

支持的网络协议、服务发现机制、Headless Service、端点分片和服务拓

扑等内容进行认识学习。

简单来说,这篇文章重点讲负载均衡在service中的实现

二、什么是service?

Service 是一种抽象概念,用于定义一组 Pod 的访问入口。它就像一个虚拟的代理,将来自外部的请求转发到后端 Pod 的集合中。

再理解一遍:Service是一个抽象层,它定义了一种访问和暴露一组运行在Pods中的应用的方法。Service能够提供负载均衡和服务发现,让客户端无需关心后端Pod的复杂性。

三、Service 的核心功能

服务发现与负载均衡

  • Kubernetes Service 为一组具有相同标签(label)的 Pod 提供了一个稳定的网络入口点。通过定义 Service,Kubernetes 会在集群内部为 Service 分配一个固定的 ClusterIP,客户端只需通过这个 IP 地址就可以访问到背后的所有 Pod。
  • Service 提供了一种抽象层,可以实现负载均衡,将客户端请求均匀地分布到后端关联的多个 Pod 上,从而提高系统的可靠性和性能。

服务抽象

  • Service 将一组具有相同功能的 Pod 抽象成一个单一的服务实体,隐藏了底层的 Pod 实例变化,如 Pod 的创建、销毁、扩容、缩容等操作都不会影响客户端对服务的访问。

    网络代理:

  • Kubernetes 通过 iptables 规则或者 kube-proxy 组件实现代理功能,透明地将到达 Service ClusterIP 的流量转发到后端的 Pod 上。

多类型暴露

  • Kubernetes Service 支持多种类型的暴露方式,如 ClusterIP(仅集群内部访问)、NodePort(通过节点端口暴露到集群外部)、LoadBalancer(借助云提供商的负载均衡器暴露到公网)以及 ExternalName(将 Service 映射到外部 DNS 名称)。

健康检查与自动摘除

  • 当 Service 与 Endpoint Controller 结合使用时,能够自动跟踪后端 Pod 的健康状态,并将不健康的 Pod 从服务负载均衡列表中移除,直到其恢复正常。

    Session Affinity(会话保持):

  • 对于部分需要会话一致性的应用,Service 支持客户端 IP 会话保持,确保来自同一客户端的请求始终路由到相同的后端 Pod。

DNS 解析

  • Kubernetes 为每个 Service 自动生成 DNS 记录,使得集群内部的其他 Pod 或 Service 可以通过域名而非 IP 地址来访问它。

四、Service 类型

Kubernetes 提供了四种类型的 Service:

ClusterIP: 默认的服务类型,将 Service 暴露在集群内部,只能在集群内部访问。

NodePort: 将 Service 暴露在所有节点的指定端口上,可以通过节点 IP 地址访问。

LoadBalancer: 创建一个外部负载均衡器,将 Service 暴露到外部网络。

ExternalName: 将 Service 映射到外部 DNS 名称上,无需创建负载均衡器。

Service 类型 特性 示例 应用场景
ClusterIP - 默认类型 - 只能在集群内部访问 - Kubernetes 分配一个唯一的集群内部 IP 地址 type: ClusterIP - 内部服务间通信 - 不需要外部访问的中间件或后台服务
NodePort - 在每个节点上打开一个静态端口 - 可通过 <NodeIP>:<NodePort> 从集群外部访问 type: NodePort spec.ports[0].nodePort: 30080 - 开发和测试环境下的简单外部访问 - 不需要复杂负载均衡配置的小规模应用
LoadBalancer - 创建一个外部负载均衡器(如 AWS ELB、GCP Load Balancer) - 自动分配公网 IP 地址 - 负载均衡到后端 Pods type: LoadBalancer spec.loadBalancerIP: X.X.X.X(可选固定公网 IP) - 需要公开访问的生产环境应用 - 高可用和负载均衡要求较高的大规模服务
ExternalName - 不创建任何代理或端口映射 - 服务名解析为指定的外部 DNS 名称 type: ExternalName spec.externalName: some.externaldns.name - 与集群外部服务集成 - 使用外部服务作为内部服务的一部分

示例代码:

  1. ClusterIP 示例:
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: internal-service
spec:
  type: ClusterIP
  selector:
    app: MyApp
  ports:
  - name: http
    port: 80
    targetPort: 8080
  1. NodePort 示例:
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
  - name: http
    port: 80
    targetPort: 8080
    nodePort: 30080
  1. LoadBalancer 示例:
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: load-balancer-service
spec:
  type: LoadBalancer
  selector:
    app: MyApp
  ports:
  - name: http
    port: 80
    targetPort: 8080
  # 可选,指定预设的负载均衡器IP
  # loadBalancerIP: X.X.X.X
  1. ExternalName 示例:
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: external-database-service
spec:
  type: ExternalName
  externalName: some.database.example.com

五、Service 实现机制

1.Service 实现主要依赖两个组件:

Endpoints: Endpoints 是由 kube-proxy 维护的一个动态更新的资源,其中包含了后端 Pod 的服务地址和端口号信息。

Selectors: Selectors 是 Service 中定义的标签匹配规则,用于选择后端 Pod。

当客户端向 Service 发送请求时,kube-proxy 会根据 Service 的 Selectors 筛选出匹配的后端 Pod,并从 Endpoints 中获取这些 Pod 的服务地址和端口号信息。

然后,kube-proxy 会将请求转发到其中一个 Pod 上,具体选择哪个 Pod 取决于所使用的负载均衡算法。

2.Kubernetes 提供了多种负载均衡算法

Round Robin: 轮询算法,将请求均匀地分配到所有可用的后端 Pod 上。

Random: 随机算法,随机选择一个后端 Pod 进行转发。

Least Connections: 最少连接算法,将请求转发到连接数最少的 Pod 上。

Source IP: 源 IP 算法,根据客户端的 IP 地址将请求转发到特定的 Pod 上。

ExternalTraffic: 外部流量算法,将来自外部集群的流量转发到特定的 Pod 上。

六、Service 实战应用

1.Web 应用负载均衡

将多个 Web Pod 部署在 Service 后面,实现负载均衡,提升 Web 应用的性能和可用性。

对于Web应用,通常我们会创建多个副本(Pod)并通过Service实现负载均衡。以下是一个简化的示例,首先创建一个Deployment以部署多个Web应用Pod,然后创建一个Service进行负载均衡。

Deployment YAML示例:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-deployment
spec:
  replicas: 3 # 设置三个副本
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-container
        image: your-web-app-image:latest
        ports:
        - containerPort: 80 # 假设应用监听80端口

Service YAML示例:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  type: ClusterIP # 或者 LoadBalancer,取决于是否需要公开到集群外部
  selector:
    app: web-app # 与Deployment的标签匹配
  ports:
  - port: 80 # Service监听的端口
    targetPort: 80 # Pod上对应的目标端口

微服务架构:

2.微服务架构负载均衡

将微服务架构中的各个服务封装成 Service,实现服务发现和负载均衡,方便服务之间的调用和通信。

在微服务架构中,每个服务都会有自己的Service。例如,假设有一个订单服务(order-service)需要被其他服务调用:

订单服务Deployment YAML示例:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-container
        image: your-order-service-image:latest
        ports:
        - containerPort: 8080 # 假设订单服务监听8080端口

订单服务Service YAML示例:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: order-service-service
spec:
  type: ClusterIP
  selector:
    app: order-service
  ports:
  - port: 8080 # Service监听的端口
    targetPort: 8080 # Pod上对应的目标端口

3.数据库服务负载均衡(不建议)

将数据库 Pod 部署在 Service 后面,实现负载均衡,避免单个数据库 Pod 成为性能瓶颈。

对于数据库服务,虽然通常不会进行传统的负载均衡(因为大多数数据库不支持横向扩展写操作)

但在高可用场景下,可以将多个数据库Pod组成一个ReplicaSet,并通过Service对外暴露,但这里的负载均衡主要是为了故障转移和读操作分发。

MySQL主从副本StatefulSet YAML示例:

yaml 复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-replicas
spec:
  serviceName: mysql-service # 创建对应的Service
  replicas: 3 # 例如,两主一从
  ...

MySQL服务Service YAML示例(仅针对读操作负载均衡):

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: mysql-service-read-only
spec:
  type: ClusterIP
  selector:
    app: mysql-replicas
  ports:
  - port: 3306 # MySQL服务端口
  sessionAffinity: ClientIP # 可以开启客户端IP会话保持,使得同一个客户端IP的读请求总是发送到同一个后端Pod

核心功能大总结

功能项 描述 示例
服务发现 Kubernetes Service 提供了一个静态的ClusterIP,让Pod能够通过该地址访问相关服务。 创建名为web-service的Service,指向所有标签为app=web的Pod,集群内部其他Pod可通过web-service.default.svc.cluster.local访问。
负载均衡 Service能将流入的请求分散到后端关联的多个Pod上,实现负载均衡。 web-service背后有3个副本的web-appPods,Service将请求均匀分配到各个Pod上。
服务抽象 隐藏具体Pod实例的变化,对外表现为统一服务实体。 扩容或缩容web-app的副本数,客户端仍继续通过web-service访问不变。
网络代理 使用iptables或kube-proxy实现网络流量的透明转发。 客户端请求到10.0.0.1:80web-service的ClusterIP),被转发至某个Pod的8080端口。
多类型暴露 支持不同级别的服务暴露方式。 - ClusterIP(默认,只在集群内部可见,例如ClusterIP: 10.0.0.1
- NodePort(将服务映射到每个节点上的特定端口,例如NodePort: 30001
- LoadBalancer(在云环境上创建外部负载均衡器,如ExternalIP: x.x.x.x
- ExternalName(映射到外部DNS记录,如CNAME: example.com
健康检查 自动检测后端Pod健康状况并更新负载均衡池。 web-app中某个Pod故障,Endpoint Controller将其从web-service的后端实例列表中移除。
会话保持 支持基于客户端IP的会话保持策略。 设置sessionAffinity: ClientIP,确保同一客户端请求在会话有效期内均发送到同一Pod处理。

以上是对Kubernetes Service核心功能的表格,实际应用中,可以通过编写YAML文件来定义Service资源,比如:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP
  sessionAffinity: ClientIP

在这个例子中,我们定义了一个类型为ClusterIP的服务web-service,它选择标签为app=web的Pod,并且启用了基于客户端IP的会话保持。

相关推荐
小诸葛的博客9 分钟前
istio-proxy不打印访问日志怎么解决?
云原生·istio
dessler17 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
zhy2956317 分钟前
【DOCKER】基于DOCKER的服务之DUFS
运维·docker·容器·dufs
秋名山小桃子31 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉1213832 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
Algorithm157639 分钟前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
MZWeiei43 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
Arenaschi1 小时前
在Tomcat中部署应用时,如何通过域名访问而不加端口号
运维·服务器
waicsdn_haha1 小时前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk