mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
[Docs] Improve high availability control plane diagram clarity
Show each worker's DB and Redis as prominent infra boxes instead of small chips, and clarify that the control plane is admin UI only — not a router.
This commit is contained in:
parent
479c5e21aa
commit
d332c5b541
3 changed files with 145 additions and 74 deletions
|
|
@ -42,9 +42,9 @@ The **High Availability Control Plane** takes a different approach:
|
|||
|
||||
<ControlPlaneArchitecture />
|
||||
|
||||
The **control plane** is a LiteLLM instance that serves the admin UI and knows about all the workers. It does not proxy LLM requests, it is purely for administration.
|
||||
The **control plane** is a LiteLLM instance that serves the admin UI and knows about all the workers. It is **not a router** — it does not proxy or route any LLM requests. It exists purely so admins can switch between workers and manage them from a single UI.
|
||||
|
||||
Each **worker** is a fully independent LiteLLM proxy that handles LLM requests for its region or team. Workers have their own users, keys, teams, and budgets.
|
||||
Each **worker** is a fully independent LiteLLM proxy that handles LLM requests for its region or team. Workers have their own database, Redis, master key, users, keys, teams, and budgets. No infrastructure is shared between workers.
|
||||
|
||||
## Setup
|
||||
|
||||
|
|
|
|||
|
|
@ -3,23 +3,56 @@ import styles from './styles.module.css';
|
|||
|
||||
/* ────────────────────── Shared small pieces ────────────────────── */
|
||||
|
||||
function InfraChip({ color, label }: { color: string; label: string }) {
|
||||
const dotClass =
|
||||
function InfraBox({ icon, label, color }: { icon: string; label: string; color: 'green' | 'blue' | 'orange' }) {
|
||||
const colorClass =
|
||||
color === 'green'
|
||||
? styles.infraDotGreen
|
||||
? styles.infraBoxGreen
|
||||
: color === 'blue'
|
||||
? styles.infraDotBlue
|
||||
: styles.infraDotOrange;
|
||||
? styles.infraBoxBlue
|
||||
: styles.infraBoxOrange;
|
||||
|
||||
return (
|
||||
<span className={styles.infraChip}>
|
||||
<span className={`${styles.infraDot} ${dotClass}`} />
|
||||
{label}
|
||||
</span>
|
||||
<div className={`${styles.infraBox} ${colorClass}`}>
|
||||
<span className={styles.infraBoxIcon}>{icon}</span>
|
||||
<span className={styles.infraBoxLabel}>{label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ────────────────────── Architecture tab ────────────────────── */
|
||||
/* ────────────────────── Worker column with infra ────────────────────── */
|
||||
|
||||
function WorkerColumn({
|
||||
name,
|
||||
region,
|
||||
subtitle,
|
||||
nodeClass,
|
||||
badgeClass,
|
||||
}: {
|
||||
name: string;
|
||||
region: string;
|
||||
subtitle: string;
|
||||
nodeClass: string;
|
||||
badgeClass: string;
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.workerColumn}>
|
||||
<div className={`${styles.node} ${styles.nodeWorker} ${nodeClass}`}>
|
||||
<div className={styles.nodeHeader}>
|
||||
<span className={styles.nodeTitle}>{name}</span>
|
||||
<span className={`${styles.badge} ${badgeClass}`}>{region}</span>
|
||||
</div>
|
||||
<div className={styles.nodeSubtitle}>{subtitle}</div>
|
||||
<div className={styles.nodeCaption}>Handles LLM requests</div>
|
||||
</div>
|
||||
<div className={styles.infraStack}>
|
||||
<InfraBox icon="🗄" label="Own Database" color="green" />
|
||||
<InfraBox icon="⚡" label="Own Redis" color="orange" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ────────────────────── Architecture diagram ────────────────────── */
|
||||
|
||||
function ArchitectureView() {
|
||||
return (
|
||||
|
|
@ -36,49 +69,41 @@ function ArchitectureView() {
|
|||
<div className={`${styles.node} ${styles.nodeControlPlane}`}>
|
||||
<div className={styles.nodeHeader}>
|
||||
<span className={styles.nodeTitle}>Control Plane</span>
|
||||
<span className={`${styles.badge} ${styles.badgeBlue}`}>UI</span>
|
||||
<span className={`${styles.badge} ${styles.badgeBlue}`}>ADMIN UI ONLY</span>
|
||||
</div>
|
||||
<div className={styles.nodeSubtitle}>cp.example.com</div>
|
||||
<div className={styles.infraRow}>
|
||||
<InfraChip color="green" label="Own DB" />
|
||||
<InfraChip color="orange" label="Own Redis" />
|
||||
<InfraChip color="blue" label="Own Key" />
|
||||
<div className={styles.nodeCaption}>
|
||||
Not a router — does not proxy LLM requests.
|
||||
<br />
|
||||
Lets admins switch between workers to manage them.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Branch connector */}
|
||||
<div className={styles.connectorBranch}>
|
||||
<div className={`${styles.branchLeg} ${styles.branchLegLeft}`} />
|
||||
<div className={`${styles.branchLeg} ${styles.branchLegRight}`} />
|
||||
{/* Branch connector with label */}
|
||||
<div className={styles.connectorBranchLabeled}>
|
||||
<span className={styles.connectorLabel}>UI management only</span>
|
||||
<div className={styles.connectorBranch}>
|
||||
<div className={`${styles.branchLeg} ${styles.branchLegLeft}`} />
|
||||
<div className={`${styles.branchLeg} ${styles.branchLegRight}`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Workers */}
|
||||
<div className={styles.workersRow}>
|
||||
<div className={`${styles.node} ${styles.nodeWorker} ${styles.nodeWorkerA}`}>
|
||||
<div className={styles.nodeHeader}>
|
||||
<span className={styles.nodeTitle}>Worker A</span>
|
||||
<span className={`${styles.badge} ${styles.badgeGreen}`}>US East</span>
|
||||
</div>
|
||||
<div className={styles.nodeSubtitle}>worker-a.example.com</div>
|
||||
<div className={styles.infraRow}>
|
||||
<InfraChip color="green" label="Own DB" />
|
||||
<InfraChip color="orange" label="Own Redis" />
|
||||
<InfraChip color="blue" label="Own Key" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`${styles.node} ${styles.nodeWorker} ${styles.nodeWorkerB}`}>
|
||||
<div className={styles.nodeHeader}>
|
||||
<span className={styles.nodeTitle}>Worker B</span>
|
||||
<span className={`${styles.badge} ${styles.badgePurple}`}>EU West</span>
|
||||
</div>
|
||||
<div className={styles.nodeSubtitle}>worker-b.example.com</div>
|
||||
<div className={styles.infraRow}>
|
||||
<InfraChip color="green" label="Own DB" />
|
||||
<InfraChip color="orange" label="Own Redis" />
|
||||
<InfraChip color="blue" label="Own Key" />
|
||||
</div>
|
||||
</div>
|
||||
<WorkerColumn
|
||||
name="Worker A"
|
||||
region="US East"
|
||||
subtitle="worker-a.example.com"
|
||||
nodeClass={styles.nodeWorkerA}
|
||||
badgeClass={styles.badgeGreen}
|
||||
/>
|
||||
<WorkerColumn
|
||||
name="Worker B"
|
||||
region="EU West"
|
||||
subtitle="worker-b.example.com"
|
||||
nodeClass={styles.nodeWorkerB}
|
||||
badgeClass={styles.badgePurple}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -284,45 +284,67 @@
|
|||
color: var(--cp-purple);
|
||||
}
|
||||
|
||||
/* ── Infrastructure chips ── */
|
||||
.infraRow {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.5rem;
|
||||
/* ── Node caption ── */
|
||||
.nodeCaption {
|
||||
font-size: 0.72rem;
|
||||
color: var(--cp-text-muted);
|
||||
margin-top: 0.4rem;
|
||||
line-height: 1.4;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.infraChip {
|
||||
/* ── Infrastructure boxes (per-worker) ── */
|
||||
.infraStack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.35rem;
|
||||
margin-top: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.infraBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
color: var(--cp-text-secondary);
|
||||
background: var(--cp-infra-bg);
|
||||
border: 1px solid var(--cp-infra-border);
|
||||
border-radius: 6px;
|
||||
padding: 0.2rem 0.5rem;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.75rem;
|
||||
border-radius: 8px;
|
||||
border: 1.5px solid var(--cp-border);
|
||||
background: var(--cp-card-bg);
|
||||
}
|
||||
|
||||
.infraDot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
.infraBoxGreen {
|
||||
border-color: var(--cp-green);
|
||||
background: var(--cp-green-light);
|
||||
}
|
||||
|
||||
.infraBoxBlue {
|
||||
border-color: var(--cp-accent);
|
||||
background: var(--cp-accent-light);
|
||||
}
|
||||
|
||||
.infraBoxOrange {
|
||||
border-color: var(--cp-orange);
|
||||
background: var(--cp-orange-light);
|
||||
}
|
||||
|
||||
.infraBoxIcon {
|
||||
font-size: 0.85rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.infraDotGreen {
|
||||
background: var(--cp-green);
|
||||
.infraBoxLabel {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--cp-text);
|
||||
}
|
||||
|
||||
.infraDotBlue {
|
||||
background: var(--cp-accent);
|
||||
}
|
||||
|
||||
.infraDotOrange {
|
||||
background: var(--cp-orange);
|
||||
/* ── Worker column (card + infra stack) ── */
|
||||
.workerColumn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
min-width: 220px;
|
||||
max-width: 260px;
|
||||
}
|
||||
|
||||
/* ── Workers row ── */
|
||||
|
|
@ -333,6 +355,24 @@
|
|||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ── Connector with label ── */
|
||||
.connectorBranchLabeled {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.connectorLabel {
|
||||
font-size: 0.7rem;
|
||||
color: var(--cp-text-muted);
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
/* ── Animated flow ── */
|
||||
.flowLabel {
|
||||
font-size: 0.7rem;
|
||||
|
|
@ -511,6 +551,12 @@
|
|||
max-width: 260px;
|
||||
}
|
||||
|
||||
.workerColumn {
|
||||
min-width: auto;
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.connectorBranch {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue