通过原生 Service 跨集群访问服务

在 Karmada 中,MultiClusterService 可以让用户通过原生 Service 域名(例如 foo.svc)跨集群访问服务,目的是让用户获得如在单个集群中访问服务般访问跨集群服务的流畅体验。

本文档提供了这样一个案例:启用 MultiClusterService 来通过原生 Service 跨集群访问服务。

前提条件

Karmada 已安装

您可以参考快速入门安装 Karmada,或直接运行 hack/local-up-karmada.sh 脚本,该脚本也用于运行 E2E 测试。

成员集群网络

确保至少已有两个集群加入 Karmada,并且成员集群之间的容器网络已连通。

  • 如果您使用 hack/local-up-karmada.sh 脚本部署 Karmada,Karmada 中会有 3 个成员集群,并且集群 member1member2 间的容器网络已连通。
  • 您可以使用 Submariner 或其他相关开源项目来连接成员集群之间的网络。

通过原生 Service 跨集群访问服务 - 图1注意

为了防止路由冲突,集群中 Pod 和 Service 的 CIDR 必须互不重叠。

在 karmada-controller-manager 中启用 MultiClusterService

要在 karmada-controller-manager 中启用 MultiClusterService 功能,请运行以下命令:

  1. kubectl --context karmada-host get deploy karmada-controller-manager -n karmada-system -o yaml | sed '/- --v=4/i \ - --feature-gates=MultiClusterService=true' | kubectl --context karmada-host replace -f -

请注意,MultiClusterService 功能默认是禁用的,可以通过 --feature-gates=MultiClusterService=true 参数开启。

如果您倾向于更谨慎的方法,请按照以下步骤操作:

  1. 运行 kubectl --context karmada-host edit deploy karmada-controller-manager -n karmada-system
  2. 检查 spec.template.spec.containers[0].command 字段中是否存在 --feature-gates=MultiClusterService=true
  3. 如果没有,添加 --feature-gates=MultiClusterService=true 来开启功能。

member1 集群中部署 Deployment

我们需要在 member1 集群中部署 Deployment:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx
  5. labels:
  6. app: nginx
  7. spec:
  8. replicas: 2
  9. selector:
  10. matchLabels:
  11. app: nginx
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx
  16. spec:
  17. containers:
  18. - image: nginx
  19. name: nginx
  20. resources:
  21. requests:
  22. cpu: 25m
  23. memory: 64Mi
  24. limits:
  25. cpu: 25m
  26. memory: 64Mi
  27. ---
  28. apiVersion: policy.karmada.io/v1alpha1
  29. kind: PropagationPolicy
  30. metadata:
  31. name: nginx-propagation
  32. spec:
  33. resourceSelectors:
  34. - apiVersion: apps/v1
  35. kind: Deployment
  36. name: nginx
  37. placement:
  38. clusterAffinity:
  39. clusterNames:
  40. - member1

部署完成后,您可以检查创建的 Pod:

  1. $ karmadactl get po
  2. NAME CLUSTER READY STATUS RESTARTS AGE
  3. nginx-5c54b4855f-6sq9s member1 1/1 Running 0 28s
  4. nginx-5c54b4855f-vp948 member1 1/1 Running 0 28s

member2 集群中部署 curl Pod

让我们在 member2 集群中部署一个 curl Pod:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: curl
  5. labels:
  6. app: curl
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. app: curl
  12. template:
  13. metadata:
  14. labels:
  15. app: curl
  16. spec:
  17. containers:
  18. - image: curlimages/curl:latest
  19. command: ["sleep", "infinity"]
  20. name: curl
  21. resources:
  22. requests:
  23. cpu: 25m
  24. memory: 64Mi
  25. limits:
  26. cpu: 25m
  27. memory: 64Mi
  28. ---
  29. apiVersion: policy.karmada.io/v1alpha1
  30. kind: PropagationPolicy
  31. metadata:
  32. name: curl-propagation
  33. spec:
  34. resourceSelectors:
  35. - apiVersion: apps/v1
  36. kind: Deployment
  37. name: curl
  38. placement:
  39. clusterAffinity:
  40. clusterNames:
  41. - member2

部署完成后,您可以检查创建的 Pod:

  1. $ karmadactl get po -C member2
  2. NAME CLUSTER READY STATUS RESTARTS AGE
  3. curl-6894f46595-c75rc member2 1/1 Running 0 15s

稍后,我们将在此 Pod 中执行 curl 命令。

在 Karmada 中部署 MultiClusterService 与 Service

现在,我们不使用 PropagationPolicy/ClusterPropagationPolicy,而是利用 MultiClusterService 来分发 Service。

要在 Karmada 中启用 MultiClusterService,请部署以下 yaml:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: nginx
  5. spec:
  6. ports:
  7. - port: 80
  8. targetPort: 80
  9. selector:
  10. app: nginx
  11. ---
  12. apiVersion: networking.karmada.io/v1alpha1
  13. kind: MultiClusterService
  14. metadata:
  15. name: nginx
  16. spec:
  17. types:
  18. - CrossCluster
  19. consumerClusters:
  20. - name: member2
  21. providerClusters:
  22. - name: member1

member2 集群访问后端 Pod

要从 member2 集群访问 member1 集群中的后端 Pod,请执行以下命令:

  1. $ karmadactl exec -C member2 curl-6894f46595-c75rc -it -- sh
  2. ~ $ curl http://nginx.default
  3. Hello, world!
  4. Version: 1.0.0
  5. Hostname: nginx-0

在此案例中,Pod 仅位于 member1 集群。但是,使用 MultiClusterService,就可以通过原生 Service 域名从 member2 集群实现跨集群访问。