← Back to blog
Xinchuang 4 min read 炬鲸团队

Running JJHub OBSERVE on Kylin + Kunpeng: An ARM Deployment Guide

A full containerized deployment of JJHub OBSERVE on Kylin V10 (ARM64) with Kunpeng 920 — image architecture checks, DM database swap, collector compatibility, and performance tuning.

Deploying an observability platform in a Xinchuang (domestic-stack) environment is less about features and more about architecture and dependencies: are ARM64 images available, can you swap in a domestic database, and will collectors run reliably on a domestic OS? This is our field record from Kylin V10 + Kunpeng 920.

A quick note on why this matters beyond the checkbox: most Xinchuang estates run on ARM servers (Kunpeng, Phytium) with domestic operating systems and databases, which means the assumptions baked into x86-first software — prebuilt amd64 images, glibc version expectations, MySQL-specific SQL — stop holding. The sections below cover the specific places where those assumptions break and what to do about them.

Environment and Compatibility Scope

  • OS: Kylin V10 SP3, kernel 4.19, ARM64 (aarch64)
  • CPU: Kunpeng 920, 2×48 cores
  • Database: DM8 (replacing MySQL for metadata and alert rules)
  • Containers: Docker 20.10 + containerd

Check image architecture before deploying anything. Run docker manifest inspect to confirm the target image ships an arm64 layer; amd64-only images fall back to qemu emulation on Kunpeng and lose an order of magnitude in performance, which shows up as sluggish queries rather than an obvious failure — easy to misdiagnose as a capacity problem. JJHub OBSERVE publishes multi-arch images for both server and collector, so pull with --platform linux/arm64 to avoid mixing architectures in one deployment.

Deployment: Server-Side Containers

The server side is orchestrated with docker-compose around four services: an ingestion gateway (OTLP and metrics), a storage engine, a query engine, and a control plane. Mount the DM8 JDBC driver separately; the schema init scripts live under /init in the image and run automatically on first start, so a fresh volume is enough to bootstrap the database. One DM8-specific detail: set the connection pool's validationQuery to SELECT 1 FROM DUAL. Copying MySQL's SELECT 1 verbatim will error out and, worse, surface as intermittent "connection is closed" failures once load picks up — the kind of bug that only appears in production.

Collector Compatibility: Gotchas on a Domestic OS

Collectors (node exporter, filelog, OpenTelemetry Collector) mostly run as-is on Kylin, but two issues should be handled up front:

  • glibc version: Kylin V10 ships an older glibc, so dynamically linked collectors may throw GLIBC_2.34 not found at startup. Switch to static or musl builds, which also removes the libc version question from future upgrades.
  • Domestic middleware monitoring: TongWeb, Apusic, and similar have no ready-made exporter. Point the OpenTelemetry JMX receiver at their exposed JMX port and add a thin metric-name mapping layer so the metrics land in dashboards with familiar names instead of raw MBean paths.

Performance and Stability Tuning

Kunpeng's NUMA topology is more pronounced than same-spec x86. Pinning the storage engine to a single NUMA node cuts cross-node memory access and lifts write throughput by roughly 20% — worth doing before capacity planning, since it changes how much hardware you actually need. Put DM8's tablespace and data files on a dedicated disk, and reduce the query engine's frequent metadata polling.

Under load testing, ARM write and query latency matched x86 at equal spec; cold start is slightly slower, which is normal for the platform and not a cause for alarm. Run the same load test you'd run on x86 and compare numbers — if they diverge, the gap is almost always in one of the three places above (architecture emulation, database config, or collector linkage) rather than a fundamental ARM limitation.

Verification Checklist

Before calling the deployment done, walk through a short checklist rather than eyeballing the dashboard. Confirm the ingestion gateway is actually accepting OTLP by checking its request counters, not just that the UI is up. Send a synthetic span from a test workload and confirm it appears in the trace view end to end. Run a query against the DM metadata store and confirm the response time is in line with your x86 baseline. Finally, leave the environment running for a full business day and watch for the intermittent "connection is closed" pattern that signals the DM validationQuery is still wrong. Each of these checks is cheap, and any one of them catches the class of problem that otherwise surfaces at 3 a.m. on a production weekend.