propeller logo
k8s

Deployment

Configuration, installation, RBAC, and testing for the Propeller Kubernetes Operator.

Configuration

The operator is configured through command-line flags and one environment variable. There is no configuration file.

Environment Variables

VariableDefaultDescription
WATCH_NAMESPACE(all namespaces)When set, the operator only watches resources in this namespace. Leave unset to watch all namespaces.

MQTT Flags

FlagDefaultDescription
--mqtt-addressMQTT broker URL (required, e.g. tcp://mqtt:1883)
--domain-idSuperMQ domain ID (required)
--channel-idSuperMQ channel ID (required)
--client-idManager client ID for MQTT authentication (required)
--client-keyManager client key for MQTT authentication (required)
--mqtt-qos0MQTT QoS level (0–2)
--mqtt-timeout30sBroker operation timeout

Proplet Monitoring Flags

FlagDefaultDescription
--liveliness-interval10sHow often to check proplet heartbeat timestamps
--last-seen-threshold30sHow long without a heartbeat before marking a proplet Offline

Kubernetes Manager Flags

FlagDefaultDescription
--health-probe-bind-address:8081Address for /healthz and /readyz endpoints
--metrics-bind-address0Address for Prometheus metrics (0 disables)
--metrics-securetrueServe metrics over HTTPS
--metrics-cert-pathDirectory containing the metrics TLS certificate
--metrics-cert-nametls.crtMetrics certificate filename
--metrics-cert-keytls.keyMetrics key filename
--leader-electfalseEnable leader election for high-availability deployments
--enable-http2falseEnable HTTP/2 (disabled by default for security)
--webhook-cert-pathDirectory containing the webhook TLS certificate
--webhook-cert-nametls.crtWebhook certificate filename
--webhook-cert-keytls.keyWebhook key filename

Installing and Deploying

For a complete walkthrough of setting up the operator with SuperMQ and running a task, see the Kubernetes Operator Example.

Installing CRDs

cd propeller-k8s-operator
make install

This runs controller-gen to generate CRD manifests from the Go types, then applies them with kubectl via Kustomize.

Deploying the Controller

make deploy IMG=<your-registry>/propeller-k8s-operator:<tag>

This renders the full deployment manifest (controller Deployment, ClusterRole, ClusterRoleBinding, ServiceAccount, CRDs) via Kustomize and applies it. The operator namespace (propeller-k8s-operator-system) is created automatically.

For local development with k3d, build the image and import it directly into the cluster nodes before deploying (no registry required):

make docker-build IMG=propeller-k8s-operator:latest
k3d image import propeller-k8s-operator:latest -c k3s-default
make deploy IMG=propeller-k8s-operator:latest

Set imagePullPolicy: Never in config/manager/manager.yaml when using a locally-loaded image.

Running Locally

go run ./cmd/main.go \
  --mqtt-address="tcp://localhost:1883" \
  --domain-id="<domain-id>" \
  --channel-id="<channel-id>" \
  --client-id="<manager-client-id>" \
  --client-key="<manager-client-key>" \
  --metrics-secure=false

The operator uses the current kubectl context for cluster access.

RBAC

The operator requires a ClusterRole with the following permissions:

API GroupResourcesVerbs
"" (core)configmapscreate, delete, get, list, patch, update
"" (core)podsget, list
"" (core)secretsget
appsdeploymentscreate, delete, get, list, patch, update, watch
batchjobscreate, delete, get, list, patch, update, watch
propeller.propeller.abstractmachines.frtasks, proplets, propellerjobs, federatedjobs, trainingroundscreate, delete, get, list, patch, update, watch
propeller.propeller.abstractmachines.fr*/statusget, patch, update
propeller.propeller.abstractmachines.fr*/finalizersupdate

Container Security

When deployed in-cluster the manager pod runs with:

  • runAsNonRoot: true
  • seccompProfile: RuntimeDefault
  • readOnlyRootFilesystem: true
  • allowPrivilegeEscalation: false
  • All Linux capabilities dropped

Resource defaults: 10m CPU / 64Mi memory requests; 500m CPU / 128Mi limits.

Health Probes

EndpointPurpose
GET /healthzLiveness probe — confirms the process is alive
GET /readyzReadiness probe — confirms the controller manager is ready to serve

Both endpoints are served on --health-probe-bind-address (default :8081).

Testing

The operator includes a controller test suite that uses envtest to spin up a real Kubernetes API server and etcd in-process, with all five CRDs loaded from config/crd/bases.

make test

End-to-end tests run against a real cluster (Kind by default):

make setup-test-e2e   # creates a Kind cluster
make test-e2e         # runs Ginkgo e2e suite
make cleanup-test-e2e # tears down the Kind cluster

On this page