远程连接K8S集群

1 背景

我们搭建好K8S集群后,默认都是从master节点上连接到集群,执行命令。但是有时候我们需要在其他机器连接k8s集群,这就需要我们的kubectl命令能够和集群的apiserver通讯,由于是通过https通讯,因此需要生成对应的证书文件。

2 最简方式

由于我们的集群是通过kubeadm部署,因此部署后会自动生成一个用于admin用户连接集群的配置文件——/etc/kubernetes/admin.conf,

[root@master ~]# cat /etc/kubernetes/admin.conf 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: ****
    server: https://192.168.0.110:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: ****
    client-key-data: ****

所以最简单的方式就是将该文件拷贝到对应的机器上,这样就能直接连接到k8s集群,比如我们把这个登录凭证拷贝node1上,

[root@node1 ~]# kubectl get node --kubeconfig=./admin.conf
NAME     STATUS   ROLES                  AGE    VERSION
master   Ready    control-plane,master   256d   v1.21.2
node1    Ready    <none>                 256d   v1.21.2
node2    Ready    <none>                 256d   v1.21.2

可见连接成功,命令正常返回。

3 证书方式

如果我们没有admin.conf文件,或者文件丢失,那我们就可以自己生成证书,然后将生成的证书拷贝到目标机器,一样可以实现远程连接。

3.1 安装cfssl工具

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

3.2 生成ca配置

证书有效时间为10年

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

3.3 生成admin证书请求配置

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

3.4 生成admin证书

进入集群证书目录,/etc/kubernetes/pki

[root@master pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
2022/03/27 07:12:43 [INFO] generate received request
2022/03/27 07:12:43 [INFO] received CSR
2022/03/27 07:12:43 [INFO] generating key: rsa-2048
2022/03/27 07:12:44 [INFO] encoded CSR
2022/03/27 07:12:44 [INFO] signed certificate with serial number 479626741822853067875971057191146068697711629773
2022/03/27 07:12:44 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@master pki]# ls admin*
admin.csr  admin-csr.json  admin-key.pem  admin.pem

因为我的集群是kubeadm部署的,因此已经有ca证书对,就不需要重新生成,直接使用就好。

4 配置远端目标机器

将生成的admin证书对,以及集群的ca证书拷贝到目标远端机器,

scp admin-key.pem admin.pem ca.crt node2:/root

然后登录远端机器,开始配置kubeconfig。

4.1 添加集群

将我们的集群添加到目标机器中,并设置使用证书文件授权,这里要注意证书文件的名字和路径,

kubectl config set-cluster kubernetes \
  --server=https://master:6443 \
  --embed-certs=true \
  --certificate-authority=/root/ca.crt

4.2 设置客户端连接集群的认证参数

其中k8sadmin就是我们指定的用户名

kubectl config set-credentials k8sadmin \
  --embed-certs=true \
  --certificate-authority=/root/ca.crt\
  --client-key=/root/admin-key.pem \
  --client-certificate=/root/admin.pem

4.3 设置上下文

将用户和集群关联

kubectl config set-context default \
  --cluster=kubernetes \
  --user=k8sadmin

4.4 切换上下文

将集群切到我们需要连接的集群

kubectl config use-context default

此时,/root/.kube/config就会生成和admin.conf类似的认证文件,我们就能连接到目标集群。

4.5 测试连接

[root@node2 ~]# kubectl get node
NAME     STATUS   ROLES                  AGE    VERSION
master   Ready    control-plane,master   256d   v1.21.2
node1    Ready    <none>                 256d   v1.21.2
node2    Ready    <none>                 256d   v1.21.2

5 最安全的方式

不管是拷贝admin.conf文件还是生成admin证书对都有个问题,权限过大,因为kubeadm和我们创建admin证书时,我们用的是以下配置,

"O": "system:masters",

system:masters是一个例外的,超级用户组,可以绕过鉴权层,比如RBAC,这是比较危险的。

所以,如果我们需要给某个用户集群权限,就需要能够限制他的权限范围。

将签名请求文件中的用户组设置为其他组,比如dev

cat > dev-csr.json <<EOF
{
  "CN": "test",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "dev",
      "OU": "System"
    }
  ]
}
EOF

然后同样生成dev的证书对,并拷贝至目标机器,

[root@master pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes dev-csr.json | cfssljson -bare dev
[root@master pki]# scp dev-key.pem dev.pem node2:/root

cluster我们上面已经设置过,就不需要重复设置,我们只要设置新的连接凭证和上下文就可以了,

[root@node2 ~]# kubectl config set-credentials test \
>   --certificate-authority=/root/ca.crt\
>   --client-key=/root/dev-key.pem \
>   --client-certificate=/root/dev.pem
[root@node2 ~]# kubectl config set-context test \
>   --cluster=kubernetes \
>   --user=test
[root@node2 ~]# kubectl config use-context test

这时候我们尝试连接集群,

[root@node2 ~]# kubectl get node
Error from server (Forbidden): nodes is forbidden: User "test" cannot list resource "nodes" in API group "" at the cluster scope

不出意外,出现意外了,因为我们还没给这个用户授予权限。

这时RBAC就需要登场了。假设我们只允许这个用户访问nginx这个namespace,我们在master节点上授予test用户nginx这个namespace的admin权限。

[root@master ~]# kubectl create rolebinding test-admin-binding --clusterrole=admin --user=test --namespace=nginx

这时我们再测试下,可见,这时test用户在nginx namespace里可以为所欲为,

[root@node2 ~]# kubectl get pod -n nginx
NAME      READY   STATUS    RESTARTS   AGE
centos7   1/1     Running   1          30s
[root@node2 ~]# kubectl delete pod centos7 -n nginx
pod "centos7" deleted

但是在其他namespace就没办法了。

[root@node2 ~]# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "kube-system"

参考文档:

  1. https://kubernetes.io/docs/reference/access-authn-authz/rbac/
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值