Prerequisites
Single node kubernetes cluster with RBAC authorization mode enabled.
-
check
kube-apiserver
hasRBAC
enabledprlctl exec scorpius "ps -aef | grep kube-apiserver | grep authorization-mode | sed 's/ --/\n--/g'"
Resulting output for
kube-apiserver
process start command should contain--authorization-mode=RBAC
. If authorization mode has other modes enabled butRBAC
then RBAC would not workroot 1624 1312 3 19:37 ? 00:00:42 kube-apiserver --advertise-address=10.211.55.49 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
Configure pod view access for user Bob in his namespace
-
Create dedicated namespace for Bob with name
bob-space
prlctl exec scorpius --user cka "kubectl create namespace bob-space"
-
Create role
pod-viewer
prlctl exec scorpius --user cka "kubectl -n bob-space create role pod-viewer --verb=get,list,watch --resource=pods"
-
Create Role Binding ‘pod-viewer’ for user
bob
prlctl exec scorpius --user cka "kubectl -n bob-space create rolebinding --role=pod-viewer --user=bob pod-viewer"
-
Use
kubectl
to test permissions# check Bob can view pods in his namespace prlctl exec scorpius --user cka "kubectl -n bob-space auth can-i get pods --as=bob" # yes # check Bob can view pods in default namespace prlctl exec scorpius --user cka "kubectl -n default auth can-i get pods --as=bob" # no $ check John can view pods in Bob's namespace prlctl exec scorpius --user cka "kubectl auth can-i get secrets --as=john" # no
-
Another way of testing is to authenticate kubectl using different user. For that you need x509 cert for user
bob
which can be generated withkubeadm
# generate credentials for Bob and save them into bob.conf prlctl exec scorpius "kubeadm kubeconfig user --client-name=bob > /home/cka/.kube/bob.conf; chown cka:cka /home/cka/.kube/bob.conf" # generate credentials for John and save them into bob.conf prlctl exec scorpius "kubeadm kubeconfig user --client-name=john > /home/cka/.kube/john.conf; chown cka:cka /home/cka/.kube/john.conf"
config generated for Bob and John would look similar to this
apiVersion: v1 clusters: - cluster: certificate-authority-data: a3ViZXJuZXRlcy4iY2VydGlmaWNhdGUtYXV0aG9yaXR5LWRhdGEiCg== server: https://10.211.55.34:6443 name: kubernetes contexts: - context: cluster: kubernetes user: bob name: bob@kubernetes current-context: bob@kubernetes kind: Config preferences: {} users: - name: bob user: client-certificate-data: Ym9iLnVzZXIuImNsaWVudC1jZXJ0aWZpY2F0ZS1kYXRhIgo= client-key-data: Ym9iLnVzZXIuImNsaWVudC1rZXktZGF0YSIK
-
start some pods before the test
# use admin permissions to create a new pod in Bob's namespace prlctl exec scorpius --user cka "kubectl run nginx --image=nginx -n bob-space" # use admin permissions to create a new pod in default namespace prlctl exec scorpius --user cka "kubectl run busybox --image=busybox -- sleep infinity"
-
Get pods using bob credentials
# use Bob's credentials to get pods in his own namespace prlctl exec scorpius --user cka "KUBECONFIG=~/.kube/bob.conf kubectl get pods -n bob-space" # NAME READY STATUS RESTARTS AGE # nginx 1/1 Running 0 81s # use Bob's credentials to get pods in default namespace prlctl exec scorpius --user cka "KUBECONFIG=~/.kube/bob.conf kubectl get pods" # Error from server (Forbidden): pods is forbidden: User "bob" cannot list resource "pods" in API group "" in the namespace "default" # use John's credentials to get pods in Bob's namespace prlctl exec scorpius --user cka "KUBECONFIG=~/.kube/john.conf kubectl get pods -n bob-space" # Error from server (Forbidden): pods is forbidden: User "john" cannot list resource "pods" in API group "" in the namespace "bob-space"
Configure pod view access for a service account
-
ssh into
scorpius
ssh cka@scorpius
-
create namespace
antares
kubectl create namespace antares
-
create service account
meteorite
kubectl create sa meteorite -n antares
-
create
nginx
podkubectl run nginx --image=nginx -n antares
-
create new role binding
antares-view
which binds existing cluster roleviewer
to the new service account ‘meteorite’kubectl create rolebinding antares-view --clusterrole=view \ --serviceaccount=antares:meteorite -n antares"
-
with
antares-view
role binding pods inantares
namespace withmeteorite
permissions have access to view resources defined by cluster roleview
. Now create such pod inantares
with curl utility onboard, set service account and a few environment variableskubectl run curl --image curlimages/curl \ --overrides='{"spec":{"serviceAccountName":"meteorite"}}' \ --env="APISERVER=https://kubernetes.default.svc" \ --env="SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount" \ --env="CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \ -n antares -- sleep infinity
-
check kubernetes REST API URIs documentation to understand how to run curl. The following list of request is expected to be forbidden since we’ve created role binding for a specific namespace
antares
/api/v1/namespaces
- forbidden/api/v1/pods
- forbidden/apis/apps/v1/deployments
- forbidden
And resources in
antares
namespace should be accessible/api/v1/namespaces/antares/pods
- allowed/apis/apps/v1/namespaces/antares/deployments
- allowed/apis/apps/v1/namespaces/antares/deployments/nginx
- allowed
-
test
antares-view
rolebinding# exec into curl pod kubectl -n antares exec curl -it -- sh
Inside pod’s shell run
# get service account namespace NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) # get service account token TOKEN=$(cat ${SERVICEACCOUNT}/token) # get pods in antares curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ ${APISERVER}/api/v1/namespaces/antares/pods # you should see full description of two pods `busybox` and `curl` in `json` # format # { # "kind": "PodList", # "apiVersion": "v1", # "metadata": { # "resourceVersion": "245637" # }, # "items": [ # { # "metadata": { # "name": "curl", # ... # }, # ... # }, # { # "metadata": { # "name": "busybox", # ... # }, # ... # } # ] # } # get pods in a different namespace curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ ${APISERVER}/api/v1/namespaces/default/pods # error # { # "kind": "Status", # "apiVersion": "v1", # "metadata": {}, # "status": "Failure", # "message": "pods is forbidden: User \"system:serviceaccount:antares:meteorite\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"", # "reason": "Forbidden", # "details": { # "kind": "pods" # }, # "code": 403 # }
-
exit pod
Ctrl+D
-
exit
scorpius
sshCtrl+D