Kubernetes服务发现机制与CoreDNS实战引言服务发现是Kubernetes的核心功能之一它使得容器化应用能够自动发现和通信。本文将深入探讨Kubernetes服务发现的实现机制并详细介绍CoreDNS的配置和优化。一、服务发现架构1.1 服务发现层次┌─────────────────────────────────────────────────────────────┐ │ Kubernetes服务发现架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ DNS层 │ │ │ │ CoreDNS / kube-dns │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Service层 │ │ │ │ ClusterIP / NodePort / LoadBalancer / ExternalName │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Endpoints层 │ │ │ │ Pod IP / Port / Ready状态 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Pod层 │ │ │ │ 应用容器 / Sidecar │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘1.2 服务类型对比类型说明适用场景ClusterIP集群内部IP集群内服务通信NodePort节点端口映射外部访问集群服务LoadBalancer云负载均衡器生产环境外部访问ExternalName外部DNS名称访问集群外部服务二、CoreDNS部署与配置2.1 CoreDNS部署apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: coredns rules: - apiGroups: [] resources: [services, endpoints, pods] verbs: [list, watch] --- apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system spec: replicas: 2 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns spec: serviceAccountName: coredns containers: - name: coredns image: coredns/coredns:1.11.1 args: - -conf - /etc/coredns/Corefile ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP volumeMounts: - name: config-volume mountPath: /etc/coredns volumes: - name: config-volume configMap: name: coredns2.2 CoreDNS配置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 CoreDNS插件说明插件功能说明errors错误日志记录DNS查询错误health健康检查提供健康检查端点ready就绪检查提供就绪检查端点kubernetesK8s服务发现提供集群内DNS解析prometheus指标暴露暴露Prometheus指标forward上游转发转发非集群域名查询cache缓存DNS响应缓存reload热重载支持配置热重载三、服务发现实战3.1 创建ServiceapiVersion: v1 kind: Service metadata: name: my-service namespace: default spec: selector: app: my-app ports: - name: http port: 80 targetPort: 8080 type: ClusterIP3.2 服务DNS名称格式# ClusterIP服务 my-service.default.svc.cluster.local # 不同命名空间 my-service.other-namespace.svc.cluster.local # 短名称同命名空间 my-service # 带端口的完整名称 my-service.default.svc.cluster.local:803.3 服务发现测试# 在Pod内测试DNS解析 kubectl run -it --rm dns-test --imagebusybox:1.35 -- nslookup my-service # 测试跨命名空间解析 kubectl run -it --rm dns-test --imagebusybox:1.35 -- nslookup kubernetes.default # 测试外部DNS解析 kubectl run -it --rm dns-test --imagebusybox:1.35 -- nslookup www.google.com四、高级服务发现配置4.1 外部服务发现apiVersion: v1 kind: Service metadata: name: external-database namespace: default spec: type: ExternalName externalName: database.example.com4.2 Headless服务apiVersion: v1 kind: Service metadata: name: stateful-service namespace: default spec: clusterIP: None selector: app: stateful-app ports: - name: http port: 80 targetPort: 80804.3 自定义DNS配置apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods verified ttl 30 } hosts /etc/coredns/custom-hosts { 10.100.200.300 my-custom-service.example.com fallthrough } forward . 8.8.8.8 8.8.4.4 cache 30 }五、CoreDNS性能优化5.1 缓存优化apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors cache 60 { success 9984 60 denial 9984 60 } kubernetes cluster.local { ttl 30 } forward . /etc/resolv.conf }5.2 健康检查优化apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { health { lameduck 10s interval 5s timeout 2s } ready kubernetes cluster.local forward . /etc/resolv.conf }5.3 资源配置apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system spec: template: spec: containers: - name: coredns image: coredns/coredns:1.11.1 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi六、服务发现监控6.1 指标收集apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: coredns-monitor namespace: monitoring spec: selector: matchLabels: k8s-app: kube-dns endpoints: - port: metrics interval: 15s6.2 监控指标# CoreDNS监控仪表盘配置 apiVersion: v1 kind: ConfigMap metadata: name: coredns-dashboard namespace: monitoring data: dashboard.json: | { title: CoreDNS Dashboard, panels: [ {type: graph, target: coredns_dns_requests_total}, {type: graph, target: coredns_dns_request_duration_seconds}, {type: graph, target: coredns_cache_hits_total}, {type: graph, target: coredns_kubernetes_dns_programming_duration_seconds} ] }七、常见问题与解决方案7.1 DNS解析失败# 问题Pod无法解析服务名称 # 解决方案检查CoreDNS状态 kubectl get pods -n kube-system -l k8s-appkube-dns kubectl logs -n kube-system coredns-xxx # 检查DNS配置 kubectl get configmap coredns -n kube-system -o yaml7.2 服务发现延迟# 问题DNS解析延迟高 # 解决方案增加缓存时间 kubectl apply -f coredns-config.yaml # 检查缓存命中率 kubectl port-forward -n kube-system coredns-xxx 9153:9153 curl http://localhost:9153/metrics | grep coredns_cache_hits7.3 服务IP变化# 问题服务IP频繁变化导致连接问题 # 解决方案使用服务名称而非IP # 配置适当的连接超时和重试八、服务发现最佳实践8.1 使用服务名称# 推荐使用服务名称 env: - name: DATABASE_URL value: jdbc:mysql://mysql-service.default.svc.cluster.local:3306/mydb # 不推荐使用固定IP # env: # - name: DATABASE_URL # value: jdbc:mysql://10.96.0.10:3306/mydb8.2 配置健康检查apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: my-app:latest ports: - containerPort: 8080 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 38.3 服务暴露策略# 内部服务使用ClusterIP kubectl expose deployment my-app --typeClusterIP --port80 # 需要外部访问使用LoadBalancer kubectl expose deployment my-app --typeLoadBalancer --port80 # 测试环境使用NodePort kubectl expose deployment my-app --typeNodePort --port80结论服务发现是Kubernetes集群内部通信的基础CoreDNS作为默认的DNS服务提供了可靠的服务发现能力。通过合理配置CoreDNS和服务能够实现高效、可靠的服务通信。