Locks in Kubernetes
Tags: kubernetes
Published: 2022-09-16 06:41:17


## Problem

In an event-driven system like Kubernetes, access to a resource can be restricted with RBAC. RBAC is not designed to execute a mandatory or exclusive lock on a particular resource. It is not impossible, but I found it complicated and error-prone.

Sometimes I want:

* The CronJob named `daily-report` is constant. No one can DELETE or UPDATE it.
* A workload `payroll` can be modified only by the actor with UID `aa-dd-f445-d-55-d` and no one else.
* All resources with the label `site: for-fun` can be updated, but not deleted.

## Solution

Using RBAC is possible to partially meet requirements, but still when working in teams messing with operators, different automation tools, etc... Always something can go wrong.

Another option is [ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook). It can be used to say who can and can not access a certain resource. It is not about authentication or authorization, that part is done by Kubernetes. It is about access,
granular access.

### [Klock](https://github.com/robert-nemet/klock) as solution

[__Klock__](https://github.com/robert-nemet/klock) is simple implementation in effort to match above problems. It adds __CRD__ that allows mandatory and exclusive locking. Matching which resource will be protected is done by matching labels. As well as which operation should be restricted.

#### Configuring ValidatingAdmissionWebhook

For which resource ValidatingAdmissionWebhook(VAW) is applied is done in VAW configuration:

```yaml
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
    - configmaps
  sideEffects: None
```

Above configuration, you can read as _for any api group and any version, whenever UPDATE or DELETE is about to be executed on a pod, a deployment, a secret, or a config map, ask VAW to validate it first_.

#### Mandatory locking

See example:

```yaml
apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
  name: lock-red-blue
  namespace: yellow
spec:
  operations:
    - DELETE
  matcher:
    aura: blue
```

Now, if VAW has config as above `Lock` is effective for every pod, deployment, secret, and configmap in the same namespace. It will deny deletion of any pod, deployment, secret, or configmap with the label `aura: red`.

#### Exclusive locking

```yaml
apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
  name: lockred
spec:
  operations:
    - UPDATE
    - DELETE
  matcher:
    aura: red
  exclusive:
    name: johny
```

With exclusive locking `operations` are forbidden for all except an actor named `johny`, in this example. So, same as above just ignore `Lock` for `johny`.

## Conclusion

You can check out [Klock](https://github.com/robert-nemet/klock) and explore it more. See `/tests/` for more examples.