The OpenFeature Operator is a Kubernetes native operator that allows you to expose feature flags to your applications. It injects a flagD sidecar into your pod and allows you to poll the flagD server for feature flags in a variety of ways.
Requires cert manager installed (see why here)
kubectl create namespace open-feature-operator-system
kubectl apply -f https://github.com/open-feature/open-feature-operator/releases/download/v0.2.6/certificate.yaml
kubectl apply -f https://github.com/open-feature/open-feature-operator/releases/download/v0.2.6/release.yaml
certificate.yaml
holds the cert-manager manifests used to authorize requests between components.release.yaml
contains the configuration of:FeatureFlagConfiguration
CustomResourceDefinition
(custom type that holds the configured state of feature flags).- Standard kubernetes primitives (e.g. namespace, accounts, roles, bindings, configmaps).
- Operator controller manager service.
- Operator webhook service.
- Deployment with containers kube-rbac-proxy & manager.
MutatingWebhookConfiguration
(configures webhooks to call the webhook service).
Prerequisite: the release and certificates have been deployed as outlined above.
Deploying a flag consuming application requires (at minimum) the creation of the following 2 resources (an example can be found here):
This is a CustomResourceDefinition
which contains the feature flags specification and a name of the spec.
This is a kubernetes primitive for deploying an application. The metadata annotations must include openfeature.dev/featureflagconfiguration
with the value set as the name of the FeatureFlagConfiguration
created in the step prior.
e.g.
metadata:
annotations:
openfeature.dev/featureflagconfiguration: "demo"
As per the issue here
As per v0.1.1, the default sync provider has been optimized as per this OpenFeature Enhancement Proposal issue.
High level architecture is as follows:
The Kubernetes resources created by OpenFeature Operator are under the open-feature-operator-system
namespace. This means
any resources that want to communicate with the OFO system (e.g. an application calling flag evaluations) must fall under
this namespace.
OpenFeature Operator is a server that communicates with Kubernetes components within the cluster, as such it requires a means of authorizing requests between peers. Cert manager handles the authorization by adding certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.
When wishing to leverage feature flagging within the local pod, the following steps are required:
- Create a new feature flag custom resource.
See here for additional custom resource parameters
apiVersion: core.openfeature.dev/v1alpha1
kind: FeatureFlagConfiguration
metadata:
name: featureflagconfiguration-sample
spec:
featureFlagSpec: |
{
"flags": {
"foo": {
"state": "ENABLED",
"variants": {
"bar": "BAR",
"baz": "BAZ"
},
"defaultVariant": "bar",
"targeting": {}
}
}
}
- Reference the CR within the pod spec annotations
apiVersion: v1
kind: Pod
metadata:
name: nginx
annotations:
openfeature.dev: "enabled"
openfeature.dev/featureflagconfiguration: "featureflagconfiguration-sample"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- Example usage from host container
root@nginx:/# curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"foo","context":{}}' -H "Content-Type: application/json"
{"value":"BAR","reason":"DEFAULT","variant":"bar"}
- Create a local cluster with MicroK8s or Kind (forward requests from your localhost:30000 to your cluster, see MicroK8s/Kind doc)
IMG=ghcr.io/open-feature/open-feature-operator:main make deploy-operator
- Apply the end-to-end example:
kubectl -n open-feature-operator-system apply -f config/samples/end-to-end.yaml
- Visit
http://localhost:30000/
- Update the value of the
defaultVariant
field in the custom resource instance inconfig/samples/end-to-end.yaml
and re-apply to update the flag value! - Visit
http://localhost:30000/
and see the change!
This repo uses Release Please to release packages. Release Please sets up a running PR that tracks all changes for the library components, and maintains the versions according to conventional commits, generated when PRs are merged. When Release Please's running PR is merged, any changed artifacts are published.