I have created a cluster role yaml(rbac.yaml) like this:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups: [""]
resources: ["services","endpoints","secrets"]
verbs: ["get","list","watch"]
- apiGroups: ["extensions"]
resources: ["ingresses"]
verbs: ["get","list","watch"]
Now I want to add a new apiGroups into the ClusterRole.
How to edit the ClusterRole and refresh? I search from kubernetes docs,but nothing to tell how to edit.what should I do to update the yaml?
You just need to modify the yaml and apply it again. Kubernetes API Server will take care of updating it into ETCD storage and it should take effect almost immediately.
You can also edit in directly via kubectl edit clusterrole clustebrolename but I don't recommend that because you loose the previous history. You should really be version controlling your yamls and apply the changes with kubectl apply
Related
Could some one please help me with this..
I would like to understand a bit about the apiGroups & its usage in below Role definition.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example.com-superuser
rules:
- apiGroups: ["example.com"]
resources: ["*"]
verbs: ["*"]
I was going through RBAC in Kubernetes. https://kubernetes.io/docs/reference/access-authn-authz/rbac/
Above example is from this link.
An api group groups a set of resource types in a common namespace. For example, resource types related to Ingress services are grouped under the networking.k8s.io api group:
$ kubectl api-resources --api-group newtorking.k8s.io
NAME SHORTNAMES APIVERSION NAMESPACED KIND
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
It is possible to have two different resource types that have the same short name in different resource groups. For example, in my OpenShift system there are two different groups that provide a Subscription resource type:
$ kubectl api-resources | awk '$NF == "Subscription" {print}'
subscriptions appsub apps.open-cluster-management.io/v1 true Subscription
subscriptions sub,subs operators.coreos.com/v1alpha1 true Subscription
If I am creating a role, I need to specify to which Subscription I want to grant access. This:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: allow-config-access
rules:
- apiGroups:
- operators.coreos.com
resources:
- subscriptions
verbs: ["*"]
Provides access to different resources than this:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: allow-config-access
rules:
- apiGroups:
- apps.open-cluster-management.io
resources:
- subscriptions
verbs: ["*"]
ApiGroups in Kubernetes are used to specify the set of resources that a Role or ClusterRole can access. In the example given, apiGroups is set to ["example.com"] which means the Role is allowed to access all resources from the “example.com” api. This allows admins to control access to different resources within the Kubernetes cluster.
The role namespace-limited should have full access to all resources (of the specified API groups) inside of a namespace. My Role manifest looks like this:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-limited
namespace: restricted-xample
rules:
- apiGroups:
- core
- apps
- batch
- networking.k8s.io
resources: ["*"] # asterisk to grant access to all resources of the specified api groups
verbs: ["*"]
I associated the Role to a ServiceAccount using a RoleBinding but unfortunately this ServiceAccount has no access to Pod, Service, Secret, ConfigMap and Endpoint Resources. These resources are all part of the core API group. All the other common Workloads work though. Why is that?
The core group, also referred to as the legacy group, is at the REST path /api/v1 and uses apiVersion: v1
You need to use "" for core API group.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: restricted-xample
name: namespace-limited
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"] # "" indicates the core API group
resources: ["*"]
verbs: ["*"]
To test the permission of the service account use below commands
kubectl auth can-i get pods --as=system:serviceaccount:restricted-xample:default -n restricted-xample
kubectl auth can-i get secrets --as=system:serviceaccount:restricted-xample:default -n restricted-xample
kubectl auth can-i get configmaps --as=system:serviceaccount:restricted-xample:default -n restricted-xample
kubectl auth can-i get endpoints --as=system:serviceaccount:restricted-xample:default -n restricted-xample
Just figured out, that it works when I omit the core keyword, like in this example. Following Role manifest works:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-limited
namespace: restricted-xample
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["*"]
verbs: ["*"]
But why it does not work if I specify the core API group is a mystery to me.
I need to grant access to one deployment and all pods of this deployment using RBAC.
I've managed to configure Role and RoleBinding for the deploymet, and it's working fine:
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: <my-namespace>
name: <deployment>-manager-role
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["deployments"]
resourceNames: ["<deployment>"]
verbs: ["get", "list", "watch", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: <deployment>-manager-binding
namespace: <my-namespace>
subjects:
- kind: User
name: <username>
apiGroup: ""
roleRef:
kind: Role
name: <deployment>-manager-role
apiGroup: ""
Using this role user can access, update and patch the deployment. This deployment creates pods with dynamic names (like <deployment>-5594cbfcf4-v4xx8). I tried to allow this user to access these pods (get, list, watch, read logs, exec, delete) using deployment name and using deployment name + wildcard char *:
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: <my-namespace>
name: <deployment>-pods-manager-role
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["pods"]
resourceNames: ["<deployment>*"]
verbs: ["get", "list", "watch", "update", "patch", "exec", "delete"]
I also updated the role binding. But when I try to get the pod:
kubectl --context=<username>-ctx -n <namespace> get pods <deployment>-5594cbfcf4-v4xx8
I'm getting error:
Error from server (Forbidden): pods "<deployment>-5594cbfcf4-v4xx8" is forbidden: User "<username>" cannot get resource "pods" in API group "" in the namespace "<namespace>"
If I add <deployment>-5594cbfcf4-v4xx8 to the list of resourceNames, user can access this pod.
Is it possible to grant access to the specific pods based on deployment name?
In Kubernetes, pods are considered as an ephemeral "cattle", they come and go. You shouldn't try to manage RBAC per pod.
In your use case, there is unfortunately no way to grant a role over a set of pods matching a certain name, because the resourceNames field doesn't support patterns like prefixes/suffixes. Don't get confused: a single asterisk character ('*') has a special meaning that means "all", but it's not a pattern. So, 'my-app-* in resourceNames will not work. There were tickets opened for this feature, but it wasn't implemented:
https://github.com/kubernetes/kubernetes/issues/56582
There was also a request to be able to manage RBAC over labels, but that feature isn't implemented neither:
https://github.com/kubernetes/kubernetes/issues/44703
Therefore, you probably need to change your model to grant roles to users to manage all pods in a certain namespace. Your deployment should be the only "source of pods" in that namespace. That way, you will not need to specify any resource names.
I am trying to allow some users in my org to forward ports to our production namespace in Kubernetes. However, I don't want them to be able to forward ports to all services. I want to restrict access to only certain services. Is this possible?
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: allow-port-forward-for-deployment-a
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["get", "list", "create"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: allow-port-forward-for-deployment-a
namespace: production
subjects:
- kind: User
name: "xyz#org.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: allow-port-forward-for-deployment-a
apiGroup: rbac.authorization.k8s.io
The above set up allows all services, but I don't want that.
I believe you can't. According to the docs
Resources can also be referred to by name for certain requests through
the resourceNames list. When specified, requests can be restricted to
individual instances of a resource. To restrict a subject to only
“get” and “update” a single configmap, you would write:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
Note that create requests
cannot be restricted by resourceName, as the object name is not known
at authorization time. The other exception is deletecollection.
Since you want to give the user permissions to create the forward ports, I don't think you can.
These rules worked for me
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: port-forward
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["get", "create"]
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
Assuming users already have access to your kubernetes cluster and relevant namespace. They can simply port-forward local port to a pod (resource) port.
How can you do this?
kubectl port-forward <POD_NAME> <LOCAL_PORT>:<POD_PORT>
See Documentation
Quoting from the document - kubectl port-forward allows using resource name, such as a pod name, to select a matching pod to port forward to since Kubernetes v1.10.
Refer this article if you wish, this nicely explains when you would need RBAC vs kubectl port-forward
RBAC could have been useful only when, you wanted person or a group of people only to port-forward for any services in a relevant namespace in your kubernetes cluster.
Workaround A: StatefulSets and resourceNames
It is possible to restrict port forwarding to a pod with a specific name. resourceNames refer to resources, not subresources:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: allow-port-forward-for-deployment-a
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
resourceNames: ["my-app"]
verbs: ["create"]
A StatefulSet generates predictable pod names, but is different from a ReplicaSet and might not fit your use case.
Workaround B: Jump pod and NetworkPolicy
Sketch:
A StatefulSet that runs kubectl port-forward services/my-service inside the cluster (JUMP).
A NetworkPolicy which restricts traffic from pods belonging to JUMP to the target service
RBAC which restricts creation of subresource portforward to the pods of JUMP up to a predefined maximum number of replicas resourceNames: ["jump-0", "jump-1", ..., "jump-N"].
I need to give access to a set of pods within a namespace to an external support.
I've been reading about the RBAC API, [Cluster]Roles and [Cluster]Role Bindings; but I could not find anything about how to apply a role to a group of pods (based on annotations or labels).
Does anyone know if it is possible to do that?
This is the Role that I use now, and need limit it to a specific pods set:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: <ClientX>-PodMonitor
namespace: <namespace>
rules:
- apiGroups: [""]
verbs: ["get", "list"]
resources: ["pods", "pods/log"]
If you guys need more details, please let me know.
Thanks.
Try below way of defining role-binding with resource name as example on docs:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]