Kubernetes operators are surprisingly easy

Hi! Welcome to my first blog post, one of many more to come :)

I recently developed a Kubernetes operator for my secrets management project, FishyKeys. The objective was to generate Secrets objects from FishyKeys, taking inspiration from how External Secrets operates.

To accomplish this, I knew I needed to create an operator that will read my Custom Resource Definition (CRD) and generate the corresponding Secret object. Here is the structure of the CRD I had in mind:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: fishykeys.2v.pm/v1alpha1
kind: FishySecret
metadata:
name: test-fishy-secret
namespace: default
spec:
target:
name: test-secret
namespace: default
data:
- secretPath: "/app/db/username"
secretKeyName: "DB_USER"
- secretPath: "/app/db/password"
secretKeyName: "DB_PASS"

The corresponding Secret would then be created:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
ownerReferences:
- apiVersion: fishykeys.2v.pm/v1alpha1
kind: FishySecret
name: test-fishy-secret
controller: true
blockOwnerDeletion: true
data:
DB_USER: ZXhhbXBsZVVzZXI= # Base64 encoding of "exampleUser"
DB_PASS: ZXhhbXBsZVBhc3M= # Base64 encoding of "examplePassword"
type: Opaque

There are quite a few libraries to interface with the Kubernetes API, but Operator SDK is the most reputable, and the one I decided to use.

Unfortunately I find their tutorial hard to follow for implementing the controller. They want you to fill in the blanks of an example code, and even though the code is quite documented, it’s too much clutter for my usecase and thus I preferred to build my controller’s logic incrementally.