温馨提示×

k8s服务发现机制在centos如何实现

小樊
42
2026-01-02 10:41:35
栏目: 智能运维

在 CentOS 上落地 Kubernetes 服务发现

一 核心原理与组件

  • Service + Endpoints:Service 为一组 Pod 提供稳定的虚拟 IP(ClusterIP)和端口;与之对应的 Endpoints 对象维护当前匹配 Pod 的 IP:Port 列表。Kubernetes 通过标签选择器将 Service 与后端 Pod 动态关联,并持续更新 Endpoints。这样调用方只需使用 Service 的地址,无需感知 Pod 的频繁变化。
  • kube-proxy:运行在每个节点上,监听 Service/Endpoints 变化,维护节点上的 iptables/ipvs 转发规则,实现四层负载均衡与故障摘除。
  • DNS 服务发现:集群内置的 CoreDNS 持续监听 API Server,为每个 Service 自动生成 DNS 记录,典型格式为:..svc.cluster.local。Pod 内可直接用服务名访问,例如 http://my-svc:80;跨命名空间需使用全域名 my-svc.other-ns.svc.cluster.local
  • 发现方式:主流为 DNS;此外 kubelet 会在 Pod 启动时注入同名的 环境变量(如 MYAPP_SVC_SERVICE_HOST/PORT),但仅对“启动前已存在”的 Service 有效,动态变更不敏感,通常作为备选。

二 在 CentOS 上的落地步骤

  • 前提:已在 CentOS 7/8 上部署好 Kubernetes 集群(kubelet、kube-proxy、apiserver、CoreDNS 运行正常),并确认节点网络与 kube-proxy 转发模式(iptables/ipvs)可用。
  • 步骤 1 创建后端应用与 Service
    示例(保存为 demo.yaml):
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: backend
      labels:
        app: demo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: demo
      template:
        metadata:
          labels:
            app: demo
        spec:
          containers:
          - name: httpd
            image: httpd:2.4
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: backend
      namespace: default
    spec:
      selector:
        app: demo
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
    
    执行创建并验证:
    kubectl apply -f demo.yaml
    kubectl get svc backend          # 应见 CLUSTER-IP 与 80/TCP
    kubectl get endpoints backend   # 应见后端 Pod IP:80 列表
    
  • 步骤 2 通过 DNS 发现并访问
    在集群内临时进入调试容器验证解析与连通:
    kubectl run -it --rm debug --image=busybox:1.36 --restart=Never -- nslookup backend.default.svc.cluster.local
    kubectl run -it --rm debug --image=busybox:1.36 --restart=Never -- wget -qO- http://backend:80
    
    跨命名空间访问示例:http://backend.other-ns.svc.cluster.local:80
  • 步骤 3 验证 kube-proxy 转发与 Endpoints 联动
    扩容/缩容或删除 Pod 后,确认 Endpoints 实时更新且访问不受影响:
    kubectl scale deployment backend --replicas=3
    kubectl get endpoints backend -w
    
    若使用 NodePort/LoadBalancer 对外暴露,可在节点访问 NodeIP:NodePort 或云厂商提供的负载均衡地址,内部依然通过 Service 名称进行服务发现。

三 常见场景与配置要点

  • 跨命名空间调用:使用全域名 ..svc.cluster.local;同一命名空间可直接用
  • 无头服务 Headless(StatefulSet 常用):将 Service 的 clusterIP: None,DNS 返回后端 Pod IP 列表,适合需要直连或客户端自实现负载均衡的场景(如数据库集群)。
  • 外部访问:使用 NodePort/LoadBalancer 类型配合 Ingress 做统一域名与路径路由;内部服务间仍推荐用 DNS 名称。
  • 健康检查与可用性:为 Pod 配置 readinessProbe/livenessProbe,确保流量只转发到健康实例;配合副本数提升弹性。
  • 安全加固:开启 ServiceAccountRBACNetworkPolicy 限制跨服务访问;对外暴露面最小化。

四 排查清单

  • DNS 解析失败:进入 Pod 执行 nslookup kubernetes.default.svc.cluster.local;检查 CoreDNS Pod 就绪与日志(kubectl -n kube-system logs -l k8s-app=coredns);确认 Pod 的 dnsPolicy/etc/resolv.conf 包含集群 DNS 服务 IP。
  • 服务不通但 DNS 正常kubectl get endpoints <svc> 是否为空;检查 selector 是否匹配 Pod 标签;查看 kube-proxy 与节点 iptables/ipvs 规则是否生效(iptables-save | grep <svc-cluster-ip>ipvsadm -Ln)。
  • 旧环境变量干扰:应用优先使用 DNS;环境变量方式仅在 Service 先于 Pod 创建时有效,且对后续变更不敏感。
  • Headless 场景:确认 clusterIP: NoneStatefulSetserviceName 指向该 Headless Service,客户端能解析到多个 Pod IP。

0