A Kubernetes operator for managing middleware updates for serverless functions deployed with the func CLI. This operator monitors deployed functions and automatically rebuilds them when outdated middleware is detected, ensuring functions stay up-to-date with the latest middleware versions.
- Kubernetes cluster (1.31+)
- Knative Serving installed
- Tekton Pipelines installed
- Container registry for storing function images
Deploy the operator to your cluster:
kubectl apply -f https://github.com/functions-dev/func-operator/releases/latest/download/func-operator.yamlCreate a Function custom resource to register an existing function for middleware monitoring and updates:
apiVersion: functions.dev/v1alpha1
kind: Function
metadata:
name: my-function
namespace: default
spec:
repository:
url: https://github.com/your-org/your-function.git
authSecretRef:
name: git-credentials
registry:
authSecretRef:
name: registry-credentialsApply the resource:
kubectl apply -f function.yamlNote: This registers an existing function with the operator for middleware management. To initially deploy a function, use the func CLI directly:
func deploy --path <function-path> --registry <registry-path>For private registries, create a secret with registry credentials:
apiVersion: v1
kind: Secret
metadata:
name: registry-credentials
namespace: default
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-docker-config>Or use kubectl:
kubectl create secret docker-registry registry-credentials \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<email>For private Git repositories, create a secret with the Git credentials:
apiVersion: v1
kind: Secret
metadata:
name: git-credentials
namespace: default
data:
token: <base64-encoded-access-token>or
apiVersion: v1
kind: Secret
metadata:
name: git-credentials
namespace: default
data:
username: <base64-encoded-username>
password: <base64-encoded-password>Then reference it in the Function under .spec.repository.authSecretRef.name
apiVersion: functions.dev/v1alpha1
kind: Function
metadata:
name: my-function
namespace: default
spec:
repository:
url: https://github.com/your-org/your-function.git
authSecretRef:
name: git-credentialsView the middleware status of your function:
kubectl get function my-function -o yamlThe status will include:
- Function name and runtime
- Middleware update conditions
- Whether the function needs rebuilding due to outdated middleware
For functions located in a subdirectory of a repository (e.g., in a monorepo), use the repository.path field to specify the path to your function:
apiVersion: functions.dev/v1alpha1
kind: Function
metadata:
name: my-function
namespace: default
spec:
repository:
url: https://github.com/your-org/your-monorepo.git
path: functions/my-function
authSecretRef:
name: git-credentials
registry:
authSecretRef:
name: registry-credentialsThe operator will clone the repository and use the specified path as the function root directory.
For local development, you can use the provided script to set up a Kind cluster with all prerequisites:
./hack/create-kind-cluster.shThis script will:
- Create a local Kind cluster with multiple worker nodes
- Set up a local container registry on
localhost:5001 - Install Tekton Pipelines
- Install Knative Serving with Kourier
- Configure the cluster to use the local registry
make docker-build IMG=<your-registry>/func-operator:latest
make deploy IMG=<your-registry>/func-operator:latestFor debugging the operator with Delve, use the debug targets:
# Build the debug image (includes Delve debugger and debug symbols)
make docker-build-debugger IMAGE_TAG_BASE=<your-registry>/func-operator
# Push the debug image
make docker-push-debugger IMAGE_TAG_BASE=<your-registry>/func-operator
# Deploy the operator in debug mode
make deploy-debugger IMAGE_TAG_BASE=<your-registry>/func-operatorThe debug deployment runs the operator under Delve in headless mode, listening on port 40000. To connect your debugger:
# Port-forward to access the debugger
kubectl port-forward -n func-operator-system deployment/func-operator-controller-manager 40000:40000
# Connect with Delve CLI
dlv connect localhost:40000You can also connect using your IDE's remote debugging features (VS Code, GoLand, etc.) by configuring it to connect to localhost:40000.
# Unit tests
make test
# E2E tests (requires Kind cluster with Gitea)
make create-kind-cluster # Sets up cluster with Gitea
make test-e2e
# Bundle tests
make test-e2e-bundleE2E tests use an in-cluster Gitea instance instead of GitHub, providing complete test isolation. See Gitea Integration for details on the test infrastructure.
# Run linter
make lint| Field | Type | Required | Description |
|---|---|---|---|
repository.url |
string | Yes | URL of the Git repository containing the function |
repository.branch |
string | No | Branch of the repository |
repository.path |
string | No | Path to the function inside the repository. Defaults to "." |
repository.authSecretRef |
object | No | Reference to the auth secret for private repository authentication |
registry.authSecretRef |
object | No | Reference to the secret containing credentials for registry authentication |
autoUpdateMiddleware |
boolean | No | Defines if the operator should rebuild when outdated middleware is detected. Defaults to global operator config |
| Field | Type | Description |
|---|---|---|
name |
string | Function name from metadata |
runtime |
string | Detected function runtime |
conditions |
array | Status conditions |
Remove the operator and CRDs:
# Undeploy operator
make undeploy
# Uninstall CRDs
make uninstall