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/name、app.kubernetes.io/version 等标准标签,避免随意命名。
  2. 端口命名 :在 Service 的 ports 中为端口添加名称(如 http、grpc),提高可读性。
  3. 健康检查 :为后端 Pod 配置 livenessProbe 和 readinessProbe,确保 Service 只路由到健康实例。
  4. 资源限制:为 Service 关联的 Pod 设置 CPU/内存请求和限制,防止单个 Pod 占用过多资源。

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

相关推荐
赵文宇(温玉)3 天前
CoreDNS的hosts插件的缺行配置导致k8s集群异常
容器·kubernetes·rancher
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
Thneonl3 天前
你的 Pod 为什么 Pending:调度器两阶段
后端·kubernetes
不吃香菜kkk、3 天前
CI/CD(GitOps)学习与部署手册
运维·云原生·容器·kubernetes·云计算·jenkins·argocd
ysu_03144 天前
【2026】K8s GPU调度空占怎么解?Kueue与Volcano Gang配置
云原生·kubernetes·gpu算力·volcano·ai基础设施·kueue·gang scheduling
哈__5 天前
KES-Operator重塑Kubernetes环境下的KES数据库集群管理
数据库·kubernetes·operator·kes
九皇叔叔5 天前
K8S 资源菜单
docker·容器·kubernetes·k8s
安易算力5 天前
PUE优化工程实践:从1.5到1.2的制冷架构与气流组织改造路径
网络·python·容器·架构·kubernetes
kuroomi6 天前
Ingress-Nginx与kubernetes 网络
linux·运维·网络·kubernetes
程序猿阿越6 天前
containerd如何创建Pod
后端·kubernetes·源码阅读