更新时间:2024-12-04 GMT+08:00

通过kubectl对接多个集群

应用现状

在使用CCE时,通常会创建多个集群,如何方便快速的连接多个集群,成为一个问题。

解决方案

本文介绍一种通过修改kubeconfig.json配置文件配置多集群访问的方法,在kubeconfig.json中定义多个上下文、用户和集群。在使用时则只需要使用kubectl config use-context切换上下文连接到不同的集群。

图1 kubectl对接多集群示意

前提条件

kubectl需要能够访问多个集群。

kubeconfig.json文件详解

kubeconfig.json是kubectl的配置文件,您可以在集群详情页面下载。

kubeconfig.json文件内容如下所示。

{
    "kind": "Config",
    "apiVersion": "v1",
    "preferences": {},
    "clusters": [{
        "name": "internalCluster",
        "cluster": {
            "server": "https://192.168.0.85:5443",
            "certificate-authority-data": "LS0tLS1CRUULIE..."
        }
    }, {
        "name": "externalCluster",
        "cluster": {
            "server": "https://xxx.xxx.xxx.xxx:5443",
            "insecure-skip-tls-verify": true
        }
    }],
    "users": [{
        "name": "user",
        "user": {
            "client-certificate-data": "LS0tLS1CRUdJTiBDRVJ...",
            "client-key-data": "LS0tLS1CRUdJTiBS..."
        }
    }],
    "contexts": [{
        "name": "internal",
        "context": {
            "cluster": "internalCluster",
            "user": "user"
        }
    }, {
        "name": "external",
        "context": {
            "cluster": "externalCluster",
            "user": "user"
        }
    }],
    "current-context": "external"
}

其中主要分为3部分内容。

  • clusters:描述集群的信息,主要是集群的访问地址。
  • users:描述访问集群访问用户的信息,主要是client-certificate-data和client-key-data这两个证书文件内容。
  • contexts:描述配置的上下文,用于使用时切换。上下文会关联user和cluster,也就是定义使用哪个user去访问哪个集群。

从上面的kubeconfig.json文件可以看出,此处将集群的内网地址和公网访问地址分别定义成一个集群,且定义了两个上下文,从而能够通过切换上下文选择使用不同的地址访问集群。

配置多集群访问

下面以配置2个集群为例演示如何修改kubeconfig.json文件访问多个集群。

为简洁文档篇幅,如下示例选取公网访问的方式,删除内网访问方式。如果您需要在内网访问多集群,只需要保留内网访问的集群clusters字段,保证能够从内网访问到集群即可,其方法与下面内容并无本质区别。

  1. 分别下载2个集群的kubeconfig.json文件,删除内网访问内容,如下所示。

    • 集群A:
      {
          "kind": "Config",
          "apiVersion": "v1",
          "preferences": {},
          "clusters": [ {
              "name": "externalCluster",
              "cluster": {
                  "server": "https://119.xxx.xxx.xxx:5443",
                  "insecure-skip-tls-verify": true
              }
          }],
          "users": [{
              "name": "user",
              "user": {
                  "client-certificate-data": "LS0tLS1CRUdJTxM...",
                  "client-key-data": "LS0tLS1CRUdJTiB...."
              }
          }],
          "contexts": [{
              "name": "external",
              "context": {
                  "cluster": "externalCluster",
                  "user": "user"
              }
          }],
          "current-context": "external"
      }
    • 集群B:
      {
          "kind": "Config",
          "apiVersion": "v1",
          "preferences": {},
          "clusters": [ {
              "name": "externalCluster",
              "cluster": {
                  "server": "https://124.xxx.xxx.xxx:5443",
                  "insecure-skip-tls-verify": true
              }
          }],
          "users": [{
              "name": "user",
              "user": {
                  "client-certificate-data": "LS0tLS1CRUdJTxM...",
                  "client-key-data": "LS0rTUideUdJTiB...."
              }
          }],
          "contexts": [{
              "name": "external",
              "context": {
                  "cluster": "externalCluster",
                  "user": "user"
              }
          }],
          "current-context": "external"
      }

      此时这两个文件除了集群访问地址clusters.cluster.server和user字段的client-certificate-data和client-key-data字段内容不同,文件结构完全一致。

  2. 修改两个配置文件中的名称,如下所示。

    • 集群A:
      {
          "kind": "Config",
          "apiVersion": "v1",
          "preferences": {},
          "clusters": [ {
              "name": "Cluster-A",
              "cluster": {
                  "server": "https://119.xxx.xxx.xxx:5443",
                  "insecure-skip-tls-verify": true
              }
          }],
          "users": [{
              "name": "Cluster-A-user",
              "user": {
                  "client-certificate-data": "LS0tLS1CRUdJTxM...",
                  "client-key-data": "LS0tLS1CRUdJTiB...."
              }
          }],
          "contexts": [{
              "name": "Cluster-A-Context",
              "context": {
                  "cluster": "Cluster-A",
                  "user": "Cluster-A-user"
              }
          }],
          "current-context": "Cluster-A-Context"
      }
    • 集群B:
      {
          "kind": "Config",
          "apiVersion": "v1",
          "preferences": {},
          "clusters": [ {
              "name": "Cluster-B",
              "cluster": {
                  "server": "https://124.xxx.xxx.xxx:5443",
                  "insecure-skip-tls-verify": true
              }
          }],
          "users": [{
              "name": "Cluster-B-user",
              "user": {
                  "client-certificate-data": "LS0tLS1CRUdJTxM...",
                  "client-key-data": "LS0rTUideUdJTiB...."
              }
          }],
          "contexts": [{
              "name": "Cluster-B-Context",
              "context": {
                  "cluster": "Cluster-B",
                  "user": "Cluster-B-user"
              }
          }],
          "current-context": "Cluster-B-Context"
      }

  3. 将两个文件的内容合并。

    文件结构不变,将clusters、users和contexts的内容合并即可,如下所示。

    {
        "kind": "Config",
        "apiVersion": "v1",
        "preferences": {},
        "clusters": [ {
            "name": "Cluster-A",
            "cluster": {
                "server": "https://119.xxx.xxx.xxx:5443",
                "insecure-skip-tls-verify": true
            }
        },
         {
            "name": "Cluster-B",
            "cluster": {
                "server": "https://124.xxx.xxx.xxx:5443",
                "insecure-skip-tls-verify": true
            }
        }],
        "users": [{
            "name": "Cluster-A-user",
            "user": {
                "client-certificate-data": "LS0tLS1CRUdJTxM...",
                "client-key-data": "LS0tLS1CRUdJTiB...."
            }
        },
        {
            "name": "Cluster-B-user",
            "user": {
                "client-certificate-data": "LS0tLS1CRUdJTxM...",
                "client-key-data": "LS0rTUideUdJTiB...."
            }
        }],
        "contexts": [{
            "name": "Cluster-A-Context",
            "context": {
                "cluster": "Cluster-A",
                "user": "Cluster-A-user"
            }
        },
        {
            "name": "Cluster-B-Context",
            "context": {
                "cluster": "Cluster-B",
                "user": "Cluster-B-user"
            }
        }],
        "current-context": "Cluster-A-Context"
    }

配置验证

将两个文件内容合并到一个kubeconfig.json后,执行如下命令将文件复制到kubectl配置路径下。

mkdir -p $HOME/.kube

mv -f kubeconfig.json $HOME/.kube/config

执行kubectl命令是否能够连接两个集群。

# kubectl config use-context Cluster-A-Context
Switched to context "Cluster-A-Context".
# kubectl cluster-info
Kubernetes control plane is running at https://119.xxx.xxx.xxx:5443
CoreDNS is running at https://119.xxx.xxx.xxx:5443/api/v1/namespaces/kube-system/services/coredns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# kubectl config use-context Cluster-B-Context
Switched to context "Cluster-B-Context".
# kubectl cluster-info
Kubernetes control plane is running at https://124.xxx.xxx.xxx:5443
CoreDNS is running at https://124.xxx.xxx.xxx:5443/api/v1/namespaces/kube-system/services/coredns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.