EFCX Kubernetes Workload Groups
Companion to efcx-kubernetes-deployment-architecture.drawio (SVG). That diagram stays at node-pool altitude; this doc carries the component-level detail and the placement rationale behind it, single site, production-ready, generic across customers (not Yomo-specific).
Profile ID naming
Each workload group below now carries a stable CX-<Name> profile ID in the leftmost column. This extends the short-code convention EFCX-Hardware-Sizing-Within-a-Site.md already started with CX-Core and CX-Data Platform, applying it consistently to the groups that doc currently leaves unprefixed (WFM, Vault) and to every other group here.
This mirrors standard practice in enterprise Kubernetes reference architectures: AKS, EKS, and GKE all group nodes into named pools (AKS’s system/user pools, GKE named node pools) rather than listing components ad hoc, and platform sizing guides such as VMware Validated Designs and SAP-style sizing docs assign each workload tier a short code precisely so later documents can cite the tier without repeating its full component list. The ID is the citation key; the “Representative components” column stays the source of truth for what’s actually in each group.
Workload groups (in-cluster)
|
Profile ID |
Workload group |
Representative components |
Node pool |
Notes |
|---|---|---|---|---|
|
CX-Edge |
Edge & Identity |
APISIX (API gateway), Keycloak (IAM) |
Edge |
Ops has flagged APISIX as the single most HA-critical component across every profile - dedicated pool, anti-affinity, PodDisruptionBudget |
|
CX-Core |
CX Core (orchestration, core services, Activities) |
agent-manager, bot-framework, conversation-manager, conversation-controller, ccm, cim-backend, routing-engine (media-routing-engine), web-channel-manager, customer-channel-manager, file-engine, license-manager, state-events-logger, room-event-store, unified-admin, cx-tenant, tenant-config-service, otp-manager, business-calendar, realtime-reports-manager |
Application |
Activities (Activity Stream/Store) is part of this group, not a separate one - see Activities storage below. customer-widget moved out of this list - see DMZ placement below. bot-framework is CX Core’s own API/SDK for connecting third-party AI engines, not part of the Rasa-X Connector row below - see that row’s note |
|
- |
Digital Channels (category) |
whatsapp, facebook, instagram, telegram, twitter, viber, twilio, email, ms-exchange-email, 360, google-playstore, apple-store, youtube, linkedin, smpp connectors |
Application |
Not one profile: each connector is its own separate profile. Bursty, outbound internet egress to social/messaging provider APIs. Each connector now ships as its own optional Helm chart. See the per-connector profile table below. Optionally deployed in a DMZ |
|
CX-Rasa-X-Connector |
Rasa-X Connector |
Rasa-X (cim-rasa-bot) |
Application |
Solid optional add-on when a customer chooses Rasa as their bot engine, not a generic “Bot & AI Orchestration” category. Other BYO-AI/LLM/ASR/TTS engines a customer connects don’t get an in-cluster component at all: they’re called externally via CX Core’s bot-framework API/SDK, so they don’t need their own profile row here |
|
CX-Agent |
AgentDesk (Unified Agent Desktop) |
unified-agent (backend/BFF), AgentDesk frontend (browser SPA) |
Application |
Matches the |
|
CX-Campaigns |
Campaigns & Engagement |
campaigns, scheduled-activities, list-management, conversation-studio |
Application |
|
|
CX-Surveys |
Surveys |
survey-backend, survey-nodes |
Application |
|
|
CX-CRM |
CRM Connectors |
Salesforce, MS Dynamics (CIF2.0/OnPremise), ServiceNow, Zendesk, Zoho, SAP C4C, Odoo, Hubspot |
Application |
Optional, enabled per tenant |
|
CX-QM |
QM (Quality Management) |
qm-backend, qm-cisco-sync-service, VRS middleware |
Application |
Optional add-on |
|
CX-WFM |
WFM (Workforce Management) |
wfm-solution |
Application |
Optional add-on. Matches |
|
CX-Cisco |
Cisco Integration |
cisco-teams-synchronizer, CiscoConnector, CiscoScheduler |
Application |
Only for customers with an existing Cisco UCCE/PCCE estate |
|
CX-Data Platform |
Reporting & Data Platform |
cx-data-platform ( |
Data-platform/batch |
Scheduled/batch profile, different scaling shape than always-on services - see Reporting pipeline below. Matches the |
|
CX-Stateful |
In-cluster stateful workloads |
Redis, ActiveMQ/Artemis |
Stateful |
StatefulSets on CSI-backed PVs, pod anti-affinity across nodes |
|
CX-Vault |
Secrets |
Vault |
Stateful |
Scope unconfirmed - see Open items. Matches |
|
CX-Observability |
Monitoring & Logging |
Prometheus, Grafana, node-exporter, Alertmanager, ElasticSearch, Kibana |
Observability |
Managed and owned jointly by the underlying platform and the customer/partner, not by EFCX, except Grafana, which EFCX bundles as the dashboard layer co-located with CX-Core (see External tag note). No EFCX sizing figure applies to Prometheus, node-exporter, Alertmanager, ElasticSearch, or Kibana. FluentBit/Fluentd have already been retired from this stack |
Digital Channels: per-connector profiles
Each channel connector is a separate profile. This also matches what the doc already noted: each connector ships as its own optional Helm chart, so each can be enabled, sized, and scaled independently per deployment.
|
Profile ID |
Connector |
Notes |
|---|---|---|
|
CX-Channel-WhatsApp |
|
|
|
CX-Channel-Facebook |
|
|
|
CX-Channel-Instagram |
|
|
|
CX-Channel-Telegram |
telegram |
|
|
CX-Channel-Twitter |
|
|
|
CX-Channel-Viber |
viber |
|
|
CX-Channel-Twilio |
twilio |
|
|
CX-Channel-Email |
|
|
|
CX-Channel-MSExchange |
ms-exchange-email |
|
|
CX-Channel-360 |
360 |
Source name as carried in the Components spreadsheet; not further identified in this doc’s sources |
|
CX-Channel-GooglePlay |
google-playstore |
|
|
CX-Channel-AppleStore |
apple-store |
|
|
CX-Channel-YouTube |
youtube |
|
|
CX-Channel-LinkedIn |
|
|
|
CX-Channel-SMPP |
smpp |
|
All fifteen share the same Application node pool and the same placement notes as the category row above (bursty outbound egress to provider APIs, optional DMZ deployment). Numeric sizing is pending for each, same as every other profile - see Open items.
External CX-Profile tag vs. node-pool placement
These are two different, non-conflicting classifications of the same six components (Redis, ActiveMQ/Artemis, Keycloak, APISIX, Grafana, Vault), answering two different questions:
-
The
Externaltag answers “who built it?” Expertflow’s component inventory (the Components spreadsheet’s “CX Profiles” column) tags all six with a singleExternalvalue, meaning: none of them is a first-party CX microservice: they’re third-party or open-source infrastructure bundled with the platform. That’s a one-bucket, packaging/licensing classification. EFCX-Hardware-Sizing-Within-a-Site.md uses this tag as-is, because it sizes at that same packaging altitude. -
Node-pool placement answers “where does it run, and how is it kept HA?” This doc splits the same six components across four different node pools based on their runtime behavior, not their origin: Edge & Identity (Keycloak, APISIX: both edge-facing, auth and API gateway), In-cluster Stateful (Redis, ActiveMQ/Artemis: both PVC-backed, StatefulSets), Observability (Grafana: part of the monitoring stack), and Secrets (Vault: isolated for its own HA/access-control treatment).
A component can be “External” (one licensing bucket) and live in any of four different node pools (a runtime-placement bucket) at the same time. Neither table is wrong; they’re just answering different questions about the same six components.
Outside the Kubernetes cluster
|
Profile ID |
Tier |
Components |
Notes |
|---|---|---|---|
|
- |
Platform-managed clustered data services |
PostgreSQL, MongoDB, S3-compatible object storage |
Shared by both the in-cluster workload groups and the Voice VM tier below - not siloed per tier. No profile ID: sized by whatever platform-managed service hosts them, not as a fixed workload profile |
|
CX-SIP |
Voice Subsystem VMs |
CX SIP Proxy |
Dedicated VM pool, outside K8s scheduling: RTP/media traffic doesn’t fit ordinary ClusterIP/Ingress networking. Still consumes the same shared cloud-native storage and managed-DB tier as the in-cluster workloads, not a separate silo. Matches |
|
CX-Media |
Voice Subsystem VMs |
CX Media Server, Voice Recording middleware |
Same VM pool and rationale as CX-SIP above. Matches |
|
- |
Carrier demarcation |
Cisco CUBE |
Fully external, customer/carrier-provided. Cisco CUBE also serves the Voice AI Gateway function - these are the same component, not two separate ones |
DMZ placement (optional)
Customer Widget and the Digital Channels connectors can optionally be deployed in a DMZ zone outside the core network, for deployments that need public connectivity: Customer Widget is served directly to the end-user’s browser on public-facing websites, and the Digital Channels connectors take inbound traffic directly from public third-party channel providers (WhatsApp, Facebook, etc.). This DMZ topology is a supported deployment option, not an open architecture question; what’s still unresolved is the granularity, see Open items.
|
Component |
Currently part of |
Why it’s DMZ-eligible |
|---|---|---|
|
Customer Widget |
CX Core representative components (table above) |
Serves customer-facing traffic directly from the end-user’s browser |
|
Digital Channels connectors |
Digital Channels workload group |
Take inbound traffic directly from third-party channel providers (WhatsApp, Facebook, etc.) |
Placement rationale
Redis and ActiveMQ/Artemis run in-cluster as StatefulSets on CSI-backed persistent volumes. Both are cache/queue infrastructure tightly coupled to the application pods’ request path - running them in-cluster keeps that latency-sensitive path inside the same network fabric as the services calling them.
PostgreSQL, MongoDB, and S3-compatible object storage are consumed as platform-managed services, outside the Kubernetes workload groups. These are the components a managed cloud-native platform is expected to operate as clustered, HA services in its own right (backup, patching, failover) rather than EFCX re-implementing that operational surface as StatefulSets.
CX SIP Proxy and CX Media Server stay outside the Kubernetes cluster on their own VM pool, because RTP media doesn’t fit ordinary ClusterIP/Ingress networking and needs direct external IPs. They are not, however, an isolated infrastructure silo: they consume the same platform-managed PostgreSQL/MongoDB/object-storage tier and the same cloud-native storage as the in-cluster workloads (for example, voice configuration in PostgreSQL, call recordings in S3-compatible storage) - one shared data platform underneath both the containerised and the VM-based parts of the deployment.
Activities storage: MongoDB → PostgreSQL
Activities (Activity Stream/Activity Store: rooms, conversations, CIMEvents/CIMActivities) are part of the CX Core workload group, not a separate one. They are stored in MongoDB today; a future migration moves this to PostgreSQL. This doc deliberately doesn’t hard-wire MongoDB as the Activities backing store in the workload-group model - CX Core connects to “platform-managed clustered data services” generically, and which specific managed database backs Activities is expected to change without altering the workload-group placement itself.
Reporting pipeline: Airflow → Metabase
The Reporting & Data Platform group runs transflux, an Apache Airflow-based scheduler with dbt transformation models, extracting from the operational stores (MongoDB today, PostgreSQL after the Activities migration) into a reporting schema, which Metabase (this repo’s earlier “CX Analyzer” terminology) then serves dashboards from. The legacy reporting-connector (Talend-based ETL) is deprecated in newer deployments and is not part of this model. Because this group runs scheduled batch jobs rather than always-on request handling, it gets its own data-platform/batch node pool rather than sharing the Application pool’s HPA-driven scaling profile.
Open items
Carried forward as unresolved, not assumed:
-
Vault’s exact scope - the component sheet marks it “optional? To confirm.” Whether it’s mandatory in every deployment and what it specifically protects needs confirmation before finalizing the Stateful pool’s sizing.
-
Customer widget DMZ granularity - ships as part of CX Core by default; can optionally be deployed in a DMZ zone instead, for deployments needing public connectivity, since it serves customer-facing browser traffic directly. Whether that’s the default for public-facing deployments or purely opt-in isn’t pinned down yet. See DMZ placement.
-
Digital channel connectors DMZ granularity - same optional DMZ topology as the customer widget, since these connectors take inbound traffic directly from third-party channel providers. Unresolved: whether all channels move to the DMZ together or per-channel, given each now ships as its own Helm chart. See DMZ placement.
-
Numeric sizing - this doc defines workload-group placement and node-pool grouping, not CPU/RAM/replica counts. Per-component resource and replica requirements are still pending. Profile IDs above are the citation key those figures should be attached to once available.
-
Site B replication - this model is single-site. Duplicating it for a second site plus cross-site clustering/DR is a later pass, not designed here.
-
hardware-sizing-kubernetes.drawio(repo root) is an earlier, in-progress sketch of this same problem. This doc and its companion diagram supersede it as the current reference; the older file is left as-is rather than deleted.