Getting Started
A guided ~30-minute walkthrough from a fresh Ubuntu or Rocky VM to a
running Keystone Core single-node deployment with one applied state.
Uses the operator install path — apt install / dnf install of the
v0.1.x packages — and drives the system through kscorectl, the
operator CLI.
For the dense reference walkthrough (full package layout, postinst
behavior, filesystem map, port table, verification matrix), see
../runbooks/bootstrap-new-cluster.md
.
This guide is the friendlier first-time tour; the runbook is what you
reach for when you have to do this without thinking about it.
v0.1.x scope note. Until the v1.0 release ceremony,
.deb/.rpmpackages are operator-distributed rather than published to a public repo. Get the snapshot you’ve been sent onto the target host before you start.Single-node trial: this guide co-locates the server and a single agent on the same VM, with the agent talking to the embedded NATS inside the server. Real multi-host topologies put agents on the hosts they manage — covered in
../runbooks/bootstrap-new-cluster.md.
Prerequisites
- Fresh Ubuntu 22.04+ / 24.04, Debian 12, or Rocky 8 / 9 / 10 VM
(full validated matrix in
E2E-VM-TESTING.md). - Root or sudo access on the VM.
curlandjqfor the smoke checks:- Debian/Ubuntu:
sudo apt install -y curl jq - Rocky/RHEL:
sudo dnf install -y curl jq
- Debian/Ubuntu:
- The Keystone Core package snapshot for your distro family, copied
onto the host (three packages:
kscore-server,kscore-cli,kscore-agent).
1. Install
Pick the section for your distro family.
Debian / Ubuntu
sudo apt install -y ./kscore-server_*_linux_amd64.deb \
./kscore-cli_*_linux_amd64.deb \
./kscore-agent_*_linux_amd64.debRocky / RHEL
sudo dnf install -y ./kscore-server-*.x86_64.rpm \
./kscore-cli-*.x86_64.rpm \
./kscore-agent-*.x86_64.rpmWhat the kscore-server postinst does on a first install:
- Creates the
kscoresystem user + group (server runs unprivileged). - Lays down
/etc/kscore/(root:kscore0750),/var/lib/kscore/,/var/log/kscore/,/run/kscore/(eachkscore:kscore0750). - Renders
/etc/kscore/server.yamlwith a freshly generated HMAC secret unique to this host. daemon-reload,enable, andstartofkscore-server.service.
The kscore-agent postinst is deliberately quieter: it lays down
files and enables the unit but does not start the agent. You’ll
edit /etc/kscore/agent.yaml and start it manually in step 3.
2. Verify the server is up
sleep 35 # past the 30s startup grace period
curl -fsS http://127.0.0.1:8080/health/ready | jq '.ready, .components'You should see true and a components object with every dependency
in READY. If you see ready=false past 35 s, the server is still
warming up or there’s a config issue — jump to
../runbooks/troubleshooting.md
.
Sanity-check the CLI works (these don’t contact the server):
/usr/bin/kscore-server --version
kscorectl --version
kscorectl --help | head -103. Bring the agent online
Edit /etc/kscore/agent.yaml. Two values matter for a single-node
trial:
agent.id— any operator-meaningful name. Using the host’s short hostname is a reasonable default:sudo sed -i "s|^ id:.*| id: $(hostname -s)|" /etc/kscore/agent.yamlnats.urls— for the single-node trial, point at the embedded NATS server insidekscore-serveron this same host:sudo sed -i 's|^ urls:.*| urls: ["nats://127.0.0.1:4222"]|' /etc/kscore/agent.yaml
(Open the file with your editor of choice if you’d rather see the full context.)
Then start the agent and verify the unit is running:
sudo systemctl start kscore-agent
sudo systemctl status kscore-agent --no-pager | head -10Confirm the agent registered with the server:
curl -fsS http://127.0.0.1:8080/api/v1/agents | jqv0.1.x scope note. A
kscorectl agent listsubcommand is on the v0.x backlog (tracked inROADMAP.md); until it lands, querying registered agents goes through the REST endpoint above or throughkscore-server’s journal:sudo journalctl -u kscore-server -n 50 --no-pager | grep -i agent
4. Run a command
Run a no-op command on the freshly registered agent — print its FQDN:
kscorectl exec --agent "$(hostname -s)" -- hostname -fYou should see the agent’s FQDN echoed back, with a clean exit. If the command hangs, the agent isn’t reachable — check step 3.
5. Apply state
Write a small declaration:
cat >/tmp/hello.yaml <<'YAML'
metadata:
name: getting-started
version: "0.1"
file:
/tmp/keystone-hello:
state: present
content: "hello from keystone-core\n"
mode: "0644"
YAMLApply it via kscorectl:
kscorectl state apply /tmp/hello.yaml --agent "$(hostname -s)"Verify the file landed on the host:
cat /tmp/keystone-hello
# hello from keystone-core6. Browse the audit log
Every command and every state run flows through the audit store. Query recent entries:
kscorectl audit log --limit 10You’ll see your exec from step 4 and the state apply from step 5
recorded, with timestamps and actor IDs. The audit stream is the
canonical answer to “what just happened on this control plane?”
7. Tear down (optional)
To remove Keystone Core entirely:
# Debian / Ubuntu
sudo apt purge -y kscore-server kscore-agent kscore-cli
# Rocky / RHEL
sudo dnf remove -y kscore-server kscore-agent kscore-clipurge (apt) and remove (dnf) leave /etc/kscore/ and
/var/lib/kscore/ in place by default — useful if you want to
reinstall and pick up where you left off. Remove them manually for
a fully clean state:
sudo rm -rf /etc/kscore /var/lib/kscore /var/log/kscoreNext steps
- The CLI reference:
CLI-REFERENCE.mdlists everykscore-*binary and every subcommand. Each operator binary is also reachable askscorectl <name>via plugin dispatch. - The configuration reference:
CONFIGURATION-REFERENCE.mdcatalogs every key inserver.yamlandagent.yaml. - The API reference:
API-REFERENCE.mdindexes every gRPC RPC + REST endpoint with links to the canonical proto / openapi sources. - Architecture:
DESIGN.mdfor the high-level design;../../PROJECT-DETAILS.mdfor per-domain implementation detail. - Operations:
../runbooks/covers bootstrap-new-cluster, disaster-recovery, security-incident, troubleshooting, upgrade-cluster, and more. - Security:
SECURITY-GOVERNANCE.mdcovers the v1.0 four-scan baseline + the vulnerability disclosure process;../../SECURITY.mdis the reporting entry point. - Developing on the source? See
DEVELOPMENT.md§ Local Dev Topology — the contributor docker-compose harness for ad-hoc iteration on server / agent code.
Troubleshooting
Server health stays ready=false
Past the 35-second grace period, this means either the server hasn’t finished initializing all of its components (NATS, store, identity, …) or one of them failed. Check the journal:
sudo journalctl -u kscore-server -n 100 --no-pagerCommon causes: a syntax error in server.yaml, a port conflict on
5397 or 8080, or filesystem permissions on /var/lib/kscore. The
runbook ../runbooks/troubleshooting.md
walks the full diagnostic tree.
Agent doesn’t register
sudo journalctl -u kscore-agent -n 50 --no-pagerThe most common cause is nats.urls in /etc/kscore/agent.yaml not
pointing at a reachable NATS endpoint. For a single-node trial it
should be exactly ["nats://127.0.0.1:4222"] — the embedded NATS
inside kscore-server on this same host.
Port already in use
The defaults are 8080 (HTTP), 5397 (gRPC), 4222 (embedded NATS).
If any collide on your host — Cockpit historically used 9090, which
is why the server default moved from 9090 to 5397 — edit the
matching block in /etc/kscore/server.yaml and restart:
sudo systemctl restart kscore-serverkscorectl state apply reports “agent not found”
The agent identifier passed via --agent must match the agent.id
in /etc/kscore/agent.yaml. Confirm what the agent registered as:
curl -fsS http://127.0.0.1:8080/api/v1/agents | jq '.[].id'then re-issue kscorectl state apply --agent <that-id>.