Manager Flags¶
The CAPTF manager is the manager binary in the manager container of the captf-controller-manager Deployment. It takes every setting as a command-line flag; it has no configuration file, and it reads only two settings from the environment (see Environment variables). The flags follow the conventions of kube-controller-manager and the CAPI core providers. A flag accepts --name=value or --name value, and underscores in place of dashes (--leader_elect is --leader-elect). Durations are Go duration strings such as 30m, 90s or 1h30m.
For what each group of flags changes in practice, see Configuration. This page is the complete list.
Set a flag¶
The shipped Deployment sets its arguments in config/manager/manager.yaml in the provider repository. clusterctl init installs that manifest, and there are no clusterctl variables for the manager’s arguments, so you change a flag by editing the args of the manager container on the live Deployment, or in a kustomize overlay over the released manifest.
apiVersion: apps/v1
kind: Deployment
metadata:
name: captf-controller-manager
namespace: captf-system
spec:
template:
spec:
containers:
- name: manager
args:
- --leader-elect
- --diagnostics-address=:8443
- --insecure-diagnostics=false
- --webhook-port=9443
- --terraformcluster-concurrency=20
- --drift-default-interval=1h
The first four arguments are the shipped ones; the highlighted two are additions. The manager logs every parsed flag once at start, one FLAG: --name="value" line each, and refuses to start on a value it cannot run with: a concurrency below 1, a --sync-period or --drift-default-interval that is not positive, a negative --state-backups, or no valid runner image.
A strategic-merge patch that adds one flag drops the others
args is a plain list, so a strategic-merge patch replaces the whole list. Add a flag with a JSON patch, or patch the full list. Either way, a hand-patched flag does not survive clusterctl upgrade apply unless you reapply it. Changing a flag has the commands.
The flags you are most likely to change¶
| Flag | Default | Change it to |
|---|---|---|
--leader-elect | false (set by the shipped manifest) | Keep it on whenever more than one replica can run. |
--runner-image | the manager’s own image | Pin or mirror the image that supplies the runner binary to every Job. |
--watch-filter | empty | Share one management cluster between provider instances. |
--namespace | empty (all namespaces) | Confine the manager to one namespace. |
--drift-default-interval | 30m | Move the fleet-wide drift cadence. |
--state-backups | 5 | Keep fewer or more state backups, or none. |
--runner-events | true | Turn off runner progress events on a busy cluster. |
--terraformcluster-concurrency and its three siblings | 10 | Raise a kind’s parallelism when its objects queue. |
--cluster-operation-gate | true | Allow a cluster’s operation and its machines’ to overlap. |
--tls-min-version | VersionTLS12 | Raise the TLS floor to VersionTLS13. |
-v, --v | 2 | Raise verbosity while diagnosing, then lower it again. |
CAPTF¶
These flags set how the manager runs Jobs and what it keeps around them.
| Flag | Type | Default | What it does |
|---|---|---|---|
--cluster-operation-gate | bool | true | Keeps a TerraformCluster’s apply, destroy or restore from running at the same time as its machines’ operations, through a per-Cluster write Lease. The per-object run Lease that stops two Jobs for one object is always on. Turn the gate off only if you accept those overlapping. |
--drift-default-interval | duration | 30m | The drift check interval an object falls back to when neither it nor its cluster’s defaults set one. Must be positive. A machine pool whose own or inherited interval is 0 also uses it, since pool drift cannot be disabled. |
--runner-events | bool | true | Has each Job’s runner post progress events (RunStarted, Step*, PlanSummary, ResourcesChanged, RunFinished) on the owning Terraform* object. Emission is best effort and never fails a run. Needs create on events in the runner ClusterRole. Turn it off to cut event volume. |
--runner-image | string | $CAPTF_MANAGER_IMAGE | The image of the init container that copies the runner binary into every Job. It must contain /runner, which means a CAPTF manager or runner image, never a module image. Unset, it takes the manager’s own image. The manager refuses to start when this is empty or not a valid image reference. |
--state-backups | int | 5 | How many state backups to keep per object. Each new state serial is copied into captf-state-backup-* Secrets, and older copies are pruned. 0 takes no new backups; existing ones stay and can still be restored. Must not be negative. |
Controllers and concurrency¶
These flags choose what the manager watches and how many objects it reconciles at once.
| Flag | Type | Default | What it does |
|---|---|---|---|
--namespace | string | empty | Restricts the manager to one namespace. Empty watches all, which is what clusterctl init installs. A manager watches one namespace or all of them, never a chosen set. TerraformClusterIdentity is cluster-scoped and is watched everywhere regardless. |
--sync-period | duration | 10m | The minimum interval at which the informers re-enqueue every cached object, on top of event-driven reconciles. Also the interval of the orphan sweep. It reads the local cache only and does not set the drift or health cadence. Must be positive. |
--terraformcluster-concurrency | int | 10 | How many TerraformCluster objects reconcile at once. Must be at least 1. |
--terraformmachine-concurrency | int | 10 | How many TerraformMachine objects reconcile at once. Must be at least 1. |
--terraformmachinepool-concurrency | int | 10 | How many TerraformMachinePool objects reconcile at once. Must be at least 1. |
--terraformmachinetemplate-concurrency | int | 10 | How many TerraformMachineTemplate objects reconcile at once. Must be at least 1. |
--watch-filter | string | empty | Reconcile only objects labeled cluster.x-k8s.io/watch-filter with this value. Empty reconciles every object the manager can see. The label key is fixed. |
A reconcile is a handful of API reads and a status patch, and mostly waits on a Job, so a higher concurrency rarely costs much CPU. Lower it to soften bursts against a small API server. The admission webhooks serve every namespace whatever --namespace and --watch-filter say, so an object the manager does not watch is admitted and then never reconciled. Namespace scoping and --watch-filter explains the trade-offs.
Leader election¶
Leader election makes sure one manager reconciles at a time. The Lease is named controller-leader-election-captf and is not parameterized.
| Flag | Type | Default | What it does |
|---|---|---|---|
--leader-elect | bool | false | Turns leader election on. Enable it whenever more than one replica can run, including during a rolling update. The shipped manifest sets it. |
--leader-elect-lease-duration | duration | 15s | How long a non-leader candidate waits before it forces leadership. |
--leader-elect-renew-deadline | duration | 10s | How long the leader keeps retrying to renew before it gives up leadership. |
--leader-elect-retry-period | duration | 2s | How long a candidate waits between attempts. |
The defaults match kube-controller-manager and rarely need changing. Lower them to replace a crashed leader faster, at the cost of more Lease traffic.
Webhooks¶
The webhook server hosts the validating webhooks. cert-manager issues its serving certificate, and the Deployment mounts the Secret into the manager pod.
| Flag | Type | Default | What it does |
|---|---|---|---|
--webhook-cert-dir | string | /tmp/k8s-webhook-server/serving-certs/ | The directory that holds the serving certificate and key. |
--webhook-cert-name | string | tls.crt | The certificate’s file name in that directory. |
--webhook-key-name | string | tls.key | The key’s file name in that directory. |
--webhook-port | int | 9443 | The port the webhook server listens on. The shipped manifest sets 9443; the webhook Service targets it, so change both together. |
The shipped manifests wire these together. You change them only for a custom certificate layout.
Diagnostics and TLS (CAPI)¶
These flags come from Cluster API’s shared manager options and behave as they do in the CAPI core providers. The diagnostics endpoint serves Prometheus metrics over HTTPS, authenticated and authorized against the API server. See Observability for what it serves.
| Flag | Type | Default | What it does |
|---|---|---|---|
--diagnostics-address | string | :8443 | The address the diagnostics endpoint binds to. With authentication on, it also serves the pprof endpoints and an endpoint that changes the log level at run time. |
--insecure-diagnostics | bool | false | Serves diagnostics over plain HTTP with no authentication or authorization, and without the pprof and log-level endpoints. For local development only. |
--tls-cipher-suites | stringSlice | empty | A comma-separated list of cipher suites for the webhook server and the metrics server (the latter only when diagnostics are secure). Empty uses Go’s defaults. The flag’s help text lists the preferred and the insecure names. |
--tls-curve-preferences | int32Slice | empty | A comma-separated list of numeric Go crypto/tls CurveID values to allow as key exchange mechanisms. The order is ignored. Empty uses Go’s defaults. The supported values depend on the Go version. |
--tls-min-version | string | VersionTLS12 | The minimum TLS version of the webhook and metrics servers: VersionTLS10, VersionTLS11, VersionTLS12 or VersionTLS13. |
--insecure-diagnostics removes authentication from the metrics endpoint
Anything that can reach the address then reads the metrics with no token. Use it on a workstation, never on a cluster others can reach.
Logging¶
The logging flags are the Kubernetes component-base set. The manager runs at verbosity 2, where the usual reconcile flow is visible. Credentials, bootstrap data, tfvars content and output values are never logged, whatever the level.
| Flag | Type | Default | What it does |
|---|---|---|---|
--feature-gates | mapStringBool | empty | A comma-separated Key=value list. Only the logging gates in Feature gates exist. |
--log-flush-frequency | duration | 5s | The longest interval between log flushes. |
--log-json-info-buffer-size | quantity | 0 | Alpha. Buffers info messages in the JSON format with split streams, to increase performance. 0 disables buffering. Takes 512, 1K, 2Ki and the like. Needs LoggingAlphaOptions. |
--log-json-split-stream | bool | false | Alpha. In the JSON format, writes errors to stderr and info messages to stdout, instead of one stream to stdout. Needs LoggingAlphaOptions. |
--log-text-info-buffer-size | quantity | 0 | Alpha. The same buffering for the text format with split streams. Needs LoggingAlphaOptions. |
--log-text-split-stream | bool | false | Alpha. In the text format, writes errors to stderr and info messages to stdout. Needs LoggingAlphaOptions. |
--logging-format | string | text | The log format: text or json. json is gated by LoggingBetaOptions, which is on by default. |
-v, --v | Level | 2 | The log verbosity. Raise it while you diagnose a problem and lower it afterward, since higher levels log more of each reconcile. |
--vmodule | pattern=N,... | empty | Per-file verbosity overrides, such as reconcile*=4. Works only with the text format. |
To change the level of a running manager without a restart, use the authenticated diagnostics endpoint; see Logs and verbosity.
Other flags¶
| Flag | Type | Default | What it does |
|---|---|---|---|
--health-addr | string | :9440 | The address of the health endpoint that serves /healthz and /readyz. The Deployment’s probes target port 9440, so change both together. |
--kubeconfig | string | empty | The path to a kubeconfig. You need it only out of cluster. Without it, the manager uses $KUBECONFIG, then its in-cluster configuration. |
--profiler-address | string | empty | A bind address for a separate pprof profiler, such as localhost:6060. Empty leaves it off. Unrelated to the pprof endpoints on the diagnostics address. |
-h, --help | bool | false | Prints the flag help, grouped by section, and exits. |
--version | version | false | Prints version information and exits. --version=raw prints the raw build stamp. --version=vX.Y.Z sets the reported version instead. |
manager version prints the same line as manager --version and exits.
Feature gates¶
--feature-gates takes a comma-separated Key=value list, for example --feature-gates=LoggingAlphaOptions=true. CAPTF registers no feature gate of its own. The gates that exist are the component-base logging gates.
| Name | Default | Maturity |
|---|---|---|
AllAlpha | false | Alpha |
AllBeta | false | Beta |
ContextualLogging | true | Beta |
LoggingAlphaOptions | false | Alpha |
LoggingBetaOptions | true | Beta |
Environment variables¶
The manager reads these from its own environment. A custom Deployment or an overlay that replaces the container’s env must keep them.
| Variable | What it does |
|---|---|
CAPTF_MANAGER_IMAGE | The default of --runner-image. The shipped Deployment sets it to the manager’s own image, and clusterctl init replaces it with the release image. |
KUBECONFIG | Read by the --kubeconfig handling when the flag is not given. Only an out-of-cluster manager needs it. |
The manager also reads POD_NAMESPACE and SERVICE_ACCOUNT_NAME, which the shipped Deployment sets through the downward API. Without them the webhook cannot tell which ServiceAccount is the manager and refuses its providerID writes. See Manager environment.
Shipped arguments¶
config/manager/manager.yaml sets these arguments on the manager container. Every other flag keeps its default.
| Flag | Value |
|---|---|
--leader-elect | set |
--diagnostics-address | :8443 |
--insecure-diagnostics | false |
--webhook-port | 9443 |