Isaac
Isaac

Reputation: 115

Kubernetes kube-apiserver to kubelet permissions

What controls the permissions when you call

kubectl logs pod-name ?

I've played around and tried calling the kubelet api from on of the controller nodes.

sudo curl -k --key /var/lib/kubernetes/cert-k8s-apiserver-key.pem --cert /var/lib/kubernetes/cert-k8s-apiserver.pem https://worker01:10250/pods

This fails with Forbidden (user=apiserver, verb=get, resource=nodes, subresource=proxy).

I've tried the same call using the admin key and cert and it succeeds and return a healthy blob of JOSN.

I'm guessing this is why kubectl logs pod-name doesn't work.

A little more reading suggests that the CN of the certificate determines the user that is authenticated and authorized.

What controls whether a user is authorized to access the kubelet API?

Background

I'm setting up a K8s cluster using the following instructions Kubernetes the not so hard way with Ansible

Upvotes: 0

Views: 1619

Answers (1)

Isaac
Isaac

Reputation: 115

Short Answer

The short answer is that you need to grant the user apiserver access to the resource node by creating a ClusterRole and ClusterRoleBinding.

Longer Explanation

Kubernetes has a bunch of resources. The relevant ones here are:

Roles and ClusterRoles are similar, except ClusterRoles are not namespaced.

A ClsuterRole can be associated (bound) to a user with a ClusterRoleBinding object.

Kubelet provides some resources (maybe more)

  • nodes/proxy
  • nodes/stats
  • nodes/log
  • nodes/spec
  • nodes/metrics

To make this work, you need to create a ClusterRole that allow access to the resource and sub-resource on the Node.

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
    verbs:
      - "*"
EOF

Then you associate this ClusteRole with a user. In my case, the kube-apiserver is using a certificate with CN=apiserver.

cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: apiserver
EOF

Upvotes: 2

Related Questions