Stellar Control is a handful of stateless services around one NATS server with JetStream. The same parts make every deployment, from a test laptop without network to a platform in the cloud serving benches on several sites: what changes is where each part runs and which networks the traffic crosses.
Choosing#
| If you… | Choose |
|---|---|
| Try Stellar Control, or run a demonstration on one machine | Docker: NATS and stellar-control in two containers |
| Run a small, lasting installation on one host (a lab, a test bench, a laptop) | Docker Compose: one file, NATS with a volume, the configuration published at start |
| Prepare procedures without any infrastructure | Dry runs (stellar run --dry), see Simulated Targets |
| Already run HashiCorp Nomad, or host several isolated installations on one platform | Nomad, with the job files delivered by Stellar Systems |
| Already run Kubernetes | Kubernetes |
| Cannot run containers (a qualified host, a certified image of the operating system) | The binaries, under systemd |
| Have benches, gateways or drivers on a network that only lets HTTPS out | Any of the above, with the NATS WebSocket open on 443 |
What to run#
| Part | What it is | Where it runs |
|---|---|---|
| The core | The services stellar-reconciler, stellar-compute, stellar-executor, stellar-api, stellar-alarms, stellar-scheduler, stellar-transfers, and stellar-editor optionally; or all of them in one process, stellar-control | Next to NATS, on a network of its own. See Running the Services |
| NATS with JetStream | The message bus and the only state of the platform (streams, KV buckets, object stores): back it up and you back up Stellar Control | Next to the core; its client port stays private, only the leaf node and WebSocket ports, with TLS, face other networks. See NATS and JetStream |
| The edges | Drivers, transports, gateways and connectors built with the SDKs, and the simulator stellar-simulator | Where the hardware is: a bench, an EGSE, a ground station, a partner; anywhere for the simulators and connectors. They only make outgoing connections to NATS |
| The web console | A static web application | Served by the API itself (api.web_dir), on the port of the API (8080) |
| The CLI | stellar: compiles and publishes the configuration, sends telecommands, runs procedures | On the workstations of the operators and in CI; it talks to the API over HTTP(S), and to NATS for stellar compile --publish and stellar sim |
Two rules hold in every topology:
- Every connection to NATS goes out from its client. The core, the edges and the CLI connect to NATS; NATS connects to nothing (but to the hub, from a leaf node). A bench needs no inbound port.
- The configuration is published, not deployed. Each change of the configuration repository
is compiled and published with
stellar compile <repository> --publish <nats-url>, from a CI job, a workstation or a one-shot container; the services pick it up at their next safe point.
NATS URLs take four schemes, in the global configuration of the core (nats.url) as in the
environment of the edges (STELLAR_NATS_URL):
| Scheme | Port (usual) | Use |
|---|---|---|
nats:// | 4222 | Plain TCP, on a private network or a single host |
tls:// | 4222 | TCP with TLS, the default between hosts |
ws:// | the WebSocket port of NATS | WebSocket without TLS: tests only |
wss:// | 443 | WebSocket with TLS, through firewalls and proxies that only let HTTPS out |
Topologies#
100 % cloud#
Everything runs in a cloud (or a data centre): the core, NATS, the simulators and connectors. The operators reach the console through a reverse proxy over HTTPS. Suited to engineering phases on simulated targets, to training and to data processing.
Internet Cloud (private network)
┌───────────────────┐ HTTPS 443 ┌───────────────────────────────────────────────┐
│ browser, CLI │─────────────►│ reverse proxy ──► stellar-api :8080 │
└───────────────────┘ │ │ │
│ core services ──────┴──► NATS + JetStream :4222│
│ simulators, connectors ──┘ (private) │
└───────────────────────────────────────────────┘Hybrid: the core in the cloud, the benches on site#
The core and NATS run in the cloud; the gateways and drivers run on site, next to the benches and
the EGSE, and connect out to NATS over tls:// on 4222, or wss:// on 443 when the site only lets
HTTPS out. Each edge has the bootstrap credentials of the platform and gets its own JWT from the
reconciler (see NATS Accounts and Credentials).
Site (bench network) Cloud
┌──────────────────────┐ ┌────────────────────────────────┐
│ bench ◄─► gateway │ tls:// 4222 or │ NATS + JetStream ◄── core │
│ EGSE ◄─► driver │ wss:// 443 ─────► │ :4222, :443 (TLS) services │
│ (outgoing only) │ │ reverse proxy ──► stellar-api │
└──────────────────────┘ └────────────────────────────────┘
Operators: browser, CLI ─── HTTPS 443 ──────────────► reverse proxyA site with many edges can run a NATS leaf node of its own: the edges connect to it on the bench network, and only the leaf node crosses the firewall (see Edges behind a firewall).
On-premise#
Everything runs on the networks of the customer: the core and NATS on a server or a cluster of the IT department, the edges on the bench and test networks, routed to NATS through the internal firewalls. Nothing leaves the site; the images or binaries come from the delivery of Stellar Systems, kept in a local registry or repository.
Customer site
┌───────────────────────────────────────────────────────────────────────┐
│ Server network Bench / test networks │
│ ┌──────────────────────────┐ tls:// ┌───────────────────────────┐ │
│ │ NATS + JetStream :4222 │◄───────│ gateways, drivers, EGSE │ │
│ │ core services │ 4222 └───────────────────────────┘ │
│ │ stellar-api :8080 │◄─── HTTP(S) ─── operator workstations │
│ └──────────────────────────┘ (browser, CLI) │
│ local registry ── images / binaries of the delivery │
└───────────────────────────────────────────────────────────────────────┘Local, on an air-gapped test laptop#
One machine without network: NATS, stellar-control and the simulators of the configuration
repository, all on the loopback interface. Suited to preparing and checking procedures away from
the benches, to demonstrations, and to training. The images are loaded from files of the delivery
(docker load -i stellar-control-<version>.tar), or the binaries copied with a nats-server
binary; nothing is pulled.
Laptop (no network)
┌────────────────────────────────────────────────────────┐
│ NATS + JetStream 127.0.0.1:4222 │
│ ▲ ▲ │
│ │ │ │
│ stellar-control stellar-simulator │
│ :8080 ◄── browser, CLI (one per target) │
│ │
│ stellar run --dry (its own nats-server, ephemeral) │
└────────────────────────────────────────────────────────┘Docker Compose runs the first part in one command. Dry runs need neither of
them: stellar run --dry starts its own nats-server and the services it needs in its process,
on ephemeral simulated targets (see Dry runs).
Edges behind a firewall#
During integration, verification and validation (IVV), the benches often sit on a network of the customer, a test centre or a partner, behind a firewall that lets nothing in and only HTTPS out. The NATS server then opens its WebSocket port, with TLS, on 443 (or on the WebSocket port of the server, 8443 in the delivered NATS job, when 443 is taken), and the edges reach it there.
Two ways, both outgoing only from the bench network:
Bench network (outgoing HTTPS only) Firewall Platform
│
(a) every edge connects directly │
gateway ─┐ │
driver ─┼──── wss://nats.example.org:443 ──────┼────► NATS WebSocket :443 (TLS)
sim ─┘ │ │
│ NATS + JetStream ◄── core
(b) one leaf node on site │ ▲
gateway ─┐ │ │
driver ─┼─► nats-server (leaf node) ─ wss:// ──┼───────────┘
sim ─┘ nats://127.0.0.1:4222 443 │- (a) Direct. Each edge sets
STELLAR_NATS_URL=wss://nats.example.org:443, with its bootstrap credentials (STELLAR_NATS_CREDENTIALS) and, for a private CA,STELLAR_NATS_CA. The Rust SDK and the simulator speak WebSocket as they are; a component of the Python SDK needs theaiohttppackage installed beside it, which the NATS client uses forws://andwss://. Simplest with a few edges. - (b) Leaf node. A NATS server on the bench network connects to the platform as a leaf node,
over
wss://on 443, bound to the account of the platform; the edges connect to it on the local network. Only one connection crosses the firewall, whatever the number of edges. See the leaf node documentation of NATS for its configuration.
On the server side, the WebSocket and leaf node ports always use TLS:
websocket {
port: 8443 # published on 443
tls {
cert_file: /etc/nats/tls/server.pem
key_file: /etc/nats/tls/server-key.pem
}
}
leafnodes {
port: 7422
tls {
cert_file: /etc/nats/tls/server.pem
key_file: /etc/nats/tls/server-key.pem
ca_file: /etc/nats/tls/ca.pem
}
}The delivered Nomad job of NATS opens them with websocket_port and leafnode_port (see
Nomad). The client port 4222 stays on the private network. A proxy that inspects
TLS must let the WebSocket upgrade through, or be bypassed for the NATS host. See
TLS, Encryption and Secrets.
Through the binaries#
Stellar Systems delivers the binaries on request, for hosts that cannot run
containers: the services of the core, stellar-control, stellar-editor, the CLI stellar and
stellar-simulator, and the files of the web console. NATS comes from its own release
(nats-server 2.12). A supervisor runs each service and restarts it when it exits with 1 (see
Exit codes).
An outline with systemd, one unit per service (here the API), all reading one global configuration:
# /etc/systemd/system/stellar-api.service
[Unit]
Description=Stellar Control API
After=network-online.target nats-server.service
Wants=network-online.target
[Service]
User=stellar
Environment=STELLAR_CONFIG=/etc/stellar/stellar.yaml
Environment=STELLAR_INSTANCE=api-1
ExecStart=/usr/local/bin/stellar-api
Restart=on-failure
RestartSec=5s
# Stops on SIGTERM, within 2 s
TimeoutStopSec=10s
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.targetFor a small installation, a single unit runs stellar-control instead of one per service.
| Service | Needs |
|---|---|
| Every service | nats.url, and in production nats.credentials and nats.tls.ca; a metrics port of its own per host (observability.metrics_addr, 9100 by default) |
stellar-reconciler | reconciler.signing_key_file and reconciler.account, to issue the JWTs of the edges; the key readable by its user only |
stellar-api | api.listen (8080), api.web_dir (the files of the web console), the auth section with an identity provider, reconciler.signing_key_file and account; a reverse proxy in front for HTTPS |
stellar-editor | editor.repository (the Git remote of the configuration repository) and a writable editor.workdir (/var/lib/stellar/editor); the CLI stellar on its path (editor.cli) |
stellar-compute, stellar-executor, stellar-alarms, stellar-scheduler, stellar-transfers | NATS only |
stellar-control | All of the above, in one process (--without leaves services out) |
| Drivers, gateways, simulators | Their environment: STELLAR_NATS_URL, STELLAR_NATS_CREDENTIALS (bootstrap), STELLAR_NATS_CA; the simulator also STELLAR_REPOSITORY |
The keys are those of the Global Configuration. Publish the
configuration once NATS is up (stellar compile <repository> --publish <nats-url>), before or after
the services start.
In containers#
The image stellar-control, from the registry given with the delivery, holds every binary above
and the web console; NATS runs from its official image (nats:2.12). See
Docker for its content.
| Runtime | When to choose it | Page |
|---|---|---|
| Docker | A trial, a demonstration, a quick check of a delivery: a few docker run commands | Docker |
| Docker Compose | One host for good: a lab, a bench, an air-gapped laptop; one file, restarts and upgrades in one command | Docker Compose |
| Nomad | Several hosts or several isolated installations, with the job files and ACL policies delivered by Stellar Systems | Nomad |
| Kubernetes | Your organisation already runs Kubernetes and its tooling (ingress, secrets, monitoring) | Kubernetes |