应用跨集群通信¶
介绍¶
随着微服务进程发展,为了满足应用隔离、高可用/容灾以及运维管理的需求,许多企业选择部署多个 Kubernetes(K8s)集群。然而,这种多集群部署带来了一个问题:一些应用依赖于其他 K8s 集群中的 微服务,需要实现集群间的通信。具体而言,需要从一个集群的 Pod 去访问另外一个集群的 Pod 或者 Service。
前提条件¶
请确认操作系统 Kernel 版本号 >= v4.9.17,推荐 v5.10+。查看并安装升级最新的 Linux 内核版本,您可以按照如下命令进行操作:
-
查看当前内核版本:
-
安装 ELRepo 存储库,ELRepo 存储库中提供的最新 Linux 内核版本:
-
安装最新的 Linux 内核版本:
kernel-ml
是最新文档版内核,您可以根据需要选择其他版本。 -
更新 GRUB 配置,以便在启动时使用新内核版本:
创建集群¶
关于创建集群的更多信息,可参考创建集群
-
创建两个名称不同的集群分别为 cluster01 和 cluster02。
- 集群 cluster01 的网络插件选择 Cilium
- 添加两个参数
cluster-id
和cluster-name
- 其他均使用默认配置项
-
以同样的步骤创建集群 cluster02。
两个集群使用的容器网段和服务网段一定不能冲突。两个参数的值不能冲突,便于标识集群确保唯一性,避免跨集群通信时出现冲突。
为 API Server 创建 Service¶
-
集群创建成功后,在两个集群上分别创建一个 Service,用于将该集群的 API server 对外暴露。
- 集群 cluster01 访问类型选择 NodePort, 便于外部访问
- 命名空间选择 kube-system,即 API Server 所在命名空间
- 标签选择器筛选 API Server 组件,可返回查看 API Server 的选择器
- 配置 Service 的访问端口,容器端口为 6443
- 获取该 Service 的外部访问链接
-
再以同样方式在集群 cluster02 上为 API Server 创建 Service。
修改集群配置¶
通过 vi
命令开始编辑 集群 cluster01 和集群 cluster02 的 kubeconfig
文件:
-
在两个集群 cluster01 和 cluster02 里分别添加新的
cluster
、context
、user
信息。-
在
clusters
下面添加新的cluster
信息:两个集群原有的 CA 颁发机构不变;新的server
地址改为上述创建的 API Server Service 地址;name
改为两个集群本身的名称:cluster01 和 cluster02。API Server Service 的地址可以从 DCE5.0 的页面查看或复制,需要使用 https 协议。
-
在
contexts
下面添加新的context
信息:将context
中集群的name
、user
、cluster
三个字段的值均修改为两个集群本身的名称:cluster01 和 cluster02 。 -
在
users
下面添加新的user
信息:两个集群 cluster01 和 cluster02 分别复制本身原有的证书信息,将 name 改为两个集群本身的名称:cluster01 和 cluster02。
-
-
在对端集群中分别互相添加已经创建好的
cluster
、context
、user
信息。如下为操作过程中的 yaml 示例:
clusters: - cluster: #添加本集群 cluster01 `cluster`信息 certificate-authority-data: {{cluster01}} server: https://{{https://10.6.124.66:31936}} name: {{cluster01 }} - cluster: #添加对端集群 cluster02`cluster`信息 certificate-authority-data: {{cluster02}} server: https://{{https://10.6.124.67:31466}} name: {{cluster02}}
contexts: - context: #添加本集群 cluster01 `context` 信息 cluster: {{cluster01 name}} user: {{cluster01 name}} name: {{cluster01 name}} - context: #添加对端集群 cluster02 `context`信息 cluster: {{cluster02 name}} user: {{cluster02 name}} name: {{cluster02 name}} current-context: kubernetes-admin@cluster.local
users: - name: {{cluster01}} #添加本集群 cluster01 `user`信息 user: client-certificate-data: {{cluster01 certificate-data}} client-key-data: {{cluster01 key-data}} - name: {{cluster02}} #添加对端集群 cluster02 `user`信息 user: client-certificate-data: {{cluster02 certificate-data}} client-key-data: {{cluster02 key-data}}
配置集群连通性¶
执行如下命令验证集群的连通性:
-
在集群 cluster01 上输入:
-
集群 cluster02 开启
clustermesh
执行如下命令: -
在集群 cluster01 上建立连接:
-
集群 cluster01 出现
connected cluster1 and cluster2!
,集群 cluster02 出现ClusterMesh enabled!
说明两个集群通了。
创建演示应用¶
-
使用 Cilium 官方文档中提供的 rebel-base 应用,复制如下 yaml 文件:
apiVersion: apps/v1 kind: Deployment metadata: name: rebel-base spec: selector: matchLabels: name: rebel-base replicas: 2 template: metadata: labels: name: rebel-base spec: containers: - name: rebel-base image: docker.io/nginx:1.15.8 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ livenessProbe: httpGet: path: / port: 80 periodSeconds: 1 readinessProbe: httpGet: path: / port: 80 volumes: - name: html configMap: name: rebel-base-response items: - key: message path: index.html --- apiVersion: v1 kind: ConfigMap metadata: name: rebel-base-response data: message: "{\"Galaxy\": \"Alderaan\", \"Cluster\": \"Cluster-1\"}\n" #将 Cluster-1 修改为集群一的名称 --- apiVersion: apps/v1 kind: Deployment metadata: name: x-wing spec: selector: matchLabels: name: x-wing replicas: 2 template: metadata: labels: name: x-wing spec: containers: - name: x-wing-container image: quay.io/cilium/json-mock:v1.3.3@sha256:f26044a2b8085fcaa8146b6b8bb73556134d7ec3d5782c6a04a058c945924ca0 livenessProbe: exec: command: - curl - -sS - -o - /dev/null - localhost readinessProbe: exec: command: - curl - -sS - -o - /dev/null - localhost
-
在 DCE 5.0 中通过 yaml 文件快速分别创建两个集群 cluster01 和 cluster02 的应用。
分别修改
ConfigMap
的内容,使得访问集群 cluster01 和集群 cluster02 中的 Service 时,返回的数据分别带有 cluster01 和 cluster02 名称的标签。可在rebel-base
应用中查看容器组标签。 -
在两个集群 cluster01 和 cluster02 中分别创建一个 global service video 的 Service,指向的是已创建的
rebel-base
应用。- Service 类型为 ClusterIP
- 添加应用的容器组标签筛选对应的应用
- 配置端口
- 添加注解,使当前的 Service 在全局生效
在创建集群 cluster02 的 Service 时,两个集群的 service name 必须相同,并位于相同的命名空间,拥有相同的端口名称和相同的 global 注解。
跨集群通信¶
-
先查看集群 cluster02 中应用的 Pod IP。
-
进入集群 cluster01 详情,点击应用 rebel-base 的 容器组 -> 控制台 ,curl 集群 cluster02 应用 rebel-base 的 Pod IP,成功返回 cluster02 信息,说明两个集群中的 Pod 可以相互通信。
-
查看集群 cluster01 的 Service 名称,进入集群 cluster02 应用 rebel-base 的 容器组 -> 控制台 ,
curl
对应的 cluster01 的 Service 名称, 有些返回内容来自 cluster01,说明两个集群中的 Pod 和 Service 也可以互相通信。