bmuschko/ckad-crash-course

worked through 21-rbac-serviceaccount with no success

p-alik opened this issue · 6 comments

The attempt to apply the solution of 21-rbac-serviceaccount didn't succeed in my environment

k version
Client Version: v1.29.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.29

Still getting

k logs service-list -n t23 --since 5s
}{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "services is forbidden: User \"system:anonymous\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "services"
  },
  "code": 403

BTW I'd like use the opportunity to express my profound gratitude to you for the crash course!

I think I'd need more information about your environment. What's the Kubernetes distribution you are using? Can you create a GitHub repository that contains the YAML manifests you are using for a reproducer?

Well the k8s cluster was setup manually on Debian 11 virtual server.

root@k8s-master:~# dpkg -l | grep kube
hi  kubeadm                              1.29.2-1.1                      amd64        Command-line utility for administering a Kubernetes cluster
hi  kubectl                              1.29.2-1.1                      amd64        Command-line utility for interacting with a Kubernetes cluster
hi  kubelet                              1.29.2-1.1                      amd64        Node agent for Kubernetes clusters
ii  kubernetes-cni                       1.3.0-1.1                       amd64        Binaries required to provision kubernetes container networking

How to reproduce:

root@k8s-master:~# kk create namespace t23
namespace/t23 created
root@k8s-master:~# kk create serviceaccount api-call -n t23
serviceaccount/api-call created
root@k8s-master:~# k apply -f - <<EOF
> apiVersion: v1
kind: Pod
metadata:
  name: service-list
  namespace: t23
spec:
  serviceAccountName: api-call
  containers:
  - name: service-list
    image: alpine/curl:3.14
    command: ['sh', '-c', 'while true; do curl -s -k -m 5 -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/services; sleep 10; done']
> EOF
cat: /var/run/secrets/kubernetes.io/serviceaccount/token: No such file or directory
pod/service-list created
root@k8s-master:~# k logs service-list -n t23
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "services is forbidden: User \"system:anonymous\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "services"
  },
  "code": 403
}
..
root@k8s-master:~# k apply -f - <<EOF                                                      
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: list-services-clusterrole
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["list"]
EOF
clusterrole.rbac.authorization.k8s.io/list-services-clusterrole created
root@k8s-master:~# k apply -f - <<EOF                                                               
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: serviceaccount-service-rolebinding
subjects:
- kind: ServiceAccount
  name: api-call
  namespace: t23
roleRef:
  kind: ClusterRole
  name: list-services-clusterrole
  apiGroup: rbac.authorization.k8s.io
EOF
rolebinding.rbac.authorization.k8s.io/serviceaccount-service-rolebinding created
root@k8s-master:~# kubectl logs service-list -n t23
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "services is forbidden: User \"system:anonymous\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "services"
  },
  "code": 403
}
..

Seems the problem relies to cat: /var/run/secrets/kubernetes.io/serviceaccount/token: No such file or directory. The request to the API from the container succeeds

root@k8s-master:~# k exec -it service-list -n t23 --  sh -c 'curl -s -k -m 5 -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/services' | jq .kind
"ServiceList"

It sounds like you opted out of ServiceAccount API credential automounting. Can you check your configuration?

It sounds like you opted out of ServiceAccount API credential automounting. Can you check your configuration?

I don't think that is the case. For the pod created with automountServiceAccountToken: false, curl showed the same error message logged by the pod itself. But curl request succeeded without automountServiceAccountToken.

root@k8s-master:~# k apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: service-list
  namespace: t23
spec:
  serviceAccountName: api-call
  automountServiceAccountToken: false
  containers:
  - name: service-list
    image: alpine/curl:3.14
    command: ['sh', '-c', 'while true; do curl -s -k -m 5 -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/services; sleep 10; done']
EOF
cat: /var/run/secrets/kubernetes.io/serviceaccount/token: No such file or directory
pod/service-list created
root@k8s-master:~# k exec -it service-list -n t23 --  sh -c 'curl -s -k -m 5 -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/services' 
cat: can't open '/var/run/secrets/kubernetes.io/serviceaccount/token': No such file or directory
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "services is forbidden: User \"system:anonymous\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "services"
  },
  "code": 403
}

However I don't think we should spend more time on the matter. So I would close the issue, if there's no objection on your side.

Hhhmm, I can't think of any other option that would turn off ServiceAccount API credential automounting centrally in your cluster. Alternatively, simply set automountServiceAccountToken: true so that you do have the file available in your container. That should do it.

I am going to close the issue. Thanks for your response.