Installing in an Air-Gapped Environment¶
Use this installation process when your cluster cannot reach the internet. You mirror Sovereign Home Cloud's images from Solace's registry into a registry inside your network, then install the chart with every image pointed at that registry. Once installed, Sovereign Home Cloud needs nothing from the internet to start, onboard datacenters, and create and upgrade event broker services.
How you move images and the chart across the air gap is up to you: a registry replication tool, an image mirroring tool such as crane or skopeo, or exported archives carried in. This page lists what to mirror and how to install from it.
Prerequisites¶
| What | Details |
|---|---|
| Private registry | An OCI registry inside your network that the cluster nodes trust (its TLS chain installed on the nodes), holding the mirrored images and chart |
| Kubernetes cluster | A StorageClass that provisions ReadWriteOnce volumes, an ingress controller already running in the cluster, and the capacity in Compute Resources |
| Workstation | kubectl and helm 3, with network access to the private registry and the Kubernetes API |
| Event broker | A Solace event broker for the control plane's own messaging, with a message VPN, a client username and a SEMP administrator, serving TLS with a valid certificate for its hostname. You need one before you install; to run one in Kubernetes, use the Solace Event Broker Operator Quick Start, and mirror its images too. Or use the chart's embedded broker, at your own risk. |
| CA certificate and key | A CA, with its certificate and its private key, that signs your event broker services' certificates and that the control plane trusts. Every datacenter uses the same CA; see The CA Certificate. |
| Hostnames | One each for the Cloud Console and the Ops User Interface (UI), and optionally one for the API, with DNS records pointing at your ingress controller's address |
| TLS certificate | One certificate from your own PKI covering those hostnames |
| Data stores | Recommended: your own PostgreSQL, OpenSearch, Redis-compatible cache and S3-compatible object store, meeting the requirements in Before You Begin. OpenSearch and the cache take only a hostname and port: they are used without credentials. |
Plan Network Connectivity¶
Inbound¶
| From | To | Port |
|---|---|---|
| Users' browsers | The Cloud Console, Ops UI and API hostnames, through your ingress controller | 443 |
| Messaging applications | Each event broker service's client ports; see Event Broker Service Exposure | Per event broker service |
| Workstation | The Kubernetes API and the private registry | Your cluster's API port, and the registry's port |
| Cluster nodes | The private registry | The registry's port |
Outbound¶
None. A few calls can still be attempted; none is needed, and blocking them breaks nothing. Before You Begin lists them.
Mirror the Images¶
You must mirror the following from Solace's registry, registry.solace.com/solace/home-cloud-control-plane/<image>, into your private registry, keeping each image's name and tag:
| Image | Used by | Tag |
|---|---|---|
home-cloud-control-plane |
The control plane | Set by the chart version |
maas-cloud-agent-k8s |
Each datacenter's agent | Set by the chart version |
solace-pubsub-enterprise |
Event broker services | Every event broker version you create or upgrade event broker services with; see below |
solace-datadog-agent |
The monitoring sidecar in every event broker service pod | latest |
busybox |
Maintenance jobs that run before an event broker service upgrade | latest |
postgres |
Bundled PostgreSQL | Only if you bundle it |
opensearch |
Bundled OpenSearch | Only if you bundle it |
valkey |
Bundled cache | Only if you bundle it |
chrislusf/seaweedfs |
Bundled object store | Only if you bundle it |
Mirror the chart too: oci://registry.solace.com/solace/home-cloud-control-plane/charts/home-cloud-control-plane, at the version you install.
To print the exact image references for your values, render the chart on a machine that can reach Solace's registry:
helm template home-cloud-control-plane oci://registry.solace.com/solace/home-cloud-control-plane/charts/home-cloud-control-plane --version <chart version> -f values.local.yaml \
| grep -E '^\s+image:' | sort -u
The render does not include the event broker, sidecar and busybox images, because the datacenter agent pulls them only when it creates or upgrades an event broker service. Add them to your list yourself.
Event broker versions¶
Each Sovereign Home Cloud release offers a set of event broker versions. An event broker version's image tag is the version without its -<n> revision: for example, version 10.26.0.9054-18 uses solace-pubsub-enterprise:10.26.0.9054.
Mirror every version you create event broker services with, and every version you upgrade them to. If an image is missing, creating or upgrading an event broker service to that version fails with ImagePullBackOff.
Write Your Values File¶
Create one values file, for example values.local.yaml. It holds secrets, so keep it out of version control or encrypt it.
Point every image at your registry¶
Five values do this, and the chart refuses to install if only some of them are changed:
imageRegistry: <registry>
persistence-layer:
postgresql:
image:
registry: <registry>
seaweedfs:
image:
registry: <registry>
solace-cloud-ca:
image:
cloudAgent:
repository: <registry>/maas-cloud-agent-k8s
k8s:
imageRepository: <registry>
global:
imagePullSecrets:
- <pull secret name>
The pull secret holds your private registry's credentials.
Identity and secrets¶
global:
persistence:
storageClassName: "" # blank: the cluster's default StorageClass
namespaceId: <prefix> # always the same value as maasPrefix
maasPrefix: <prefix> # names your stored data; fixed at installation
organization:
operator:
username: <Ops UI administrator email>
password: <Ops UI administrator password>
secrets:
values:
VAULT_LOCAL_KEY: <64 hexadecimal characters> # openssl rand -hex 32
Warning! Keep the encryption key. VAULT_LOCAL_KEY encrypts sensitive values in the database. Losing it loses every value encrypted under it, even if the database survives. Store a copy outside the cluster.
The Ops UI administrator defaults to admin@company.com with the password admin; set your own.
Event broker for the control plane¶
Use your own event broker, or one the chart deploys for you.
Give the connection details of the event broker you are running. broker.enabled stays false, its default.
ivmr:
smfHost: tcps://broker.example.internal:55443
mgmtHost: https://broker.example.internal:943
msgVpn: <message VPN>
username: <client username>
mgmtUsername: <SEMP admin username>
secrets:
values:
EXTERNAL_IVMR_PASSWORD: <client password>
EXTERNAL_IVMR_MGMT_PASSWORD: <SEMP admin password>
Every datacenter connects to this event broker at the smfHost address, so it must be reachable from the control plane and from every datacenter.
The event broker must present a valid TLS certificate: unexpired, with the smfHost and mgmtHost hostname in its subject alternative names, and signed by a CA the control plane trusts. Sign it with the CA from The CA Certificate, or add the CA that signed it under Other private CAs. Every other client of the broker, such as the Event Management Agents, must trust that CA too.
The chart deploys a single-node event broker in the release's namespace and sets up the control plane's connection to it. Leave every ivmr.* value unset: the chart refuses them alongside the embedded event broker. It generates the event broker's passwords and keeps them across upgrades. It runs the solace-pubsub-enterprise image at the tag the chart sets, so mirror that tag too.
broker:
enabled: true
networkPolicy:
extraIngress: # admits the datacenter namespaces you label
- from:
- namespaceSelector:
matchLabels:
solace.com/home-cloud-mca: "true"
ports:
- { protocol: TCP, port: 55555 }
Warning! Use it at your own risk. The embedded event broker has no redundancy, so it is down while its pod restarts, and monitoring it is up to you. It speaks plain text, without TLS, and only clients inside the cluster can reach it.
Only datacenters in the same cluster can use it. When you onboard each datacenter, label its namespace so the event broker's NetworkPolicy admits it, and give its agent the event broker's full in-cluster address; see step 5.
This is an installation-time choice. Moving the control plane to another event broker later, including from the embedded event broker to your own, is a reinstall, not an upgrade.
Hostnames and TLS¶
ingress:
enabled: true
className: <ingress class> # blank: the cluster's default IngressClass
consoleHost: console.example.internal
opsHost: ops.example.internal
apiHost: api.example.internal # optional
tls:
- secretName: home-cloud-control-plane-tls
hosts: [console.example.internal, ops.example.internal, api.example.internal]
Every hostname must be covered by the certificate. Renewing it is your responsibility.
Your own data stores¶
For each data store you run yourself, turn off the bundled one and give its endpoint:
persistence-layer:
postgresql:
enabled: false
seaweedfs:
enabled: false
dataLayer:
opensearch:
enabled: false
redis:
enabled: false
external:
postgresHost: pg.example.internal
postgresPort: 5432
postgresUsername: hosted_fleet
opensearchHost: search.example.internal
opensearchPort: 443
opensearchProtocol: https
redisHost: cache.example.internal
redisPort: 6379
objectStorage:
enabled: false
bucket: <bucket>
region: <region>
external:
endpoint: https://s3.example.internal
forcePathStyle: true
secrets:
values:
HOSTED_FLEET_POSTGRES_PASSWORD: <password>
HOSTED_FLEET_S3_ACCESS_KEY: <access key>
HOSTED_FLEET_S3_SECRET_KEY: <secret key>
OpenSearch and the cache are used without credentials, so restrict access to them by network. Installing for Production has the details of each block.
No datacenter or organization at installation¶
The installation creates no datacenter and no Cloud Console organization. After you install, the Ops UI administrator creates the organizations and their users (Administering with the Ops UI), then onboards each datacenter (Onboarding a Datacenter). Point each datacenter's event broker images at your private registry when you do.
The CA Certificate¶
One CA serves the whole installation: each datacenter's agent signs event broker service certificates with it, so it needs the CA's certificate and private key, and the control plane trusts it, so it needs only the certificate.
The CA must use an RSA key, be marked CA:TRUE, and have at least seven days of validity left. Use an intermediate CA dedicated to event broker services, not your root.
-
Get the CA's certificate as
ca.crtand its private key asca.key, in PKCS#8 format.To use an existing CA, export its certificate, followed by its chain, and its private key.
To create a new CA instead:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \ -subj "/CN=Broker Issuing CA" \ -addext "basicConstraints=critical,CA:TRUE" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -keyout ca.key -out ca.crtThis writes the key in PKCS#8 format and a certificate valid for 10 years (
-days 3650). Event broker service certificates never outlive the CA, so plan to replace it before then. -
Encrypt the key. This is optional and recommended: anyone who has
ca.keycan issue certificates your clients trust.openssl pkcs8 -topk8 -v2 aes-256-cbc -in ca.key -out ca.enc.key -passout pass:"$PASSPHRASE" -
Create the Secret, after the namespace exists (see Deploy):
kubectl create secret generic broker-issuing-ca -n home-cloud-control-plane \ --from-file=ca.crt=ca.crt \ --from-file=ca.key=ca.enc.key \ --from-file=passphrase=<(printf '%s' "$PASSPHRASE")For an unencrypted key, use
--from-file=ca.key=ca.keyand leave outpassphrase. -
Add to your values file, so the control plane trusts only the certificate:
composite: trustedCA: existingSecret: broker-issuing-ca keys: [ca.crt]
If your data stores or your event broker service present certificates from another private CA, add it under composite.trustedCA.certificates; see Other private CAs.
Deploy¶
-
Create the namespace, the pull secret for your private registry, the TLS Secret and the CA Secret:
kubectl create namespace home-cloud-control-plane kubectl create secret docker-registry <pull secret name> -n home-cloud-control-plane \ --docker-server=<registry> --docker-username=<username> --docker-password=<password> kubectl create secret tls home-cloud-control-plane-tls -n home-cloud-control-plane \ --cert=<chain.pem> --key=<key.pem> -
Check the values against the cluster without installing anything:
helm install home-cloud-control-plane <chart in your registry> --version <chart version> -n home-cloud-control-plane \ -f values.local.yaml --dry-run=server -
Install:
helm install home-cloud-control-plane <chart in your registry> --version <chart version> -n home-cloud-control-plane \ -f values.local.yaml --wait --timeout 30mThe installation waits for the control plane's first start, which can take several minutes.
Verify the Deployment¶
-
Every pod is running, and every image comes from your registry:
kubectl get pods -n home-cloud-control-plane kubectl get pods -n home-cloud-control-plane -o jsonpath='{..image}' | tr ' ' '\n' | sort -u -
Sign in to the Ops UI at its hostname as the Ops UI administrator.
An ImagePullBackOff names the missing image. Either it was not mirrored, or one of the five registry values still points elsewhere.
Next Steps¶
- Onboarding a Datacenter: create organizations and users, then add a datacenter for your event broker services.
- Upgrading: mirror the new chart version and its images, including any new event broker versions, before you upgrade.
- Troubleshooting Your Installation.