一个计算机技术爱好者与学习者

0%

好好学K8S:使用curl访问k8s的apiserver

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