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 无服务器)打下坚实基础。

相关推荐
阿方索27 分钟前
Kubernetes Pod 管理
云原生·容器·kubernetes
汪碧康1 小时前
一文掌握k8s的健康检查探针
云原生·容器·kubernetes·k8s·xkube·k8s管理平台
危笑ioi1 小时前
k8s创建pv和pvc部署jenkins
kubernetes·jenkins
有谁看见我的剑了?3 小时前
K8s crictl 客户端学习
学习·容器·kubernetes
KubeSphere 云原生3 小时前
云原生周刊:Kubernetes 1.35 新机制与云原生生态更新
云原生·容器·kubernetes
腾讯数据架构师4 小时前
cube studio 存储资源对接ceph
ceph·kubernetes·cube-studio·ai平台
青衫客3620 小时前
浅谈Kubernetes在systemd cgroup模式下的Slice/Scope组织结构
云原生·容器·kubernetes
王九思20 小时前
Podman 介绍
docker·云原生·kubernetes·podman
Gold Steps.1 天前
K8S基于 Argo Rollouts 的高级版本发布实践
云原生·容器·kubernetes
孤岛悬城1 天前
61 K8s之Pod控制器与配置资源管理
云原生·容器·kubernetes