rke集群手动创建kubeconfig

默认分类 · 2024-05-24

之前用rancher创建了几个rke集群,rancher提供的kubeconfig包含两个context,一个是通过rancher转发到apiserver的,一个是直连apiserver的,但是这两个context都用的是同一个user,这个user又藏在rancher的命名空间里面

现在需要把这个rke集群切换到另一个rancher上面管理,从旧rancher上面踢出集群后,集群上rancher的命名空间会被删掉,kubectl用的user也会跟着被删掉,导致kubectl无法连接到集群,只能回滚虚拟机

为了切换到新rancher,需要单独为kubectl创建一个新的user,在rke脱离rancher后仍然能控制集群

创建账号并授权

创建一个新的ServiceAccount
可以写yaml

apiVersion: v1
kind: ServiceAccount
metadata:
    name: kubectl-admin
    namespace: default

当然也可以直接一句话

kubectl create serviceaccount kubectl-admin

然后给这个SA授权,这里可以用Role和RoleBinding授权,限制这个账户仅可对特定的命名空间执行特定的操作,也可以用ClusterRole和ClusterRoleBinding来授予跨命名空间的权限,具体参考k8s的RBAC文档

因为这里创建的kubectl-admin账户是给kubectl用来控制集群的,所以使用ClusterRoleBinding来授予权限

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
    name: kubectl-admin-binding
subjects:
    - kind: ServiceAccount
      name: kubectl-admin
      namespace: default
roleRef:
    kind: ClusterRole
    name: cluster-admin
    apiGroup: rbac.authorization.k8s.io

roleRef引用的ClusterRole是cluster-admin,这是k8s内置的一个集群角色,拥有集群的所有权限,用这个就不需要自己配ClusterRole了

接下来获取ServiceAccount的Token

[root@master-01 ~]# kubectl describe serviceaccounts kubectl-admin 
Name:                kubectl-admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   kubectl-admin-token-t56kr
Tokens:              kubectl-admin-token-t56kr
Events:              <none>

可以看到Token的名称是kubectl-admin-token-t56kr

[root@master-01 ~]# kubectl describe secrets kubectl-admin-token-t56kr 
Name:         kubectl-admin-token-t56kr
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: kubectl-admin
              kubernetes.io/service-account.uid: 1c477ddc-281f-41f3-b6a7-539056c34a0a

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1058 bytes
namespace:  7 bytes
token:      eyJhbGciO.....X6gPw

eyJhbGciO.....X6gPw这一长串复制下来,这就是ServiceAccount的Token

创建kubeconfig文件

先看看rancher提供的kubeconfig是啥样子的

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUd......tLQ==
    server: https://rce.test.cn/k8s/clusters/c-8pffj
  name: test
- cluster:
    certificate-authority-data: LS0tLS1CRU......LQo=
    server: https://192.168.0.11:6443
  name: test-master-01
users:
- name: test
  user:
    token: kubeconfig-user-5782d.c-8pffj:lls.....m42bt
contexts:
- context:
    cluster: test
    user: test
  name: test
- context:
    cluster: test-master-01
    user: test
  name: test-master-01
current-context: test-master-01

可以看到配置文件主要分成三块:

  • clusters:指定kubectl要连接的集群的信息,rancher为文件生成了两个信息,一个是通过rancher的代理,一个是直连集群的ip地址,除了地址以外还带了个证书
  • users:指定kubectl与集群通信所使用的用户身份,rancher只提供了一个用户,这里就要用到上面创建的新的ServiceAccount了
  • contexts:指定kubectl连接上下文,某个上下文的名称是什么,连接的集群是哪个,使用的用户身份是哪一个,切换上下文可以用kubectl config use-context命令

users和context已经有了,就差一个cluster的证书了,这个证书在rke集群下可以在master节点的/etc/kubernetes/ssl/目录下找到,名字是kube-ca.pem

可以用下面的命令取出来,以base64编码的方式粘贴到kubeconfig里面

cat /etc/kubernetes/ssl/kube-ca.pem | base64

最终的kubeconfig文件内容如下

apiVersion: v1
kind: Config
clusters:
- cluster:
  name: local
    certificate-authority-data: LS0tLS1CRU.......LS0tLQo= # 这里粘kube-ca.pem经过base64编码后的内容
    server: https://192.168.70.11:6443
contexts:
- context:
    cluster: local
    user: kubectl-admin
  name: local
users:
- name: kubectl-admin # 这个名字无所谓,不对应SA,下面的Token对就行
  user:
    token: eyJhbGc....9omOX6gPw # 这里粘ServiceAccount的Token

切换一下kubectl的上下文

kubectl config use-context local

尝试获取node信息

[root@master-01 ~]# kubectl get nodes
NAME             STATUS   ROLES               AGE    VERSION
test-master-01   Ready    controlplane,etcd   206d   v1.20.15
test-worker-01   Ready    worker              247d   v1.20.15
test-worker-02   Ready    worker              246d   v1.20.15

可以看到kubectl已经可以正常和apiserver通信

Theme Jasmine by Kent Liao