Clean and easy way to protect the k8s resource from deletion or updates. It could be achieved with RBAC but it is not explicit enough. This does not exclude RBAC, an operator which set the lock on the resource still needs rights to access it.
- Mandatory locking (no one can update/delete a resource) as long the lock exists
- Exclusive locking (only one can update/delete a resource) as long the lock exists
Lock CRD which resign in a namespace, protects any resource which matches at least one label. Protection is only for specified operations.
Avoid deadlock by ignoring lock on a lock.
Which resources are tracked by the lock is defined in ValidatingWebhookConfiguration.
apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
name: lock-red-blue
namespace: yellow
spec:
operations:
- UPDATE
- DELETE
matcher:
aura: redIn above example Lock is mandatory lock. In the namespace yellow is will prevent any UPDATE/DELETE operation
on every resource that have at least one label as defined in matcher section. So, if there is a Pod with label
aura: red in the same namespace as the lock it can be deleted as long the lock exists.
If you need to lock multiple resources with same label name but different values you can use expressions like:
aura: red|blue|greenWhich means protect from update and delete all resources if they have label named aura which value is red or
blue or green.
In case label named aura can have values: red, blue, green and black, above expression can be:
aura: ^blackWhich can be read as protect all resources with label named aura which value is not black.
Other examples:
...
aura: ^(red|blue)
...
aura: black|^blueSupported operations are &(AND) , |(OR) and ^(NOT).
See test: /tests/e2e/lock-expression
Locks like this:
apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
name: lock-protect-sun
spec:
operations:
- UPDATE
- DELETE
matcher:
aura: red
element: ^windBefore version v3.0.0 would lock any resource that have label aura: red. In version v3.0.0 for resource to be locked it has to match all expressions under matcher.
Looking in above example a Pod with labels aura: red and element: earth will be locked, while a Pod with labels aura: red and element: wind will not be lock.
See test: /tests/e2e/lock-expressions-two-labels
apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
name: lockred
spec:
operations:
- UPDATE
- DELETE
matcher:
aura: red
exclusive:
name: johnySame as in previous example except if operation requester is the johny. The johny can delete a pod.
Field spec contains Lock specification. It has two sub resources:
operationsis a list containing operations to watch for.matcheris a set of labels to match when looking for locked resources. For operation to be denied ony one needs to be matched.exclusivedefine requester params when setting exclusive lock. One parameter is enough. If both are set then both needs to match:namerequester nameuidrequester uid
Based on ValidatingWebhookConfiguration when ever one of operations is invoked:
- check if in target
namespaceexists anyLock - for every found
Lockwhich contains target operation:- try to find matching
Lockand target object
- try to find matching
A lock will not lock other lock, even if it set by configuration.
Cpnfiguration is autogenerated by kubebuilder. Initially only Pods, Deployments and,
Secretcs can be locked. This can be changed by modifying ValidatingWebhookConfiguration named klock-validating-webhook-configuration.
As well, UPDATE and DELETE operations are set there as operations to watch for. If needed user can modify that as well. It is not recommended
to watch for all possible resources.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
annotations:
cert-manager.io/inject-ca-from: klock-system/klock-serving-cert
name: klock-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: klock-webhook-service
namespace: klock-system
path: /validate-all
failurePolicy: Fail
name: klocks.rnemet.dev
rules:
- apiGroups:
- '*'
apiVersions:
- '*'
operations:
- DELETE
- UPDATE
resources:
- pods
- deployments
- secrets
sideEffects: NoneIf you need some other resources or operations modify webhook configuration. Operations used in webhook configuration are used in Lock.
Tests are located in folder ./tests/:
make ktestTests are run by kind and KUTTL.
Start kind cluster:
make make-clusterInstall cert-manager:
make cert-managermake docker-build IMG=IMG=<some-registry>/klock:tagLoad image into local cluster: kind load docker-image IMG=<some-registry>/klock:tag
- Kustomize:
make deploy IMG=IMG=<some-registry>/klock:tag
To your cluster:
kubectl apply -f install/klock-1.0.0.yaml$ helm repo add rnemet https://rnemet.dev/helm-charts
$ helm install klock rnemet/klockmake ktestTo delete the CRDs from the cluster:
make uninstallUnDeploy the controller to the cluster:
make undeployThis project aims to follow the Kubernetes Operator pattern
It uses Controllers which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster
Copyright 2022 Robert Nemet.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.