通过kubectl对接多个集群
应用现状
kubectl命令行工具使用kubeconfig配置文件来查找选择集群所需的认证信息,并与集群的API服务器进行通信。默认情况下,kubectl会使用“$HOME/.kube/config”文件作为访问集群的凭证。
在CCE集群的日常使用过程中,我们通常需要同时管理多个集群,因此在使用kubectl命令行工具连接集群时需要经常切换kubeconfig配置文件,为日常运维带来许多不便。本文将为您介绍如何便捷地使用同一个kubectl客户端连接多个集群。
用于配置集群访问的文件称为kubeconfig配置文件,并不意味着文件名称为kubeconfig。
解决方案
在K8s集群的运维中,多集群之间的切换是无法避免的问题,常见的集群切换方案如下:
- 方案一:您可以通过指定kubectl的“--kubeconfig”参数来选择每个集群所使用的kubeconfig配置文件,并可使用alias别名的方式来简化命令。
- 方案二:将多个kubeconfig文件中的集群、用户和凭证合并成一个配置文件,并使用“kubectl config use-context”命令进行集群切换。
该方案与方案一相比,需要手动配置kubeconfig文件,相对来说较为复杂。
前提条件
- 您需要在一台Linux虚拟机上安装kubectl命令行工具,kubectl的版本应该与集群版本相匹配,详情请参见安装kubectl。
- 安装kubectl的虚拟机需要可以访问每个集群的网络环境。
kubeconfig文件结构解析
kubeconfig是kubectl的配置文件,您可以在集群详情页面下载。
kubeconfig文件内容如下所示。
{ "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文件可以看出,此处将集群的内网地址和公网访问地址分别定义成一个集群,且定义了两个上下文,从而能够通过切换上下文选择使用不同的地址访问集群。
方案一:在命令中指定不同的kubeconfig配置文件
- 登录安装kubectl的虚拟机。
- 分别下载2个集群的kubeconfig文件到kubectl客户端机器的“/home”目录下,本文中使用以下名称作为示例。
集群名称
kubeconfig配置文件名称
集群A
kubeconfig-a.json
集群B
kubeconfig-b.json
- 假设以集群A作为kubectl的默认连接集群,将kubeconfig-a.json文件移动至“$HOME/.kube/config”。
cd /home mkdir -p $HOME/.kube mv -f kubeconfig-a.json $HOME/.kube/config
- 将集群B对应的kubeconfig-b.json文件移动至“$HOME/.kube/config-test”。
mv -f kubeconfig-b.json $HOME/.kube/config-test
其中config-test文件名称可以自定义。
- 由于集群A为kubectl的默认连接集群,使用kubectl命令时无需添加“--kubeconfig”参数。而在使用kubectl连接集群B时,需要添加“--kubeconfig”参数用于指定kubectl命令所使用的凭证。例如查看集群B的节点命令如下:
kubectl --kubeconfig=$HOME/.kube/config-test get node
上述使用方式命令较长,频繁使用的情况下带来诸多不便,您可使用alias别名的方式简化命令,例如:alias ka='kubectl --kubeconfig=$HOME/.kube/config' alias kb='kubectl --kubeconfig=$HOME/.kube/config-test'
其中ka、kb可根据喜好自定义。使用kubectl命令时,可直接输入ka或kb来代替kubectl,并自动添加“--kubeconfig”参数。例如上述查看集群B的节点命令可简化为:
kb get node
方案二:将两个集群的kubeconfig文件合并
下面以配置2个集群为例演示如何修改kubeconfig文件访问多个集群。
为简洁文档篇幅,如下示例选取公网访问的方式,删除内网访问方式。如果您需要在内网访问多集群,只需要保留内网访问的集群clusters字段,保证能够从内网访问到集群即可,其方法与下面内容并无本质区别。
- 分别下载2个集群的kubeconfig文件,删除内网访问内容,如下所示。
- 集群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字段内容不同,文件结构完全一致。
- 集群A:
- 修改两个配置文件中的名称,如下所示。
- 集群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" }
- 集群A:
- 将两个文件的内容合并。
文件结构不变,将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文件后,执行如下命令将文件复制到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'.
上述使用方式命令较长,频繁切换的情况下带来诸多不便,您也可以使用alias别名的方式简化命令,如下:
alias ka='kubectl config use-context Cluster-A-Context;kubectl' alias kb='kubectl config use-context Cluster-B-Context;kubectl'
其中ka、kb可根据喜好自定义。使用kubectl命令时,可直接输入ka或kb来代替kubectl,在使用时会先切换context,再执行kubectl命令。例如:
# ka cluster-info Switched to context "Cluster-A-Context". 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'.