Reputation: 1
By default, the data in clusterrole system:node is as below:
$ kubectl get clusterrole system:node -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
name: system:node
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- apiGroups:
- ""
resources:
- pods/status
verbs:
- patch
- update
Now, I want to change the clusterrole system:node
, and added a - patch
under the pods resources, it should be like this:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- patch
I could update it by using kubectl edit
, but I want to update it in the bash script, so kubectl edit
is not suitable, is there any other solution using kubectl?
Upvotes: 0
Views: 14150
Reputation: 2196
If you don't mind storing the entire manifest, then I recommend Blokje5's answer of using kubectl apply
. However, if you're looking for a minimal command that doesn't require storing the entire manifest, then you have two options here using kubectl patch --type 'json'
:
1 - Use an 'add' operation
kubectl patch clusterrole system:node --type='json' -p='[{"op": "add", "path": "/rules/0", "value":{ "apiGroups": [""], "resources": ["pods"], "verbs": ["get","list","watch","patch"]}}]'
This will insert your new rule at the beginning of the array. Since permissions are additive, the role will get the additional permission you want.
2 - Use a 'replace' operation
kubectl patch clusterrole system:node --type='json' -p='[{"op": "replace", "path": "/rules/0/verbs", "value":["get","list","watch","patch"]}]'
This will replace the verbs
array of the first element in the rules
array.
Here is an explanation as to why these are your only options:
kubectl patch
can use 3 different patch strategies. It defaults to using the 'strategic' patch.
Elements in the containers
array of the Deployment
object have the unique name
field and so when doing a 'strategic' patch, it will replace the element that matches the unique value of that field.
containers:
- name: this-is-unique-and-a-match-will-replace-this
image: nginx
However, elements in the rules
array of the ClusterRole
object do not have a field that requires a unique value. And so the 'strategic' patch has no way of knowing which element you want replaced. Therefore, it just replaces the entire array with whatever patch you give it.
Since the 'strategic' patch is not a viable option for you here (unless you're okay with replacing the entire rules array), you have to resort to using the 'json' patch, which allows you to explicitly define array inserts and replaces.
The disadvantage here is that in option 1, you can add permissions, but not remove them as Kubernetes RBAC is purely additive. And in option 2, you must know the index of the element you want to replace.
Here are some useful links:
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
Upvotes: 3
Reputation: 15252
Probably, the simplest automatable way is to add a new rule to the ClusterRole.
Create a file named append.yaml
with the following content:
- apiGroups:
- ""
resources:
- pods
verbs:
- patch
Then, append this rule to the existing YAML manifest of the ClusterRole and reapply it with:
kubectl apply -f <(cat <(kubectl get clusterrole system:node -o yaml) append.yaml)
The new rule will be merged with the other permissions for pods
, which you can verify with:
kubectl describe clusterrole system:node
The nicest imperative solution would be to patch the object with kubectl patch
, but it doesn't seem to be easily possible:
rules
array of the ClusterRole object seems to use a replace patch strategy, that is, the provided patch would just replace the existing array rather being merged with it.Upvotes: 0
Reputation: 13456
chages.yaml
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- patch #added
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- apiGroups:
- ""
resources:
- pods/status
verbs:
- patch
- update
Use the following bash command to update the ClusterRole
kubectl patch clusterrole system:node --patch "$(cat changes.yaml)"
For more details visit k8s official documentations
Upvotes: 3
Reputation: 4993
You can use a kubectl apply -f node-role.yaml
where node-role.yaml
contains the yaml definition of the ClusterRole
with your change included. kubectl apply
will update the role if it already exists (and create it otherwise).
Upvotes: 9