Skip to content
LinkState
Go back

Collector fan-out or direct device subscriptions

Introduction to gNMI Design Review

Overview of gNMI

gNMI (gRPC Network Management Interface) is a protobuf‑based, gRPC‑transport protocol defined by the OpenConfig working group for reading, writing, and subscribing to operational and configuration data on network devices. It defines three primary RPCs: Get, Set, and Subscribe. The Subscribe RPC supports stream, poll, and once modes, allowing a client to receive a continuous stream of updates (telemetry) or a snapshot of state. gNMI uses TLS for transport security and can carry authentication tokens (e.g., JWT) or username/password credentials via gRPC metadata.

Importance of gNMI in Network Management

Modern network automation relies on a standardized, model‑driven interface to decouple orchestration logic from vendor‑specific CLIs. gNMI provides:

When scaling to hundreds or thousands of devices, the placement of the gNMI termination point—whether each downstream consumer talks directly to the device or a shared termination layer fronts the devices—has profound effects on isolation, replay capability, backpressure handling, and credential management.


Design Options for gNMI Implementation

Terminating gNMI Once Per Device (Centralized Proxy)

Benefits

Drawbacks

Letting Each Downstream System Subscribe Directly (Distributed Subscriptions)

Benefits

Drawbacks


Trade‑Offs in gNMI Design

Isolation and Security Considerations

Impact on Isolation

Security Implications

AspectCentralized TerminationDistributed Subscriptions
Credential storageSingle vault‑backed secret; easier rotation, auditMultiple copies; rotation requires coordination across all consumers
Mutual TLSProxy presents device‑side cert; clients authenticate to proxyEach client must present its own cert to device (device must trust many CAs)
Authorization granularityProxy can enforce per‑client policies (e.g., allow Get only, block Set)Device must enforce per‑client policies; many devices lack fine‑grain gNMI ACLs
Audit loggingCentral log of all gNMI RPCs at proxyLogs distributed across devices; correlation harder
Blast radiusProxy compromise → all devicesConsumer compromise → only that consumer’s sessions

Replay and Backpressure Mechanisms

Handling Replay

Managing Backpressure

Credentials and Authentication Management

Centralized gNMI

Distributed gNMI


Troubleshooting gNMI Implementations

Common Issues in gNMI Termination

Debugging gNMI Connection Issues

  1. TLS handshake failures – verify proxy’s client certificate matches the device’s expected SAN; check device logs for unknown_ca or certificate_unknown.
  2. Authentication rejections – ensure the proxy retrieves the correct secret; test with gnmic -a <device>:<port> -u <user> -p <pass> capabilities.
  3. gNMI service not responding – confirm the device’s gNMI server is enabled (show running-config | include gnmi) and listening on the correct TCP port (default 9339).
  4. Proxy crashes – inspect proxy stdout/stderr for panics; enable verbose logging (-log-level=debug) to see RPC errors.

Resolving gNMI Subscription Conflicts

Troubleshooting Distributed gNMI Subscriptions

Identifying Issues in Downstream Subscriptions

Resolving Authentication and Authorization Issues


Code and CLI Examples for gNMI

Configuring gNMI Termination using CLI

Example CLI Commands for gNMI Setup
Assuming a proxy implementation based on the open‑source gnmi_proxy (Go) that terminates gNMI per device and exposes a local gRPC endpoint for consumers:

# 1. Start Vault agent to fetch dynamic secrets
vault agent -config=/etc/vault/agent.hcl &
# Agent writes device credentials to /run/secrets/gnmi/<device>

# 2. Launch the proxy for a specific device
gnmi_proxy \
  --device-addr router01.example.com:9339 \
  --device-cert /run/secrets/gnmi/router01/tls.crt \
  --device-key  /run/secrets/gnmi/router01/tls.key \
  --device-ca   /run/secrets/gnmi/router01/ca.crt \
  --listen-addr 0.0.0.0:10000 \
  --client-cert /run/secrets/proxy/tls.crt \
  --client-key  /run/secrets/proxy/tls.key \
  --client-ca   /run/secrets/proxy/ca.crt \
  --replay-buffer-size 10000 \
  --backpressure-policy drop-newest

The proxy opens a gNMI session to the device (--device-*) and exposes a local gNMI endpoint (--listen-addr) for downstream systems. Mutual TLS is enforced both ways.

Verifying gNMI Connection Status

# Check proxy health endpoint (if exposed)
curl -k https://localhost:10001/healthz
# Expected: {"status":"ok","device":"router01.example.com","subscribers":3}

# Use gnmic to query capabilities via the proxy
gnmic -a localhost:10000 \
      --insecure \
      capabilities

Implementing gNMI Subscriptions using Code

Python (using gnmi_client library)

import grpc
from gnmi import gnmi_pb2, gnmi_pb2_grpc
from google.protobuf.any_pb2 import Any

def subscribe(device_addr, token, paths):
    # Load TLS credentials
    creds = grpc.ssl_channel_credentials(
        root_certificates=open('ca.pem', 'rb').read(),
        private_key=open('client.key', 'rb').read(),
        certificate_chain=open('client.crt', 'rb').read()
    )
    # Add bearer token as metadata
    call_creds = grpc.metadata_call_credentials(
        lambda context, callback: callback([('authorization', f'Bearer {token}')], None)
    )
    composite_creds = grpc.composite_channel_creds(creds, call_creds)

    channel = grpc.secure_channel(device_addr, composite_creds)
    stub = gnmi_pb2_grpc.gNMIStub(channel)

    # Build subscription request (example: stream mode)
    subscribe = gnmi_pb2.SubscribeRequest(
        subscribe=gnmi_pb2.SubscriptionList(
            subscription=[
                gnmi_pb2.Subscription(path=gnmi_pb2.Path(elem=[gnmi_pb2.PathElem(name=p)]),
                                      mode=gnmi_pb2.SubscriptionMode.STREAM,
                                      sample_interval=10_000_000_000)  # 10 seconds
                for p in paths
            ],
            mode=gnmi_pb2.SubscriptionList.STREAM
        )
    )

    for resp in stub.Subscribe(iter([subscribe])):
        print(resp)

This snippet establishes a mutual‑TLS channel, injects a JWT token via gRPC metadata, and opens a streaming subscription for the supplied YANG paths.


End of review.


Share this post on:

Previous Post
Intended Maintenance Window Versus Observed Blast Radius
Next Post
Config match does not equal recovery