K8s - using service accounts across namespaces - kubernetes

I have a service account, in the default namespace, with a clusterRoleBinding to a clusterRole that can observe jobs.
I wish to use this service account in any namespace rather than have to define a new service account in each new namespace. The service account is used by an init container to check a job has completed before allowing deployment to continue.
Not sure what extra info I need to provide but will do so on request.

You can simply reference a ServiceAccount from another namespace in the RoleBinding:
For example, below is sample use to refer the service account in one namespace to another for just reading the pods.
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-reader
namespace: ns2
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-from-ns1
namespace: ns2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: ServiceAccount
name: ns1-service-account
namespace: ns1

Related

How to configure a ClusterRole for namespaced resources

I want to allow a ServiceAccount in namespace A to access a resource in namespace B.
To achieve this I connect the ServiceAccount to a ClusterRole via a ClusterRoleBinding.
The documentation says I can "use a ClusterRole to [1.] define permissions on namespaced resources and be granted within individual namespace(s)"
But looking through the K8s documentation I can't find a way how to create a ClusterRole with namespaced resources. How can I achieve this?
...how to create a ClusterRole with namespaced resources...
Read further down a bit:
A ClusterRole can be used to grant the same permissions as a Role.
Because ClusterRoles are cluster-scoped. You can also use them to
grant access to:
...
namespaced resources (like Pods), across all namespaces
ClusterRole won't help you to restraint access to a single namespaced object. You can however use RoleBinding to reference a ClusterRole and restraint access to the object in the namespace of the RoleBinding.
I believe you need to create clusterrole not role.
example:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["bind"]
# omit resourceNames to allow binding any ClusterRole
resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: role-grantor-binding
namespace: user-1-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: user-1
above example is from this link.
I find both other answers a little confusing, hopefully this is clearer.
You did the right thing in creating a ClusterRole, but you want to bind it using a namespaced RoleBinding, not a ClusterRoleBinding.
Example using your examples. Notice how the RoleBinding is in the B namespace, giving A's ServiceAccount the permissions defined in the ClusterRole, but limited to the B namespace.
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: what-a-is-allowed-to-do-in-b
rules:
- apiGroups: [""]
resources: ["pods", "deployments"] # etc
verbs: ["get", "list", "create"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: namespace-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: what-a-is-allowed-to-do-in-b
namespace: namespace-b
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: what-a-is-allowed-to-do-in-b
subjects:
- kind: ServiceAccount
name: my-app
namespace: namespace-a
Notes:
You have to use the ClusterRole because you can't get outside your own namespace without one. By using a RoleBinding, which is namespaced, you can then limit the access to the scope of the namespace of that RoleBinding.

How to write a psp in k8s only for a specific user?

minikube start
--extra-config=apiserver.enable-admission-plugins=PodSecurityPolicy
--addons=pod-security-policy
we have a default namespace in which the nginx service account does not have the rights to launch the nginx container
when creating a pod, use the command
kubectl run nginx --image=nginx -n default --as system:serviceaccount:default:nginx-sa
as a result, we get an error
Error: container has runAsNonRoot and image will run as root (pod: "nginx_default(49e939b0-d238-4e04-a122-43f4cfabea22)", container: nginx)
as I understand it, it is necessary to write a psp policy that will allow the nginx-sa service account to run under, but I do not understand how to write it correctly for a specific service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-sa
namespace: default
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-sa-role
namespace: default
rules:
- apiGroups: ["extensions", "apps",""]
resources: [ "deployments","pods" ]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-sa-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: nginx-sa
namespace: default
roleRef:
kind: Role
name: nginx-sa-role
apiGroup: rbac.authorization.k8s.io
...but I do not understand how to write it correctly for a specific service account
After you get your special psp ready for your nginx, you can grant your nginx-sa to use the special psp like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-to-use-special-psp
rules:
- apiGroups:
- policy
resourceNames:
- special-psp-for-nginx
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-to-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-to-use-special-psp
subjects:
- kind: ServiceAccount
name: nginx-sa
namespace: default

How to schedule a job on behalf of a service account from another namespace?

I have a Kubernetes service running in namespace NA that is configured to run as a service account A. The service schedules a Kubernetes job in namespace NB. How do I make a job in NB act on behalf of service account A? I tried to specify the name of the service account for the job, but I get the following error:
Error creating: pods "pod_id_x is forbidden: error looking up service account NB/A: serviceaccount "A" not found
P.S. I am using Google Kubernetes Engine
AFAIK this can be done by granting Service Account [A] a rolebinding in namespace NB allowing it to deploy pods. You just need the proper role.
You can simply reference a ServiceAccount from another namespace in the RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-reader
namespace: ns2
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-from-ns1
namespace: ns2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: ServiceAccount
name: ns1-service-account
namespace: ns1

Kubernetes can not list pods as user

I am seeing this error for user jenkins when deploying.
Error: pods is forbidden: User "system:serviceaccount:ci:jenkins" cannot list pods in the namespace "kube-system"
I have created a definition for service account
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
I have created a ClusterRoleBinding
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: jenkins
namespace: kube-system
Any advice?
Without a namespace (in the ServiceAccount creation) you will automatically create it in the default namespace. The same with a Role (which is always a one-namespace resource).
What you need to do is to create a ClusterRole with the correct permissions (basically just change your role into a ClusterRole) and then set the correct namespace either on the ServiceAccount resource or in the ClusterRole binding.
You can also skip creating the Role and RoleBinding, as the ClusterRole and ClusterRoleBinding will override it either way.
--
With that said. It's always good practice to create a specific ServiceAccount and RoleBinding per namespace when it comes to deploys, so that you don't accidently create an admin account which is used in a remote CI tool like... Jenkins ;)

Can I connect one service account to multiple namespaces in Kubernetes?

I have couple of namespaces - assume NS1 and NS2. I have serviceaccounts created in those - sa1 in NS1 and sa2 in NS2. I have created roles and rolebindings for sa1 to do stuff within NS1 and sa2 within NS2.
What I want is give sa1 certain access within NS2 (say only Pod Reader role).
I am wondering if that's possible or not?
You can simply reference a ServiceAccount from another namespace in the RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-reader
namespace: ns2
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-from-ns1
namespace: ns2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: ServiceAccount
name: ns1-service-account
namespace: ns1