通过命令行管理多集群服务实现Kubernetes服务的跨集群访问

通过多集群服务,让您无需创建负载均衡,即可实现Kubernetes服务的跨集群访问。本文通过示例介绍如何在Fleet实例上创建ServiceExport、ServiceImport等资源来管理多集群服务,实现Kubernetes服务的跨集群访问。

前提条件

概述

通过多集群服务实现Kubernetes服务的跨集群访问,打破了多集群服务访问的边界。多集群服务示例如下图所示。

多集群服务

  1. 管理员在服务提供者集群(ACK Cluster 1)和服务消费者集群(ACK Cluster 2)中,创建应用相关资源,包含Namespace、Deployment和Service;创建多集群Service资源,包括ServiceExport和ServiceImport。

  2. 多集群舰队Fleet监听子集群的ServiceExport和ServiceImport资源,同步多集群Service对应的Endpoint信息。

  3. 在服务消费者集群ACK Cluster 2上,Client Pod可跨集群访问服务提供者集群ACK Cluster 1上的Service1。

步骤一:创建服务提供者相关资源

如果您的服务提供者集群ACK Cluster 1已经部署了Kubernetes服务和相关资源,可以跳过此步骤。

  1. 在服务提供者集群ACK Cluster 1上,执行以下命令,创建服务提供者命名空间。

    示例的命名空间为provider-ns

    kubectl create ns provider-ns
  2. 在服务提供者集群ACK Cluster 1上,创建服务提供者Kubernetes服务和相关的Deployment等资源。

    1. 使用以下内容,创建一个app-meta.yaml文件。

      apiVersion: v1       # 服务提供者。
      kind: Service
      metadata:
        name: service1
        namespace: provider-ns
      spec:
        ports:
        - name: http
          port: 80
          protocol: TCP
          targetPort: 8080
        selector:
          app: web-demo
        sessionAffinity: None
        type: ClusterIP
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          app: web-demo
        name: web-demo
        namespace: provider-ns
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: web-demo
        template:
          metadata:
            labels:
              app: web-demo
          spec:
            containers:
            - image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/web-demo:0.4.0
              name: web-demo
              env:
              - name: ENV_NAME
                value: cluster1-beijing
    2. 执行以下命令,在服务提供者集群ACK Cluster 1中创建资源。

      kubectl apply -f app-meta.yaml
    3. 执行以下命令,在服务提供者集群ACK Cluster 1中创建ServiceExport资源,指定需要开放多集群访问的Kubernetes服务。

      apiVersion: multicluster.x-k8s.io/v1alpha1
      kind: ServiceExport
      metadata:
        name: service1           # 名称与待开放的Kubernetes服务名称相同。
        namespace: provider-ns   # 与待开放的Kubernetes服务在同一个命名空间。

      具体参数说明如下:

      参数

      说明

      metadata.name

      待开放的Kubernetes服务名称。

      metadata.namespace

      待开放的Kubernetes服务所在的命名空间。

步骤二:配置消费者集群

  1. 在服务消费者集群ACK Cluster 2上,执行以下命令,创建服务提供者命名空间。

    示例的命名空间为provider-ns

    kubectl create ns provider-ns
  2. 在服务消费者集群ACK Cluster 2中,使用以下内容,创建ServiceImport资源。

    apiVersion: multicluster.x-k8s.io/v1alpha1
    kind: ServiceImport
    metadata:
      name: service1           
      namespace: provider-ns   
    spec:
      ports:                   # 与待开放的Kubernetes服务ports相同。
      - name: http
        port: 80
        protocol: TCP
      type: ClusterSetIP

    以上示例代码中ServiceImport的spec字段仅定义了部分参数。关于spec完整的参数说明如下表所示。

    参数

    说明

    metadata.name 

    服务名称,需要与待开放的Kubernetes服务名称相同。

    metadata.namespace

    服务命名空间。需要与待开放的Kubernetes服务命名空间一致。

    spec. ports. name

    Port名称。需要与待开放的Kubernetes服务相应字段一致。

    spec. ports. protocol

    协议。需要与待开放的Kubernetes服务相应字段一致。

    spec. ports. appProtocol

    应用协议。需要与待开放的Kubernetes服务相应字段一致。

    spec. ports. port

    Port。需要与待开放的Kubernetes服务相应字段一致。

    spec. ips

    服务VIP。由Fleet实例分配,无需填写。

    spec. type

    支持ClusterSetIPHeadless

    当待开放的Kubernetes服务的ClusterIPNone时,表示服务为Headless服务,设置typeHeadless

    否则,设置typeClusterSetIP

    spec. sessionAffinity

    会话关联,支持ClientIPNone。需要与待开放的Kubernetes服务相应字段一致。

    spec. sessionAffinityConfig

    会话关联配置。需要与待开放的Kubernetes服务相应字段一致。

步骤三:访问多集群服务

在服务消费者集群Cluster 2中的Client Pod可以通过以下两种方式访问服务提供者集群ACK Cluster 1中的Service 1。

方式一:通过新的Service名称访问

服务消费者集群ACK Cluster 2创建ServiceImport后,Fleet实例会在服务消费者集群ACK Cluster 2中,创建一个以amcs-为前缀的Kubernetes服务代表多集群Service。

在服务消费者集群ACK Cluster 2的Client Pod中,可以通过访问amcs-service1.provider-ns来访问服务提供者集群ACK Cluster 1中的Service 1。

  1. 在服务消费者集群ACK Cluster 2上执行以下命令,获取相关Service信息。

    kubectl get service -n provider-ns

    预期输出:

    NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
    amcs-service1   ClusterIP   172.xx.xx.xx   <none>        80/TCP    26m
  2. 在服务消费者集群ACK Cluster 2的Client Pod上执行以下命令,访问服务提供者集群ACK Cluster 1中的Service 1。

    curl amcs-service1.provider-ns

方式二:通过新的Service域名访问

  1. 在服务消费者集群Cluster 2中安装或升级CoreDNS,版本要求1.9.3及以上。具体操作,请参见CoreDNS管理组件

  2. 修改CoreDNS组件的配置Corefile。

    1. 执行如下命令,修改CoreDNS组件的ConfigMap文件。

      kubectl edit configmap coredns -n kube-system
    2. 在Corefile文件中新增一行配置项multicluster clusterset.local,支持多集群服务域名解析。

      apiVersion: v1
      data:
        Corefile: |
          .:53 {
              errors
              health {
                 lameduck 15s
              }
              ready
              multicluster clusterset.local    #增加配置项,支持多集群服务域名解析。
              kubernetes cluster.local in-addr.arpa ip6.arpa {
      
                pods verified
                ttl 30
                fallthrough in-addr.arpa ip6.arpa
              }
              ...
          }
      kind: ConfigMap
      metadata:
        name: coredns
        namespace: kube-system
                                      
  3. 在服务消费者集群Cluster 2的Client Pod上执行如下命令,访问服务提供者集群Cluster 1中的Service 1。

    curl service1.provider-ns.svc.clusterset.local
  4. (可选)通过修改服务消费者集群Cluster 2中Client Pod的dnsConfig.searches,访问多集群服务。

    1. 在Client Pod的dnsConfig.searches字段中增加搜索clusterset.local的域名。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: client-pod
        namespace: consumer-ns
      spec:
        ...
        template:
          ...
          spec:
            dnsPolicy: "ClusterFirst"    
            dnsConfig:                   
              searches:                        #dnsConfig,增加搜索clusterset.local域名。
                - svc.clusterset.local
                - clusterset.local
                - consumer-ns.svc.cluster.local
                - svc.cluster.local
                - cluster.local
            containers:
            - name: client-pod
              ...
    2. 执行如下命令,访问多集群服务。

      curl service1.provider-ns

相关文档

除了命令行方式,您也可以通过控制台方式管理多集群服务。具体操作,请参见通过控制台管理多集群服务