SONiC config_db.json: Save, Reload and Replace Safely - 夜莺博客

SONiC config_db.json: Save, Reload and Replace Safely

The most common SONiC surprise for engineers coming from IOS or Junos is that configuration changes are not automatically permanent. SONiC holds its running state in a Redis-backed configuration database, and the switch only writes that state to /etc/sonic/config_db.json when you ask it to. That single design decision explains most "my config disappeared after reboot" tickets, and it also gives you a very useful rollback tool: if you never save, a reload wipes your mistake. This guide explains what save, reload and replace actually do, how the Redis layers map to JSON files, and how to verify each step with docker and redis-cli commands.

Where the Configuration Actually Lives

SONiC's control plane is a set of containers (bgp, swss, syncd, pmon, telemetry) and a Redis instance. Redis database instance 4 holds the configuration tables; a separate instance holds application state. The JSON file on disk is only the boot-time input:

show version
show platform summary

# Look at the config database directly
redis-cli -n 4 keys '*'
redis-cli -n 4 hgetall 'VLAN|Vlan10'

# Dump the whole candidate configuration as JSON
sonic-cfggen -d --print-data

Because the configuration is a set of Redis tables, a change made with config vlan add 20 is visible immediately in the running system but invisible to the next boot until it is saved.

The multi-database layout is worth internalising because it decides which commands actually change behaviour:

  • Database 4 - CONFIG_DB. The intended configuration. Every config CLI command writes here.
  • Database 0 - APPL_DB. What the application-level daemons derive from CONFIG_DB. Read-only from a user's point of view.
  • Database 1 - STATE_DB. Operational state reported by daemons - interface link status, BGP session state, transceiver presence.
  • Database 2 - COUNTERS_DB. Statistics counters, which is what a monitoring system scrapes.
  • Database 6 - ASIC_DB. What the SAI layer actually programmed into the switching ASIC - the ground truth that hardware agrees with.

So when you are debugging "I configured it but it does not work", the diagnostic path is CONFIG_DB → APPL_DB → ASIC_DB. If CONFIG_DB has your change and ASIC_DB does not, the failure is in a daemon, not in your CLI syntax.

config save: Make It Permanent

sudo config save -y

config save serialises the Redis configuration tables into /etc/sonic/config_db.json. It does not restart any daemon and does not touch traffic. The rule of thumb on a production switch is simple: every approved change ends with config save -y, and nothing else does.

Two extensions matter in practice. First, you can save to an explicit path, which is how you produce a dated artefact to copy off the box:

# save to a named file instead of the default location
sudo config save -y -f /home/admin/config-$(date +%F-%H%M).json

# verify the file exists and is valid JSON before you rely on it
ls -l /etc/sonic/config_db.json
python3 -m json.tool /etc/sonic/config_db.json > /dev/null && echo "valid JSON"

Second, config save is not idempotent magic - it writes what is currently in CONFIG_DB, including any half-finished change you made ten minutes ago and forgot. That is why the ordering rule exists: finish the change, verify the running state, then save. If you have to back out a change, prefer to fix CONFIG_DB first and save afterwards, because saving a broken state simply makes the breakage survive a reboot.

config reload: Rebuild from the Saved File

sudo config reload -y

config reload restarts almost every service and re-reads the saved config_db.json, so it is a traffic-affecting operation. It is the correct tool after a bad change you never saved, or when a service is wedged and you want a clean state. Verify afterwards that containers came back and interfaces are as expected:

docker ps
show interface status
show ip bgp summary

Because reload restarts the container set, it is also the operation that takes the longest and the one most likely to reveal a problem you did not know about - a service that fails to come back, a port that no longer links, a transceiver that is not detected. Treat the post-reload checks as mandatory, not optional:

  1. docker ps - all expected containers running, none in a restart loop.
  2. show interface status - every port up/up that should be, correct speed and FEC.
  3. show ip bgp summary (or the equivalent for your routing stack) - all peers Established.
  4. show reboot-cause - confirm why the box last rebooted, which is easy to forget during a maintenance window.
  5. redis-cli -n 4 keys '*' - the configuration surface looks like what you expect, not an empty database.

If the reload was triggered by a mistake, remember the asymmetry: a reload discards unsaved changes but preserves everything in config_db.json. That is exactly why the "save only approved changes" discipline pays for itself - an unapproved experiment that was never saved evaporates with a reload, and the device returns to the last known-good state.

config replace, load and load_minigraph

When you want to move a device to a known-good full configuration (for example a golden config produced in a lab), the JSON file is the unit of change:

sudo config load /etc/sonic/golden-config.json -y   # load a local file into Redis
sudo config replace /etc/sonic/golden-config.json -y # replace the running config in place
sudo config load_minigraph -y                       # rebuild from minigraph.xml / ZTP metadata

config replace applies the file as the new running configuration without a full reload, which is faster but also less forgiving: anything missing from the file is removed. config load_minigraph is what ZTP uses to build a machine-generated baseline; it discards manual configuration that is not represented in the minigraph.

The three differ in scope and in how much they can surprise you:

Command Source of truth Service restart Removes absent entries
config load a JSON file you name partial / targeted no
config replace a JSON file you name minimal, in-place yes
config reload config_db.json on disk nearly all yes (relative to saved file)
config load_minigraph minigraph.xml / ZTP nearly all yes - drops manual config

Before any replace or minigraph load on a live device, take a copy of what is running. Two minutes of copying prevents an afternoon of reconstructing a config from memory:

# snapshot current state before a destructive operation
sudo config save -y -f /home/admin/pre-change-$(date +%F-%H%M).json
scp admin@switch:/home/admin/pre-change-*.json ./backups/

Note that config load_minigraph is the one to be most careful with. On a device where ZTP provisioned the base and engineers then added everything by hand - VLANs, ACLs, port channels - a minigraph load will delete the hand-built configuration because it is not represented in the minigraph. If the site has drifted from ZTP, confirm before typing that command.

Backups, Rollback and Off-Box Copies

An on-box file protects you from a bad change; an off-box file protects you from a dead disk. Build both into the workflow.

# 1. on-box: current running config to a named file
sudo config save -y -f /home/admin/cfg-$(date +%F).json

# 2. off-box: pull it to your workstation or a Git repository
scp admin@switch:/home/admin/cfg-$(date +%F).json ./sonic-backups/
sha256sum ./sonic-backups/cfg-$(date +%F).json

# 3. commit the artifacts so every change is reviewable
git add sonic-backups/ && git commit -m "sonic config snapshot $(date +%F)"

Keep the snapshots in version control and the diff between yesterday's and today's JSON becomes a change log the whole team can read. Because the format is plain JSON keyed by table name, a diff is human-readable: you can see exactly which VLAN, interface or BGP neighbour was added. That property is what makes SONiC automation-friendly compared with a binary startup configuration - see our notes on SONiC PFC watchdog and storm detection for another case where reading state tables directly beats guessing from the CLI.

Verification and Recovery Checklist

  1. Confirm the running state: show running-configuration and redis-cli -n 4 keys '*'.
  2. Save it, then prove persistence: config save -y followed by ls -l /etc/sonic/config_db.json and a checksum.
  3. Keep an off-box copy: scp admin@switch:/etc/sonic/config_db.json ./switch-$(date +%F).json.
  4. After any reload, check docker ps, show interface status, show reboot-cause and BGP session state before closing the change.

If a device comes up in an unexpected state, that list is also the recovery order. First ask what the device actually booted from - ls -l /etc/sonic/config_db.json and show version tell you whether a config was present at all. If the file is missing or empty, config load_minigraph -y rebuilds a baseline from ZTP metadata, and then your newest off-box snapshot becomes the fastest path back to the intended configuration. Establishing that recovery path before it is needed is the whole point of keeping snapshots in Git.

Common Failure Modes on Real Switches

Most SONiC configuration incidents fit into a handful of patterns. Recognising the pattern shortens the fix considerably.

  • "My change vanished after a reboot." The change was never saved. It existed only in CONFIG_DB in memory, and the boot sequence read a config_db.json that predated it. Fix: apply the save discipline and, if the state must be guaranteed, verify the JSON contains the table you just changed.
  • "The reload brought the box up wrong." The saved file was itself broken - typically because a partial change was saved. Fix: compare the file against your last known-good off-box snapshot and reload from that.
  • "config replace dropped half my device." Replace is authoritative, so anything absent from the file is removed. Fix: build the replacement file from a save of a device that was already correct, then edit it deliberately, rather than hand-writing JSON from a partial spec.
  • "A container is restarting in a loop after reload." A service failed to initialise, often because a referenced object (VLAN, port channel, transceiver) is missing or misspelled in config_db.json. Fix: check the container logs with docker logs <container> and cross-check CONFIG_DB against what the daemon expected.
  • "Nothing is configured at all." A missing or unreadable config_db.json. Fix: confirm the file exists and is valid JSON, then rebuild with config load_minigraph if the device is ZTP-managed.

Every one of those five is diagnosable by comparing three things: what is in CONFIG_DB now, what is in config_db.json on disk, and what your last snapshot contains. Keeping the third artefact current is what turns a mystery into a diff.

Automating the Save Discipline

Manual saves are correct on a change window and unreliable in daily operations, because the person making the change is also the person who has to remember. Two automations close that gap without giving up the "save only approved changes" principle.

The first is a scheduled snapshot that copies the current configuration off-box without altering it - a backup job, not a save job:

#!/usr/bin/env bash
# nightly: snapshot the running config and push it somewhere durable
set -euo pipefail
STAMP=$(date +%F)
sudo config save -y -f "/home/admin/nightly-${STAMP}.json"
scp "/home/admin/nightly-${STAMP}.json" backup@storage:/sonic-snapshots/
sha256sum "/home/admin/nightly-${STAMP}.json" >> /home/admin/snapshot-manifest.txt

Because this writes to a dated file and never to a live device by itself, it is safe on production. The output is a rolling history you can diff, and the manifest proves the file has not silently changed on disk.

The second is a drift check. If automation is the source of truth, periodically compare the device's running configuration with the file automation expects, and alert on the difference:

# expected config from the automation repository
sonic-cfggen -d --print-data > /tmp/running.json

# compare against the golden file (jq normalises key order)
jq -S . /tmp/running.json     > /tmp/running.sorted.json
jq -S . /etc/sonic/golden.json > /tmp/golden.sorted.json

diff -u /tmp/golden.sorted.json /tmp/running.sorted.json || \
  echo "DRIFT DETECTED - investigate before the next change window"

Run that comparison after every maintenance window and you will catch hand-edits that were never folded back into the repository - a common cause of "the automation keeps reverting my change" arguments. For teams already running Ansible against SONiC, the same normalise-and-diff idea fits naturally into a playbook alongside the modules covered in our Ansible network modules walkthrough, which shows the facts-and-backup pattern this borrows from.

Related Reading

If you are still building CLI muscle memory, start with our SONiC OS CLI cheat sheet: 50 essential commands, and for the fabric context around open network operating systems see spine-leaf architecture in the data center. Automated collection of SONiC state is covered in monitoring network devices with Prometheus and SNMP exporter, and if you are chaining external tools against the same config database, the routing and grouping rules in our Alertmanager routing and silences guide apply directly to SONiC telemetry pipelines.

原文链接:https://r12f.com/sonic-book/1-3-command-cheatsheet.html