Skip to content

Service基础

概述

Service是Kubernetes中定义一组Pod访问策略的抽象。它为一组功能相同的Pod提供稳定的网络端点,实现服务发现和负载均衡。

Service核心功能

1. 服务发现

  • 为动态变化的Pod提供稳定的访问地址
  • 通过标签选择器关联Pod
  • 自动更新端点列表

2. 负载均衡

  • 在多个Pod实例间分配流量
  • 支持多种负载均衡策略
  • 实现会话保持

3. 网络抽象

  • 隐藏Pod的具体实现细节
  • 提供统一的访问入口
  • 支持多种访问模式

Service类型详解

1. ClusterIP(默认)

特点

  • 集群内部IP地址:分配一个集群内部的虚拟IP地址
  • 内部访问:只能在集群内部访问
  • 负载均衡:默认在Pod间进行负载均衡
  • 无外部暴露:不暴露到集群外部

适用场景

  • 内部服务通信
  • 微服务之间的调用
  • 不需要外部访问的服务

配置示例

yaml
apiVersion: v1
kind: Service
metadata:
  name: internal-service
spec:
  type: ClusterIP
  selector:
    app: myapp
  ports:
  - port: 80          # Service端口
    targetPort: 8080  # Pod容器端口
    protocol: TCP
  sessionAffinity: None  # 无会话保持

优势与劣势

  • 优势:简单、安全、资源占用少
  • 劣势:只能内部访问,无法从集群外部访问

2. NodePort

特点

  • 节点端口:在每个节点上开放一个端口
  • 外部访问:通过节点IP:节点端口访问
  • 端口范围:默认30000-32767
  • 内部ClusterIP:同时创建ClusterIP

适用场景

  • 开发测试环境
  • 临时外部访问需求
  • 没有负载均衡器的环境

配置示例

yaml
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - port: 80          # Service端口
    targetPort: 8080  # Pod容器端口
    nodePort: 30080   # 节点端口(可选)
    protocol: TCP
  externalTrafficPolicy: Local  # 保留源IP

优势与劣势

  • 优势:简单易用,无需额外资源
  • 劣势:端口范围有限,需要管理端口冲突,每个节点都开放端口

3. LoadBalancer

特点

  • 云服务商集成:利用云服务商的负载均衡器
  • 外部IP:自动分配外部IP地址
  • 高可用:云负载均衡器提供高可用
  • 自动路由:自动配置路由规则

适用场景

  • 生产环境
  • 需要外部访问的服务
  • 高可用要求的应用

配置示例

yaml
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service
  annotations:
    # 云服务商特定注解
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-internal: "false"
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
  loadBalancerIP: 10.0.0.100  # 固定IP(可选)
  loadBalancerSourceRanges:
  - 192.168.0.0/24  # 限制访问源IP

优势与劣势

  • 优势:外部可访问,高可用,自动管理
  • 劣势:依赖云服务商,可能产生额外费用

4. ExternalName

特点

  • 外部域名映射:将服务映射到外部域名
  • 无代理:不创建代理或负载均衡
  • 简单映射:通过CNAME记录实现

适用场景

  • 集成外部服务
  • 访问集群外部的数据库
  • 服务迁移和过渡

配置示例

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: my.database.example.com
  ports:
  - port: 3306
    protocol: TCP

优势与劣势

  • 优势:配置简单,无需额外资源
  • 劣势:依赖外部服务,无法进行健康检查

5. Headless Service

特点

  • 无ClusterIP:不分配ClusterIP
  • 直接DNS解析:直接返回Pod IP列表
  • 适合有状态应用:与StatefulSet配合使用
  • 自定义服务发现:允许客户端直接访问Pod

适用场景

  • StatefulSet应用
  • 需要稳定网络标识的服务
  • 自定义服务发现机制

配置示例

yaml
apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  clusterIP: None  # Headless Service
  selector:
    app: stateful-app
  ports:
  - port: 80
    targetPort: 8080

优势与劣势

  • 优势:支持有状态应用,灵活的服务发现
  • 劣势:需要客户端处理负载均衡

Service配置详解

基本Service配置

yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
  namespace: default
  labels:
    app: web
    tier: frontend
spec:
  type: ClusterIP
  selector:
    app: web
    tier: frontend
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
  - name: https
    protocol: TCP
    port: 443
    targetPort: 8443
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

完整Service配置

yaml
apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  type: LoadBalancer
  selector:
    app: api
    version: v1.2.0
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30080
  - name: grpc
    protocol: TCP
    port: 50051
    targetPort: 50051
    nodePort: 30081
  externalIPs:
  - 192.168.1.100
  - 192.168.1.101
  externalTrafficPolicy: Local
  healthCheckNodePort: 30082
  loadBalancerIP: 10.0.0.100
  loadBalancerSourceRanges:
  - 192.168.0.0/24
  - 10.0.0.0/8
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  publishNotReadyAddresses: false
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
  - IPv4
  - IPv6

Service端口配置

端口映射关系

┌─────────────────────────────────────────┐
│            Service (ClusterIP)          │
│                                         │
│  Port: 80 ──────┐                      │
│                 │                      │
│  Port: 443 ─────┤                      │
│                 │                      │
│  NodePort: 30080├─┐                    │
│                 │ │                    │
│  NodePort: 30443├─┤                    │
│                 │ │                    │
└─────────────────┘ │                    │
                    │                    │
                    │  ┌─────────────────┘
                    │  │
                    │  ▼
                    │  Pod
                    │  ┌─────────────────┐
                    │  │ Container       │
                    │  │                 │
                    └─►│ TargetPort:8080 │
                       │                 │
                       │ TargetPort:8443 │
                       │                 │
                       └─────────────────┘

端口配置示例

yaml
ports:
# 简单映射
- port: 80          # Service端口
  targetPort: 8080  # Pod容器端口

# 命名端口
- name: http
  protocol: TCP
  port: 80
  targetPort: web-port

# 多端口映射
- name: web
  protocol: TCP
  port: 80
  targetPort: 8080
- name: metrics
  protocol: TCP
  port: 9090
  targetPort: 9090
- name: admin
  protocol: TCP
  port: 8081
  targetPort: 8081

服务发现机制

1. 环境变量

bash
# 自动注入的环境变量
MYAPP_SERVICE_HOST=10.0.0.1
MYAPP_SERVICE_PORT=80
MYAPP_PORT=tcp://10.0.0.1:80
MYAPP_PORT_80_TCP=tcp://10.0.0.1:80
MYAPP_PORT_80_TCP_PROTO=tcp
MYAPP_PORT_80_TCP_PORT=80
MYAPP_PORT_80_TCP_ADDR=10.0.0.1

2. DNS服务发现

bash
# 集群内DNS解析
<service-name>.<namespace>.svc.cluster.local

# 示例
web-service.default.svc.cluster.local
api-service.production.svc.cluster.local

3. CoreDNS配置

corefile
.:53 {
    errors
    health
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

操作命令

创建Service

bash
# 从YAML文件创建
kubectl apply -f service.yaml

# 快速创建
kubectl expose deployment nginx --port=80 --target-port=8080 --type=NodePort

# 创建LoadBalancer
kubectl expose deployment nginx --port=80 --type=LoadBalancer

查看Service

bash
# 查看所有Service
kubectl get services
kubectl get svc

# 查看详细信息
kubectl describe service <service-name>

# 查看Endpoint
kubectl get endpoints <service-name>
kubectl describe endpoints <service-name>

# 查看YAML格式
kubectl get service <service-name> -o yaml

测试Service

bash
# 通过临时Pod测试
kubectl run test --image=busybox --rm -it --restart=Never -- wget -O- http://<service-name>:<port>

# 使用curl测试
kubectl run curl --image=curlimages/curl --rm -it --restart=Never -- curl http://<service-name>:<port>

# 查看DNS解析
kubectl run test --image=busybox --rm -it --restart=Never -- nslookup <service-name>

更新Service

bash
# 更新标签选择器
kubectl label pods <pod-name> version=v2
kubectl get endpoints <service-name> --watch

# 更新端口
kubectl edit service <service-name>

# 更新类型
kubectl patch service <service-name> -p '{"spec":{"type":"LoadBalancer"}}'

删除Service

bash
# 删除Service
kubectl delete service <service-name>

# 删除所有Service
kubectl delete services --all

实践示例

示例1:Web应用Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
  labels:
    app: web
    environment: production
spec:
  type: NodePort
  selector:
    app: web
    environment: production
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30080
  - name: https
    protocol: TCP
    port: 443
    targetPort: 8443
    nodePort: 30443
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 3600

示例2:数据库Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  labels:
    app: mysql
    tier: database
spec:
  type: ClusterIP
  clusterIP: None  # Headless Service
  selector:
    app: mysql
    tier: database
  ports:
  - name: mysql
    protocol: TCP
    port: 3306
    targetPort: 3306

示例3:微服务Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: user
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
spec:
  type: ClusterIP
  selector:
    app: user-service
    version: v1.0.0
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
  - name: grpc
    protocol: TCP
    port: 50051
    targetPort: 50051
  - name: metrics
    protocol: TCP
    port: 9090
    targetPort: 9090
  - name: health
    protocol: TCP
    port: 8081
    targetPort: 8081

示例4:外部服务集成

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-api
spec:
  type: ExternalName
  externalName: api.example.com
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-api
subsets:
- addresses:
  - ip: 203.0.113.10
  - ip: 203.0.113.11
  ports:
  - port: 443
    name: https

性能优化

1. 负载均衡策略

内置负载均衡

  • 轮询:默认负载均衡策略
  • 会话保持:基于客户端IP的会话保持
  • 外部流量策略:Local或Cluster模式

负载均衡优化

yaml
# 会话保持配置
sessionAffinity: ClientIP
sessionAffinityConfig:
  clientIP:
    timeoutSeconds: 10800  # 3小时

# 外部流量策略
externalTrafficPolicy: Local  # 保留源IP,减少网络跳数

云负载均衡器优化

  • 选择合适的负载均衡器类型:ALB/NLB/CLB
  • 启用跨区域负载均衡:提高高可用性
  • 配置健康检查:快速检测故障节点
  • 优化会话超时:根据应用特性设置

2. 连接管理

连接池优化

  • 使用连接池:减少连接建立开销
  • 配置合理的连接超时:避免连接泄漏
  • 监控连接状态:及时发现连接问题

网络连接优化

  • TCP Keepalive:保持长连接
  • MTU配置:优化网络数据包大小
  • 网络拥塞控制:使用现代拥塞控制算法

3. 网络优化

网络策略

  • 配置网络策略:限制不必要的网络流量
  • 使用Calico或Cilium:提供更高级的网络功能
  • 优化网络插件:选择适合场景的网络插件

服务发现优化

  • DNS缓存:减少DNS解析开销
  • 使用环境变量:适合简单场景
  • 服务网格:复杂场景使用Istio等服务网格

4. 资源优化

端口管理

  • 使用命名端口:提高可读性和可维护性
  • 避免端口冲突:合理规划端口使用
  • 统一端口规范:建立组织级端口使用规范

标签和选择器

  • 优化标签选择器:减少标签数量,提高匹配效率
  • 使用标准化标签:便于管理和自动化
  • 避免过多标签:减少调度开销

5. 监控与调优

监控指标

  • 服务健康状态:Endpoint就绪状态
  • 网络流量:请求数、响应时间
  • 连接状态:活跃连接数、连接错误
  • 负载均衡性能:后端Pod分布情况

性能调优

  • 根据负载调整副本数:使用HPA自动扩缩容
  • 优化Pod分布:使用反亲和性提高可用性
  • 调整负载均衡参数:根据应用特性优化
  • 定期性能测试:发现性能瓶颈

高级特性

1. Headless Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  clusterIP: None  # Headless Service
  selector:
    app: stateful-app
  ports:
  - port: 80
    targetPort: 8080

特点

  • 没有ClusterIP
  • 直接返回Pod IP列表
  • 适合StatefulSet
  • 支持自定义服务发现

2. 会话保持

yaml
sessionAffinity: ClientIP
sessionAffinityConfig:
  clientIP:
    timeoutSeconds: 10800  # 3小时

支持的模式

  • None: 无会话保持
  • ClientIP: 基于客户端IP

3. 外部流量策略

yaml
externalTrafficPolicy: Local

策略

  • Cluster: 流量可能转发到其他节点
  • Local: 只转发到本地节点,保留源IP

4. 负载均衡器配置

yaml
spec:
  type: LoadBalancer
  loadBalancerIP: 10.0.0.100
  loadBalancerSourceRanges:
  - 192.168.0.0/24
  - 10.0.0.0/8

故障排查

常见问题

1. Service无法访问

bash
# 检查Service状态
kubectl describe service <service-name>

# 检查Endpoint
kubectl get endpoints <service-name>

# 检查Pod标签
kubectl get pods --show-labels

# 测试网络连通性
kubectl run test --image=busybox --rm -it --restart=Never -- ping <pod-ip>

2. Endpoint为空

bash
# 检查Pod标签是否匹配
kubectl get pods --selector=app=<app-name>

# 检查Service选择器
kubectl describe service <service-name>

# 验证标签匹配
kubectl get pods -l app=<app-name>

3. DNS解析失败

bash
# 检查CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 测试DNS解析
kubectl run test --image=busybox --rm -it --restart=Never -- nslookup <service-name>

# 查看DNS配置
kubectl get configmap -n kube-system coredns -o yaml

4. NodePort无法访问

bash
# 检查节点防火墙
sudo iptables -L -n | grep <node-port>

# 检查节点网络配置
ip addr show

# 测试节点端口
curl http://<node-ip>:<node-port>

最佳实践

1. 命名规范

  • 使用有意义的服务名称
  • 遵循命名约定
  • 保持一致性

2. 标签管理

  • 使用标准化的标签
  • 便于服务发现
  • 支持自动化

3. 端口管理

  • 使用命名端口
  • 避免端口冲突
  • 记录端口用途

4. 安全配置

  • 限制访问范围
  • 使用网络策略
  • 启用TLS加密

5. 监控告警

  • 监控服务健康状态
  • 设置端点监控
  • 配置告警规则

6. 文档记录

  • 记录服务配置
  • 说明访问方式
  • 更新维护文档

总结

Service是Kubernetes中实现服务发现和负载均衡的核心组件,通过本章的学习,您已经掌握了:

核心功能

  1. 服务发现

    • 为动态Pod提供稳定的访问地址
    • 通过标签选择器关联Pod
    • 自动更新端点列表
  2. 负载均衡

    • 在多个Pod实例间分配流量
    • 支持多种负载均衡策略
    • 实现会话保持
  3. 网络抽象

    • 隐藏Pod的具体实现细节
    • 提供统一的访问入口
    • 支持多种访问模式

服务类型

  1. ClusterIP:集群内部访问,安全可靠
  2. NodePort:通过节点端口外部访问,适合开发测试
  3. LoadBalancer:利用云负载均衡器,适合生产环境
  4. ExternalName:映射到外部域名,用于集成外部服务
  5. Headless Service:无ClusterIP,适合有状态应用

性能优化

  1. 负载均衡策略:轮询、会话保持、外部流量策略
  2. 连接管理:连接池优化、网络连接优化
  3. 网络优化:网络策略、服务发现优化、网络插件选择
  4. 资源优化:端口管理、标签和选择器优化
  5. 监控与调优:关键指标监控、性能测试和调优

高级特性

  • Headless Service:支持有状态应用的稳定网络标识
  • 会话保持:基于客户端IP的会话关联
  • 外部流量策略:Local模式保留源IP
  • 负载均衡器配置:云服务商特定配置

Service为Kubernetes集群中的应用提供了可靠的网络访问层,是构建微服务架构的基础。通过合理配置Service,您可以实现:

  • 服务的高可用性:通过多副本和负载均衡
  • 灵活的网络访问:从内部到外部的多种访问方式
  • 性能优化:根据应用特性调整配置
  • 安全的网络隔离:通过网络策略和访问控制

掌握Service的使用是Kubernetes学习的重要组成部分,它为您提供了构建可靠、高效、安全的容器化应用的能力。

下一步学习