服务发现 #

一、服务发现概述 #

服务发现是Kubernetes中自动检测和定位服务的机制,使应用能够相互通信而无需硬编码地址。

1.1 服务发现方式 #

text
服务发现方式
    │
    ├── DNS服务发现
    │   ├── CoreDNS
    │   └── 域名解析
    │
    └── 环境变量发现
        ├── {SVCNAME}_SERVICE_HOST
        └── {SVCNAME}_SERVICE_PORT

1.2 DNS命名规则 #

text
DNS命名格式
    │
    └── <service-name>.<namespace>.svc.<cluster-domain>

示例
    │
    ├── nginx-service.default.svc.cluster.local
    ├── mysql.database.svc.cluster.local
    └── redis.cache.svc.cluster.local

简写形式
    │
    ├── 同命名空间: nginx-service
    └── 跨命名空间: mysql.database

二、CoreDNS #

2.1 CoreDNS概述 #

CoreDNS是Kubernetes的默认DNS服务器,提供服务发现功能。

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

# 查看CoreDNS Service
kubectl get svc -n kube-system kube-dns

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

2.2 CoreDNS配置 #

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        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 {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }

2.3 配置说明 #

插件 功能
errors 错误日志
health 健康检查
ready 就绪检查
kubernetes Kubernetes服务发现
prometheus 指标暴露
forward 上游DNS转发
cache DNS缓存
loop 循环检测
reload 配置热加载
loadbalance 负载均衡

三、DNS解析 #

3.1 Service DNS #

bash
# 在Pod中测试DNS解析
kubectl exec -it <pod-name> -- nslookup kubernetes

# 输出示例
Server:    10.96.0.10
Address:   10.96.0.10

Name:      kubernetes.default.svc.cluster.local
Address:   10.96.0.1

3.2 Pod DNS #

yaml
# Headless Service的Pod DNS
# 格式: <pod-name>.<service-name>.<namespace>.svc.cluster.local

# StatefulSet Pod DNS
# web-0.nginx-headless.default.svc.cluster.local
# web-1.nginx-headless.default.svc.cluster.local

3.3 DNS策略 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: dns-demo
spec:
  dnsPolicy: ClusterFirst
  containers:
  - name: app
    image: nginx
策略 说明
ClusterFirst 优先使用集群DNS
Default 使用节点DNS配置
ClusterFirstWithHostNet 主机网络使用集群DNS
None 自定义DNS配置

3.4 自定义DNS配置 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: custom-dns
spec:
  dnsPolicy: None
  dnsConfig:
    nameservers:
    - 8.8.8.8
    - 8.8.4.4
    searches:
    - default.svc.cluster.local
    - svc.cluster.local
    - cluster.local
    options:
    - name: ndots
      value: "5"
  containers:
  - name: app
    image: nginx

四、环境变量服务发现 #

4.1 自动注入环境变量 #

bash
# 查看Service环境变量
kubectl exec <pod-name> -- env | grep SERVICE

# 输出示例
NGINX_SERVICE_SERVICE_HOST=10.96.145.23
NGINX_SERVICE_SERVICE_PORT=80
NGINX_SERVICE_PORT=tcp://10.96.145.23:80
NGINX_SERVICE_PORT_80_TCP=tcp://10.96.145.23:80
NGINX_SERVICE_PORT_80_TCP_PROTO=tcp
NGINX_SERVICE_PORT_80_TCP_PORT=80
NGINX_SERVICE_PORT_80_TCP_ADDR=10.96.145.23

4.2 环境变量格式 #

text
环境变量格式
    │
    ├── {SVCNAME}_SERVICE_HOST
    │   └── 服务ClusterIP
    │
    ├── {SVCNAME}_SERVICE_PORT
    │   └── 服务端口
    │
    └── {SVCNAME}_PORT_{PORT}_{PROTO}
        └── 端口详细信息

4.3 使用环境变量 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: env-demo
spec:
  containers:
  - name: app
    image: nginx
    env:
    - name: DB_HOST
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: SERVICE_HOST
      value: $(NGINX_SERVICE_SERVICE_HOST)

五、跨命名空间访问 #

5.1 完整DNS名称 #

yaml
# 跨命名空间访问Service
apiVersion: v1
kind: Pod
metadata:
  name: cross-ns-pod
  namespace: frontend
spec:
  containers:
  - name: app
    image: nginx
    env:
    - name: DB_HOST
      value: "mysql.database.svc.cluster.local"
    - name: REDIS_HOST
      value: "redis.cache.svc.cluster.local"

5.2 简写形式 #

yaml
# 同命名空间简写
env:
- name: DB_HOST
  value: "mysql-service"

# 跨命名空间简写
env:
- name: DB_HOST
  value: "mysql-service.database"

六、服务注册 #

6.1 自动注册 #

text
服务注册流程
    │
    ├── 1. 创建Service
    │
    ├── 2. Endpoints Controller创建Endpoints
    │
    ├── 3. CoreDNS添加DNS记录
    │
    └── 4. kube-proxy更新网络规则

6.2 手动注册外部服务 #

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  ports:
  - port: 3306
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-db
subsets:
- addresses:
  - ip: 192.168.1.100
  ports:
  - port: 3306

七、DNS调试 #

7.1 DNS测试Pod #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: dns-test
    image: busybox
    command: ["sleep", "3600"]
bash
# 创建测试Pod
kubectl apply -f dns-test.yaml

# 测试DNS解析
kubectl exec -it dns-test -- nslookup kubernetes
kubectl exec -it dns-test -- nslookup nginx-service
kubectl exec -it dns-test -- nslookup nginx-service.default.svc.cluster.local

# 查看DNS配置
kubectl exec -it dns-test -- cat /etc/resolv.conf

7.2 DNS查询命令 #

bash
# 使用nslookup
kubectl exec -it dns-test -- nslookup kubernetes

# 使用dig
kubectl exec -it dns-test -- dig kubernetes.default.svc.cluster.local

# 使用getent
kubectl exec -it dns-test -- getent hosts kubernetes

八、高级配置 #

8.1 自定义域名 #

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  example.server: |
    example.com:53 {
      forward . 8.8.8.8
    }

8.2 Hosts记录 #

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  test.override: |
    hosts {
      192.168.1.100 myapp.local
      fallthrough
    }

8.3 Stub域名 #

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
        }
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
    example.com:53 {
        forward . 8.8.8.8
    }

九、故障排查 #

9.1 DNS问题诊断 #

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

# 检查CoreDNS日志
kubectl logs -n kube-system -l k8s-app=kube-dns

# 检查CoreDNS Service
kubectl get svc -n kube-system kube-dns

# 测试DNS解析
kubectl exec -it dns-test -- nslookup kubernetes

9.2 常见问题 #

问题 原因 解决方案
DNS解析失败 CoreDNS异常 检查CoreDNS状态
解析超时 网络问题 检查网络配置
外部域名无法解析 上游DNS问题 检查forward配置

十、总结 #

10.1 核心要点 #

要点 说明
DNS服务 CoreDNS提供服务发现
DNS格式 service.namespace.svc.cluster.local
DNS策略 ClusterFirst、Default等
环境变量 自动注入Service信息

10.2 下一步 #

掌握了服务发现后,让我们学习 存储卷,了解Kubernetes的存储管理机制。

最后更新:2026-03-28