I am trying to access a kubernetes cluster using the rest api. I followed the instructions of this but i wanted to get the pods of the cluster.
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
curl $APISERVER/api/v1/pods --header "Authorization: Bearer $TOKEN" --insecurethe result is:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403I tried the same (curl localhost:8001/api/v1/pods) by running the command:
kubectl proxy --address='0.0.0.0' --disable-filter=trueat the master node of the cluster and now it works as desired.
How can I make the Athorization Bearer work in the same manner?
In order to be able to get the pods for all the namespaces then you have to define a cluster-role and a cluster-role-binding, instead of a role/role-binding pair
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: get-pods
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: get-pods-binding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: get-pods
apiGroup: rbac.authorization.k8s.ioYou may save this to a file named for example get_pods_role.yaml and execute kubectl create -f get_pods_role.yaml. Then you will be able to get the desired output by this:
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
curl $APISERVER/api/v1/pods --header "Authorization: Bearer $TOKEN" --insecureYou are using default service account to get pods. default serviceaccount don't have that permission. You can check an action is allowed or not by running
$ kubectl auth can-i get pods --as system:serviceaccount:default:default
no
"message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
as can be seen above the default service account cannot list pods
but when given proper role and role binding like below
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: demo-role
namespace: default
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: demo-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: demo-role
subjects:
- kind: ServiceAccount
name: default
namespace: defaultNow if you check
$ kubectl auth can-i get pods --as system:serviceaccount:default:default
yes
If you want to list pods of default namespace using api then run
$ APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
$ SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
$ TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
$ curl $APISERVER/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/pods",
"resourceVersion": "1589"
},
"items": []
}