kubernetes核心概念 Service

零基础入门 Kubernetes Service:概念、YAML 配置示例与常见问题排查指南

一、Kubernetes Service 的核心概念

Kubernetes Service 是集群中一组 Pod 的逻辑抽象,通过静态 IP 地址和 DNS 名称提供稳定的网络访问入口。其核心价值在于:

  1. 解耦生命周期:Pod 可能因崩溃、扩容或缩容频繁重建,但 Service 的 IP 和 DNS 名称保持不变,避免客户端频繁更新访问地址。
  2. 负载均衡:自动将流量分发到后端 Pod,例如一个 Service 可关联 3 个 Nginx Pod,客户端请求会被均衡分配到不同实例。
  3. 服务发现 :通过 DNS 名称(如 my-service.default.svc.cluster.local)实现内部服务间的自动发现,无需硬编码 IP。

典型应用场景

  • 微服务架构:订单服务通过 Service 访问用户服务,无需关心用户服务的 Pod 数量或位置。
  • 数据库访问:应用通过 Service 连接 MySQL 集群,即使主从切换或扩容,访问地址不变。
  • 外部流量接入:通过 NodePort 或 LoadBalancer 类型 Service 将集群内服务暴露给外部用户。

二、Service 的 4 种类型及 YAML 配置示例

1. ClusterIP(默认类型)

用途 :仅在集群内部访问,适用于后端微服务间的通信。
配置示例

yaml 复制代码
yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend  # 匹配标签为 app=backend 的 Pod
  ports:
    - protocol: TCP
      port: 80      # Service 的端口
      targetPort: 8080  # Pod 的端口
  type: ClusterIP  # 可省略,默认值

验证命令

csharp 复制代码
bash
kubectl get svc backend-service  # 查看 Service 的 ClusterIP(如 10.96.123.45)
kubectl describe svc backend-service  # 检查 Endpoints 是否包含 Pod IP

2. NodePort

用途 :通过集群节点的固定端口暴露服务,适用于开发测试或裸金属集群。
配置示例

yaml 复制代码
yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30080  # 默认范围 30000-32767,可省略自动分配
  type: NodePort

验证命令

csharp 复制代码
bash
kubectl get svc web-service  # 查看 NodePort 端口(如 30080)
curl http://<任意节点IP>:30080  # 从集群外部访问

3. LoadBalancer

用途 :在云环境中自动创建外部负载均衡器(如 AWS ELB、GCP LB),适用于生产环境。
配置示例

yaml 复制代码
yaml
apiVersion: v1
kind: Service
metadata:
  name: public-service
spec:
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

验证命令

arduino 复制代码
bash
kubectl get svc public-service  # 查看 EXTERNAL-IP(如 a1b2c3d4.us-west-2.elb.amazonaws.com)
curl http://<EXTERNAL-IP>  # 通过负载均衡器访问

4. ExternalName

用途 :将 Service 映射到外部 DNS 名称,适用于访问集群外部服务(如数据库)。
配置示例

yaml 复制代码
yaml
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: mysql.example.com  # 外部数据库的 DNS 名称

验证命令

bash 复制代码
bash
kubectl exec -it <任意Pod> -- nslookup external-db  # 解析到 mysql.example.com

三、常见问题排查指南

问题 1:Service 无法访问

排查步骤

  1. 检查 Service 状态

    csharp 复制代码
    bash
    kubectl get svc <service-name> -o wide  # 确认 IP 和端口
    kubectl describe svc <service-name>  # 检查 Events 和 Endpoints
    • Endpoints 为空,说明 Selector 未匹配到 Pod,需检查 Pod 标签是否与 Service 的 spec.selector 一致。
  2. 验证 Pod 状态

    ini 复制代码
    bash
    kubectl get pods -l app=<label-value>  # 检查关联 Pod 是否存在
    kubectl logs <pod-name>  # 查看 Pod 日志是否有错误
  3. 测试网络连通性

    ruby 复制代码
    bash
    kubectl run -it --rm debug --image=busybox --restart=Never -- sh
    # 在调试容器中执行
    ping <service-cluster-ip>  # 测试 ClusterIP 可达性
    wget <service-cluster-ip>:<port>  # 测试端口连通性

问题 2:NodePort 类型 Service 外部无法访问

排查步骤

  1. 检查节点端口监听

    perl 复制代码
    bash
    # 在集群节点上执行
    netstat -tulnp | grep <nodePort>  # 确认端口被 kube-proxy 监听
  2. 验证防火墙规则

    • 云平台:检查安全组是否放行 NodePort 端口(如 30080)。
    • 裸金属集群:使用 iptables -L -n 检查是否有 DROP 规则。
  3. 测试从节点直接访问

    bash 复制代码
    bash
    curl http://localhost:<nodePort>  # 从节点本地访问

问题 3:DNS 解析失败

排查步骤

  1. 检查 CoreDNS 状态

    ini 复制代码
    bash
    kubectl get pods -n kube-system -l k8s-app=kube-dns
    kubectl logs <coredns-pod-name> -n kube-system  # 查看日志是否有错误
  2. 测试 DNS 解析

    ini 复制代码
    bash
    kubectl run -it --rm dns-test --image=busybox --restart=Never -- sh
    # 在调试容器中执行
    nslookup <service-name>.<namespace>.svc.cluster.local  # 完整 FQDN 解析
    nslookup <service-name>  # 同命名空间内可省略后缀

问题 4:负载均衡不均匀

排查步骤

  1. 检查 Service 的 sessionAffinity

    yaml 复制代码
    yaml
    spec:
      sessionAffinity: ClientIP  # 默认 None(轮询),可改为 ClientIP 固定 IP 到同一 Pod
  2. 验证 Pod 资源使用

    ini 复制代码
    bash
    kubectl top pods -l app=<label-value>  # 检查 CPU/内存是否均衡
  3. 检查网络插件

    • 若使用 Calico/Flannel,检查 kube-proxy 日志是否有 iptables 规则更新失败:

      perl 复制代码
      bash
      kubectl logs <kube-proxy-pod-name> -n kube-system | grep "error"

四、最佳实践

  1. 标签设计 :使用 app.kubernetes.io/nameapp.kubernetes.io/version 等标准标签,避免随意命名。
  2. 端口命名 :在 Service 的 ports 中为端口添加名称(如 httpgrpc),提高可读性。
  3. 健康检查 :为后端 Pod 配置 livenessProbereadinessProbe,确保 Service 只路由到健康实例。
  4. 资源限制:为 Service 关联的 Pod 设置 CPU/内存请求和限制,防止单个 Pod 占用过多资源。

通过掌握 Service 的核心概念、配置方法和排查技巧,您可以高效管理 Kubernetes 集群中的服务通信,为后续部署复杂应用(如 Istio 服务网格、Knative 无服务器)打下坚实基础。

相关推荐
有谁看见我的剑了?3 小时前
k8s-容器探针和生命周期回调学习
学习·容器·kubernetes
Rancher社区5 小时前
Rancher 社区双周报|聚焦 Harvester 新特性:网络、存储与虚拟化全面升级
kubernetes
linweidong10 小时前
解锁 Ray 在 Kubernetes 上的弹性伸缩:打造高效、稳定的分布式作业
分布式·容器·kubernetes·ray·keda·autoscaling·ray推理
Katzelala16 小时前
[K8S学习笔记] Service和Ingress的关系
笔记·学习·kubernetes
有谁看见我的剑了?16 小时前
k8s-init容器学习
学习·容器·kubernetes
有谁看见我的剑了?1 天前
k8s-Sidecar容器学习
学习·容器·kubernetes
2201_761199041 天前
7.k8s四层代理service
云原生·容器·kubernetes
清风笑烟语1 天前
Ubuntu 24.04 搭建k8s 1.33.4
linux·ubuntu·kubernetes
能不能别报错1 天前
K8s学习笔记(二):Pod
笔记·学习·kubernetes