16.4.7 跨集群服务发现与多集群网络
跨集群服务发现与多集群网络#
跨集群场景常见于多数据中心、混合云与多地域部署,需要解决服务发现、网络互通、流量治理与统一可观测问题。目标是在不牺牲隔离性的前提下,实现跨集群的服务访问与容灾切换。
1. 原理与架构草图#
2. 需求与挑战(要点)#
- 服务发现一致性:跨集群解析同一服务名或全局服务名。
- 网络互通与隔离:Pod/Service网段可达且可控。
- 流量治理:就近访问、主备切换与灰度比例。
- 可观测性:跨集群链路指标与日志统一。
3. 典型实现模式与示例#
模式A:DNS级别多集群发现(简化版)
- 思路:ExternalDNS/全局DNS将服务域名解析到多集群入口。
- 优点:简单;缺点:健康检查与细粒度治理有限。
模式B:Kubernetes MCS(标准化)
- 思路:ServiceExport/ServiceImport 同步跨集群服务与DNS。
- 需要:MCS控制器与多集群DNS插件支持。
模式C:网关+服务网格
- 思路:东西向网关暴露服务,网格提供mTLS与治理策略。
- 适合:复杂流量治理与多活。
4. Kubernetes MCS 安装与示例#
以下示例使用 MCS API CRD + CoreDNS 插件 的典型流程(以两集群为例,A/B 均需操作)。
4.1 安装 MCS API CRD(两集群)
# 安装 MCS API CRD(Cluster A / Cluster B 都执行)
kubectl apply -f https://github.com/kubernetes-sigs/mcs-api/releases/download/v0.1.0/mcs-crds.yaml
# 解释:
# - ServiceExport/ServiceImport CRD 供控制器与DNS插件使用
4.2 部署示例服务(Cluster A)
# 文件:svc-a.yaml
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-a
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: echo-a
template:
metadata:
labels:
app: echo-a
spec:
containers:
- name: echo
image: hashicorp/http-echo:0.2.3
args: ["-text=hello-from-cluster-a"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: echo
namespace: demo
spec:
selector:
app: echo-a
ports:
- port: 80
targetPort: 5678
kubectl apply -f svc-a.yaml
kubectl -n demo get svc,po -l app=echo-a
4.3 导出服务(Cluster A)
# 文件:export-echo.yaml
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
name: echo
namespace: demo
kubectl apply -f export-echo.yaml
# 解释:
# - 将 demo/echo 标记为可跨集群发现
4.4 导入服务与解析(Cluster B)
这里假设已经有 MCS 控制器与DNS插件运行(如 Kubefed/MCS-controller 实现)。
# 验证 ServiceImport(由控制器自动创建)
kubectl -n demo get serviceimport echo -o yaml
# 在 Cluster B 中解析全局服务名(示例格式)
kubectl -n demo run dns-test --rm -it --image=busybox:1.36 --restart=Never -- \
nslookup echo.demo.svc.clusterset.local
预期效果
- echo.demo.svc.clusterset.local 返回 Cluster A 的地址列表。
- Cluster B 访问 curl http://echo.demo.svc.clusterset.local 返回 hello-from-cluster-a。
5. 多集群网络互通示例(CNI 互通 + 网段规划)#
5.1 网段规划检查
# 检查 Cluster A/B 的 Pod/Service CIDR
kubectl cluster-info dump | grep -m 1 -E "clusterCIDR|serviceCIDR"
# 解释:
# - Pod/Service 网段不能冲突,否则跨集群路由不稳定
5.2 互通验证(双向)
# Cluster A 中访问 Cluster B 的 Pod IP(假设已互通)
kubectl -n demo run ping-test --rm -it --image=busybox:1.36 --restart=Never -- \
ping -c 3 <cluster-b-pod-ip>
# 解释:
# - 能 ping 通说明底层网络可达
6. 关键命令与效果说明#
# 查看跨集群导出/导入状态
kubectl get serviceexport -A
kubectl get serviceimport -A
# 查看 CoreDNS 配置是否包含 clusterset.local
kubectl -n kube-system get configmap coredns -o yaml
7. 常见故障排查#
1) 解析成功但访问失败
- 检查网段冲突、路由是否可达、NetworkPolicy/安全组限制。
# 网络连通性测试
kubectl -n demo run net-test --rm -it --image=alpine:3.19 --restart=Never -- \
sh -c "apk add --no-cache curl; curl -m 3 http://echo.demo.svc.clusterset.local"
2) 解析不到 clusterset.local
- 检查 CoreDNS 配置与 MCS 控制器状态。
kubectl -n kube-system logs deploy/coredns --tail=200
kubectl -n <mcs-namespace> logs deploy/mcs-controller --tail=200
3) 流量未按策略分配
- DNS TTL 过长或网关权重未刷新。
# 查看 DNS 记录 TTL
kubectl -n kube-system logs deploy/coredns | grep -i ttl
8. 练习(动手验证)#
1) 在 Cluster A 导出 demo/echo,在 Cluster B 解析并访问。
2) 修改 Cluster A 部署为 replicas=0,验证 Cluster B 访问失败并观察 DNS 缓存行为。
3) 将服务暴露到网关(Cluster A),在 Cluster B 通过网关域名访问并对比延迟。
4) 规划不同 Pod/Service CIDR(如 10.10.0.0/16 与 10.20.0.0/16),验证互通与冲突差异。
本节重点在于理解跨集群服务发现的模式与网络互通的核心原则,结合实际业务需求选择合适的实现路径,确保可靠性与可治理性。