Install ctrl
This page shows how to install and initialize ctrl on a host and issue the first Operator enrollment key.
Run the following commands in the verified release set directory, adjusting the version number to match.
1. Install the package and write the configuration
sudo apt-get install ./kibotos-ctrl_1.2.3_amd64.deb
sudo install -o kibotos-ctrl -g kibotos-ctrl -m 0600 \
/usr/share/doc/kibotos-ctrl/ctrl.example.toml /etc/kibotos/ctrl/config.toml
sudoedit /etc/kibotos/ctrl/config.tomlIn the configuration, fill in the database, the artifact store, identity.host, and the data-plane names. For every table and key, see ctrl configuration.
Notes:
- Only
kibotos-ctrlmay read the configuration file. When you usedsn_file, that file must also be readable by this account. - To provide E2B sandbox metrics, fill in the
[metrics]section here as well. See Configuring ctrl. - To export ctrl's own metrics and cluster status, fill in the
[telemetry]section. See Listener in Cluster and service metrics. It is unrelated to[metrics]. - The state directory is fixed at
/var/lib/kibotos/ctrl, and the service can write only to this directory. - The package only creates the account and directories and reloads systemd. Initialization, migration, enabling, and starting are done in the steps below.
Connecting to the database
database.dsn can point to the primary itself, or to a connection proxy or connection pool, as long as all reads and writes reach the primary.
| Address | Usable | What to watch for |
|---|---|---|
| The primary itself, or a high-availability address that points to the new primary on failover | Yes | |
| A cloud database's connection proxy, for example Amazon RDS Proxy | Yes | |
A cloud database's read/write splitting address, for example the database proxy address of Alibaba Cloud RDS (the hostname usually contains rwlb) | Only when the read weight of the read-only instances is 0 | Not usable when reads go to read-only instances: ctrl must read the data it has just written, and a lagging read-only instance makes it decide on old state |
| PgBouncer in session mode | Yes | |
| PgBouncer in transaction mode | Yes | Requires version 1.21 or later with max_prepared_statements greater than 0. The DSN cannot carry connection parameters such as search_path |
| A read replica | No |
A proxy or pool affects only performance. Only one ctrl executes, which a row in the database guarantees independently of connections and database sessions. A second ctrl on the same database only answers reads. See Execution ownership.
kibotos-ctrl migrate must connect to the primary directly. The migration tool uses a session-level lock to keep two migrations from running at the same time, and a transaction-level pool leaves that lock on a session that another client uses. For migration, use a configuration file whose database.dsn points to the primary. Other commands are not subject to this restriction.
A database failover invalidates the prepared statements on a connection. Behind a proxy, ctrl's connections are not dropped; each connection fails at most once before it is replaced, and callers see a retryable error.
To check that the DSN reaches the primary, run this a few times. The first column must be f every time:
psql "$DSN" -Atc 'select pg_is_in_recovery()'Number of database connections
At runtime, ctrl uses at most database.max_connections PostgreSQL connections, 32 by default. PostgreSQL's max_connections must accommodate this number, plus other clients and a few short-lived connections from one-off kibotos-ctrl commands (migration, issuing enrollment keys, and so on).
| Setting | Default | Meaning |
|---|---|---|
workspace.execution_concurrency | 16 | The number of Workspace commands running at the same time across all nodes. Create, start, and Transfer restore form one group, and stop, delete, and data-plane revocation form another; each group counts against this number separately. Transfer export and import form one group, and storage object moves form another; each counts against half this number (at least 1) |
database.max_connections | 32 | The total number of connections ctrl uses. It cannot be less than 8 |
- A running command holds a connection only while it reads or writes the database, so raising
execution_concurrencydoes not require more connections. - When
kibotos_ctrl_db_acquire_waits_totalkeeps growing and requests slow down, raisemax_connections. - The connection limit can be set only in
database.max_connections.pool_max_connsin the DSN is rejected. - At startup, ctrl logs a
database connectionsline giving the actual concurrency and connection limit.
2. Prepare the bucket and permissions
Before starting ctrl, the storage administrator creates the bucket named in the configuration and grants access to ctrl's runtime identity.
- For the required permissions (object read and write, delete, multipart upload, and listing by prefix), see the example policy. When deploying, replace the resources with the actual bucket and namespace. Automatic object storage reclamation needs the delete permission.
- The permissions cover two prefixes:
kibotos-template/v1/<namespace>/holds Template artifacts, andkibotos-transfer/v1/<namespace>/holds Transfer archives. - Create the bucket with a separate administrative identity. Do not put administrative credentials in the ctrl configuration.
- Transfer archives are data from user Volumes. Enable encryption at rest and access auditing on the bucket, and restrict the identities that can read it to ctrl's runtime identity.
Every time ctrl starts, it checks that storage is usable: before opening the API and starting background tasks, it uses the runtime identity to write one small random object under kibotos-template/v1/<namespace>/staging/ and then one under kibotos-transfer/v1/<namespace>/, reads each back to verify it, and deletes it. The whole check is limited to 10 seconds.
- If any step fails, ctrl does not start. The
operationfield in the journal tells whether the failure was in writing, reading, verifying, or deleting. Thereasonfield distinguishes a missing bucket, insufficient permissions, a configuration error, and unreachable storage, and gives a suggested fix. - The check uses only object permissions on these two prefixes. It does not create a bucket or start a multipart upload.
- When the check fails, it tries to delete the objects it wrote. On a timeout or without delete permission, small objects may be left behind; configure a lifecycle rule on the staging prefix to reclaim them.
- This check proves only that basic reads and writes work. Capabilities such as multipart upload are verified the first time a Template is published.
- Publishing failures at runtime are logged in the journal with the stage and the command/session identifiers. Transient storage failures do not make a running ctrl exit.
Stores without S3 conditional writes or additional checksums, such as Alibaba Cloud OSS, also work: ctrl switches to the OSS no-overwrite header and verifies each published blob by reading it back, which costs one extra transfer per blob between storage and ctrl.
Alibaba Cloud OSS supports only virtual-hosted addressing. In the configuration, set path_style = false, use the regional domain without the bucket as endpoint (such as oss-cn-shenzhen.aliyuncs.com), and fill in bucket separately.
3. Initialize, issue the first Operator enrollment key, and start
umask 077
sudo -u kibotos-ctrl kibotos-ctrl init --config /etc/kibotos/ctrl/config.toml
sudo -u kibotos-ctrl kibotos-ctrl migrate --config /etc/kibotos/ctrl/config.toml
sudo -u kibotos-ctrl kibotos-ctrl enrollment create \
--config /etc/kibotos/ctrl/config.toml --operator operator-a \
--output /var/lib/kibotos/ctrl/operator-enrollment.key
sudo systemctl enable --now kibotos-ctrl.service
sudo journalctl -u kibotos-ctrl.service --no-pager -n 50- Run all three
kibotos-ctrlcommands as the service account withsudo -u kibotos-ctrl. Plainsudocreatespki/as root, the service account cannot enter it, and the service fails at startup withload managed PKI state: ... permission denied. Wheninitfinds that the state directory does not belong to the current account, it refuses and tells you which account to rerun it as. If you already created it as root, hand it back withsudo chown -R kibotos-ctrl:kibotos-ctrl /var/lib/kibotos/ctrl/pki, then runinitonce more as the service account. initcan be run repeatedly. When already initialized, it printsunchanged. If any step fails, resolve the error before continuing.- At boot, PostgreSQL may become ready later than ctrl, for example when the database runs in a local container. When ctrl cannot connect to the database, it exits, and systemd restarts it every 5 seconds until the database is available. This interval does not hit systemd's default start limit (5 starts within 10 seconds), so no manual
reset-failedis needed. The log repeatedly showsconnect ctrl PostgreSQL: ... connection refused, which stops once the database is ready. - When the database stays unavailable, ctrl keeps retrying. To have ctrl start only after the database service is ready, use
systemctl edit kibotos-ctrl.serviceto addAfter=andWants=for that service. - The
kibotos-ctrlaccount writes the enrollment key to its own state directory with mode0600. The administrator reads it and hands it to the Operator over a secure channel; there is no need to loosen the file permissions. - For PKI renewal and recovery, see Identity, configuration, and connections.
Warning
The first time serve starts, it creates credential-keys/ under storage.root. The keys in it encrypt the caller credentials stored in the database (such as Egress usernames and passwords). They are not in the database, so back them up together with pki/. If they are lost, those credentials cannot be decrypted, and only callers can write them again.
Automatic object storage reclamation
Ten minutes after it starts, ctrl begins reclaiming object storage automatically, and repeats every 24 hours. It deletes only manifests and blobs that meet all conditions: withdrawn more than 7 days ago, and no Workspace, retention period, or unwithdrawn revision in the catalog still references them.
For reclamation records, manual planning and execution, and excluding a Launch from reclamation, see Artifact reclamation.
Next steps: enroll an Operator
On their own workstation, the Operator uses this key to set up the kibo connection configuration, then issues an enrollment key for each node. For the steps, see Operator setup and node enrollment.
The node-enrollment.key used in Install node comes from that step.