1. k8s管理工具
管理k8s集群,除了kubectl和go-client,其实还可以使用curl命令。
本文,我们就学习一下怎样使用curl访问k8s的apiserver,实现k8s集群的管理。主要参考如何使用curl访问k8s的apiserver。
需求:使用curl命令,实现 kubectl get pod 同样的效果。
使用curl命令访问k8s集群时,分别使用证书和token两种认证方式。
2. 使用证书
假设我们拥有集群的kubeconfig文件,我们需要从中拿出ca cert、client cert和client key,保存为文件。并且拿出apiserver,保存为变量。
1 2 3 4
| cat config | grep certificate-authority-data | awk '{print $2}' | base64 -d > ca.crt cat config | grep client-certificate-data | awk '{print $2}' | base64 -d > client.crt cat config | grep client-key-data | awk '{print $2}' | base64 -d > client.key APISERVER=$(cat config | grep server | awk '{print $2}')
|
查看API的url,使用curl命令调用API
1 2 3 4
| curl --cert ./client.crt --cacert ./ca.crt --key ./client.key $APISERVER/api
kubectl get pods -v8 curl --cert ./client.crt --cacert ./ca.crt --key ./client.key $APISERVER/api/v1/namespaces/default/pods/
|
以上,拿到了default空间下的pod信息,和 kubectl get pod 等同。
3. 使用token
3.1. 获取token
想要使用curl命令访问apiserver,首先要获得一个具有权限的token。
1 2
| kubectl get secrets --all-namespaces | grep admin kubectl describe secrets admin-token-vmv2c -n kube-system
|
输出结果为:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Name: admin-token-vmv2c Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: admin kubernetes.io/service-account.uid: a75b4cdc-e120-11e9-8695-00163e300424
Type: kubernetes.io/service-account-token
Data ==== ca.crt: 1419 bytes namespace: 11 bytes token: xxxthisisatokenxxx
|
最后一个字段就是token,那么这个token有哪些权限呢?
3.2. 查看token权限
根据annotations中的key value,可以看到这个secrets绑定了一个service-account(sa),name为admin。等同于这个token绑定了一个sa,name为admin。
查看admin这个service-account的信息。
1 2
| kubectl get sa --all-namespaces | grep admin kubectl describe sa admin -n kube-system
|
输出结果为:
1 2 3 4 5 6 7 8 9
| Name: admin Namespace: kube-system Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"admin","namespace":"kube-system"}} Image pull secrets: <none> Mountable secrets: admin-token-vmv2c Tokens: admin-token-vmv2c Events: <none>
|
没有关于admin的权限信息,那么我们再看一下admin绑定了哪些role和clusterrole。
1 2
| kubectl get rolebindings --all-namespaces -oyaml | grep "name: admin" -A10 -B10 kubectl get clusterrolebindings --all-namespaces -oyaml | grep "name: admin" -A10 -B10
|
找到有用信息为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"admin"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"cluster-admin"},"subjects":[{"kind":"ServiceAccount","name":"admin","namespace":"kube-system"}]} creationTimestamp: "2019-09-27T12:16:37Z" name: admin resourceVersion: "1317" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/admin uid: a75e1ef9-e120-11e9-8695-00163e300424 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin namespace: kube-system
|
可知admin绑定了一个名为cluster-admin的clusterrole,接着查看cluster-admin的权限。
1
| kubectl describe clusterrole cluster-admin -n kube-system
|
结果为:
1 2 3 4 5 6 7 8
| Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- *.* [] [] [*] [*] [] [*]
|
cluster-admin这个角色拥有集群的所有权限,因此admin这个sa拥有集群的所有权限。
3.3. 使用token
1、获取admin sa的token
1 2
| TOKEN=$(kubectl describe secrets $(kubectl get secrets -n kube-system |grep admin |cut -f1 -d ' ') -n kube-system |grep -E '^token' |cut -f2 -d':'|tr -d '\t'|tr -d ' ') APISERVER=$(kubectl config view |grep server|cut -f 2- -d ":" | tr -d " ")
|
或者获取default sa的token
1 2 3
| APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ") SECRET_NAME=$(kubectl get secrets | grep ^default | cut -f1 -d ' ') TOKEN=$(kubectl describe secret $SECRET_NAME | grep -E '^token' | cut -f2 -d':' | tr -d " ")
|
2、查看API的url,使用curl命令调用API
1 2 3 4
| curl --header "Authorization: Bearer $TOKEN" --insecure $APISERVER/api
kubectl get pods -v8 curl -H "Authorization: Bearer $TOKEN" --insecure $APISERVER/api/v1/namespaces/default/pods/
|
以上,拿到了default空间下的pod信息,和 kubectl get pod 等同。
4. kubectl proxy
上文中,我们使用curl命令访问k8s集群时,分别使用证书和token两种认证方式。
而使用kubectl proxy命令,可以启动一个apiserver的本地代理,默认监听在本地的8001端口上。
使用apiserver本地代理有什么好处呢?
- 我们使用curl访问apiserver的时候,不用自己获取token,更加简单。
- 因为不需要使用token,所以还可以浏览器访问apiserver。
1、启动apiserver本地代理
1 2
| kubectl proxy kubectl proxy --port 8080
|
2、另外打开一个终端
1 2 3
| curl http://localhost:8001
curl http://localhost:8080/api/v1/proxy/namespaces/YOURNAMESPACE/services/YOURSERVICE:PORT
|