彻底搞定kubernetes远程访问

2022年7月5日13:13:53

kubectl方式远程访问集群

kubectl是kubernetes自带的命令行客户端,安装kubernete集群之后,可以使用kubectl相关的命令访问kubernetes集群资源。kubectl可以独立在本地安装,来访问远程的kubernetes集群资源。
配置方式:将远程kubernetes集群~.kube/config文件 拷贝到本地并替换,即可通过kubectl访问远程kubernetes集群

使用kubectl proxy代理方式

执行如下命令

$ kubectl proxy --port=8080&
  • 注意这里不仅仅只是可以在kubernetes集群的节点上执行才能达到访问目的,如果已经通过上面提到的方式在本地通过kubectl已经连接到远程集群,那么在本地执行此以下命令也是可以的。此时映射的端口是在执行命令的本地机器上
  • 该命令执行后通过curl访问kubernetes接口具有较高的权限,包括查看、删除等

不使用 kubectl 代理

$ APISERVER=$(kubectl config view|grep server|cut -f 2- -d":"|tr -d" ")#下面这地方可能会有坑,获取到的token尽量检查一下前面是否有空格,如果有空格,后面即使赋权之后也会报权限错误,注意删除空格
$ TOKEN=$(kubectl describe secret$(kubectl get secrets|grep default|cut -f1 -d' ')|grep -E'^token'|cut -f2 -d':'|tr -d'\t')
$curl$APISERVER/api/v1/namespaces/default/pods  --header"Authorization: Bearer$TOKEN" --insecure{"kind":"APIVersions","versions":["v1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"10.0.1.149:443"}]}

通过这种方式访问kubernetes集群会经过认证、授权、准入控制等环节,所以需要在请求发送时提供证书、token或者账号密码信息。以上示例是提供了TOKEN方式进行了身份认证,其他方式详见身份认证

  • 如果认证失败,会出现以下返,需要确认一下提供的token 或者证书等身份信息是否正确。
{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code": 401}
  • 更常见的我们会遇到类似如下返回
{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"","reason":"Forbidden","details":{"kind":"pods"},"code": 403}

通过提示信息我们看到没有我们可以通过以下命令来查看,结果发现并没有system:anonymous 这个用户,其实这里的system:anonymous 其实是kubernetes默认配置指定的,kubernetes对于外部请求的身份认证分为认证、授权、准入控制三个层面,所有 未被配置的其他身份验证方法拒绝 的请求被视为匿名请求,并被授予 system:anonymous 用户名和 system:unauthenticated 组(可以通过启动 kubelet 时指定 --anonymous-auth=false 标志来禁止该返回)。所以这里只是说明 我们提供的token 通过了认证,但并没有被授予合适的权限。

kubectl config view -o jsonpath='{.users[*].name}'

首先要知道kubernetes中并没有user这个资源对象的概念,对应的有service account这个资源对象,主要用于pod内部访问kubernetes api,通过将关联的 secret挂载到pod实现。但通过curl访问kubernetes api时,我们可以即可以使用use账号来认证授权,也可以通过service account来完成,上面的例子就是通过service account 来访问的,我们只需要解决授权的问题。
在RBAC这种认证模式下,通过创建ClusterRole/Role进行角色权限定义,指定对某类资源(如pods)的操作权限(get,list,watch,update,create,delete等),然后通过Rolebinding/ClusterRoleBinding去将创建好的角色绑定到 user 或者 service account。

#role定义文件 role.yaml#使用kubectl create -f role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate:"true"# 此处的 "namespace" 被省略掉是因为 ClusterRoles 是没有命名空间的。
  name: role-xingqing
rules:
- apiGroups:[""]
  resources:["pods"]
  verbs:["get","list","watch","update","create","delete"]
kubectl create rolebinding role-binding-xingqing --role=role-xingqing --serviceaccount=default:default

因为我们的角色是定义的对pods的权限,所以对于pods的接口是可以正常返回的,当你访问其他资源时,就会被禁止

curl$APISERVER/api/v1/namespaces/default/pods  --header"Authorization: Bearer$TOKEN" --insecure                                                       caidongqing@IT-C02Z2CAFLVCF{"kind":"PodList","apiVersion":"v1","metadata":{"selfLink":"/api/v1/namespaces/default/pods","resourceVersion":"265992975"},"items":[]}%                                                                                                                                                                                       -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

~ »curl$APISERVER/api/v1/namespaces/default/deployment  --header"Authorization: Bearer$TOKEN" --insecure                                                 caidongqing@IT-C02Z2CAFLVCF{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"deployment is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"deployment\" in API group \"\" in the namespace \"default\"","reason":"Forbidden","details":{"kind":"deployment"},"code": 403}
  • 作者:%%'' OR 1=1
  • 原文链接:https://blog.csdn.net/cdq1358016946/article/details/106269512
    更新时间:2022年7月5日13:13:53 ,共 3439 字。