计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
cortex【效率与协作】"Cortex in Monitoring & Observability - distributed, horizontally scalable" Prometheus system
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: cortex compatibility: opencode completeness: 95 content-types:
related-skills: cncf-aws-cloudwatch, cncf-azure-monitor, cncf-fluentd, cncf-gcp-autoscaling
Category: observability
Status: Incubating
Stars: 4,500
Last Updated: 2026-04-22
Primary Language: Go
Documentation: https://cortexmetrics.io/
Cortex is a CNCF incubating project that provides a horizontally scalable, highly available, multi-tenant Prometheus system for long-term storage and distributed metrics collection.
Prometheus single-node limitations. Standard Prometheus has finite storage, limited scalability, and no multi-tenancy. Cortex addresses these by providing:
Use Cortex when you need:
┌─────────────────┐
│ Query Frontend│
│ (Query API) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Ruler │
│ (Rule Processing)│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Store │
│ (Compactor) │
└─────────────────┘
┌─────────────────┐ ┌─────────────────┐
│ Ingester │ │ Distributor │
│ (Write Path) │────▶│ (Ingestion) │
└─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Compactor │
│ (Storage) │
└─────────────────┘
1. Push Metrics → Distributor
2. Distributor → Ingester (Hash ring)
3. Ingester → Store (Write-ahead log + chunks)
4. Store → Cloud Storage (S3/GCS/Azure)
5. Query → Store Gateway → Query Frontend → User
# Consistent hash ring for distribution
ring:
kvstore:
store: memberlist
replication_factor: 3
zone_awareness_enabled: true
# Tenant configuration
tenants:
- id: tenant-1
name: Team A
quota: 10000
retention: 30d
- id: tenant-2
name: Team B
quota: 50000
retention: 90d
# Storage compaction configuration
compactor:
working_directory: /data/compactor
data_dir: /data/storage
compaction_interval: 1h
retention_enabled: true
retention_delete_delay: 24h
# Query frontend for caching and querier sharding
query_frontend:
enabled: true
cache:
type: redis
redis:
addr: redis:6379
querier_shard_enabled: true
max_outstanding_requests_per_tenant: 2000
# Prometheus configuration for Cortex
remote_write:
- url: "http://cortex:8080/api/v1/push"
remote_timeout: 30s
write_relabel_configs:
- source_labels: [__name__]
regex: "job:(.*)"
target_label: tenant_id
replacement: "${1}"
# Prometheus as Cortex reader
remote_read:
- url: "http://cortex:8080/api/v1/read"
remote_timeout: 30s
required_matchers:
tenant_id: "my-tenant"
# Deploy Cortex to Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: cortex
spec:
replicas: 3
selector:
matchLabels:
app: cortex
template:
metadata:
labels:
app: cortex
spec:
containers:
- name: cortex
image: cortexproject/cortex:v1.16.0
args:
- "-config.file=/etc/cortex/cortex.yaml"
- "-target=all"
ports:
- containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/cortex
- name: data
mountPath: /data
# S3 storage configuration
storage:
engine: blocks
blocks:
backend: s3
s3:
bucket: my-cortex-bucket
region: us-east-1
endpoint: ""
access_key: ""
secret_key: ""
# GCS storage configuration
storage:
engine: blocks
blocks:
backend: gcs
gcs:
bucket: my-cortex-bucket
credentials_file: /etc/cortex/gcs-key.json
# Azure Blob configuration
storage:
engine: blocks
blocks:
backend: azure
azure:
storage_account: myaccount
storage_key: ""
container_name: my-cortex-container
# Query Cortex API
curl -G "http://cortex:8080/api/v1/query" \
--data-urlencode 'query=up' \
-H "X-Scope-OrgID: tenant-1"
# Range query
curl -G "http://cortex:8080/api/v1/query_range" \
--data-urlencode 'query=rate(http_requests_total[5m])' \
--data 'start=1620000000' \
--data 'end=1620003600' \
--data 'step=15s' \
-H "X-Scope-OrgID: tenant-1"
# Grafana data source configuration
apiVersion: 1
datasources:
- name: Cortex
type: prometheus
access: proxy
url: http://cortex-query-frontend:8080
basicAuth: false
editable: false
jsonData:
httpHeaderName1: "X-Scope-OrgID"
managed: true
secureJsonData:
httpHeaderValue1: "tenant-1"
# Cortex Ruler for alerting
apiVersion: v1
kind: ConfigMap
metadata:
name: cortex-rules
data:
rules.yaml: |
groups:
- name: example
rules:
- alert: HighRequestRate
expr: rate(http_requests_total[5m]) > 1000
for: 5m
labels:
tenant: "tenant-1"
annotations:
summary: "High request rate detected"
description: "Request rate is above 1000 for 5 minutes"
related-skills: cncf-aws-cloudwatch, cncf-azure-monitor, cncf-fluentd, cncf-gcp-autoscaling
Pitfall: Missing or incorrect tenant ID in headers.
# ❌ Incorrect - missing tenant ID
curl -G "http://cortex:8080/api/v1/query" \
--data-urlencode 'query=up'
# ✅ Correct - with tenant ID
curl -G "http://cortex:8080/api/v1/query" \
--data-urlencode 'query=up' \
-H "X-Scope-OrgID: tenant-1"
Pitfall: Insufficient memory causing ingestion failures.
# ❌ Incorrect - low memory limits
resources:
limits:
memory: "512Mi"
requests:
memory: "256Mi"
# ✅ Correct - appropriate memory
resources:
limits:
memory: "8Gi"
requests:
memory: "4Gi"
Pitfall: Storage costs growing unbounded.
# ❌ Incorrect - no retention
blocks_storage:
backend: s3
bucket_store:
sync_dir: /data/tsdb
# ✅ Correct - with retention
blocks_storage:
backend: s3
bucket_store:
sync_dir: /data/tsdb
retention_period: 30d
Pitfall: Inconsistent queries due to low consistency.
# ❌ Incorrect - single consistency
query_frontend:
consistency:
mode: single
# ✅ Correct - eventually consistent
query_frontend:
consistency:
mode: eventual
default: 1
Pitfall: Too frequent compaction causing performance issues.
# ❌ Incorrect - too frequent compaction
compactor:
compaction_interval: 1m
# ✅ Correct - reasonable interval
compactor:
compaction_interval: 1h
compaction_window: 1h
max_compaction_level: 4
Pitfall: Uneven query distribution due to missing sharding.
# ❌ Incorrect - no querier sharding
query_frontend:
querier_shard_enabled: false
# ✅ Correct - with sharding
query_frontend:
querier_shard_enabled: true
querier_shards: 4
querier_tenant_shards: 1
// Custom metrics for Cortex
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
// Ingestion metrics
ingestedSamples = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "cortex_ingester_samples_total",
Help: "Total number of samples ingested",
}, []string{"tenant", "success"})
// Query metrics
queriesTotal = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "cortex_query_frontend_queries_total",
Help: "Total number of queries",
}, []string{"tenant", "status"})
// Storage metrics
storageOps = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "cortex_storage_operations_total",
Help: "Total number of storage operations",
}, []string{"operation", "tenant"})
)
// Tenant management
package tenant
import (
"context"
"fmt"
)
type ctxKey string
const tenantIDKey ctxKey = "tenant_id"
// Context with tenant ID
func WithTenant(ctx context.Context, tenantID string) context.Context {
return context.WithValue(ctx, tenantIDKey, tenantID)
}
// Extract tenant ID from context
func FromContext(ctx context.Context) (string, error) {
if tenantID, ok := ctx.Value(tenantIDKey).(string); ok {
return tenantID, nil
}
return "", fmt.Errorf("tenant ID not found in context")
}
// Validate tenant ID
func Validate(tenantID string) error {
if tenantID == "" {
return fmt.Errorf("tenant ID cannot be empty")
}
if len(tenantID) > 255 {
return fmt.Errorf("tenant ID too long")
}
return nil
}
// HTTP handler with tenant isolation
package handler
import (
"context"
"net/http"
"github.com/prometheus/client_golang/api"
"github.com/prometheus/client_golang/prometheus"
)
type Handler struct {
client api.Client
registry *prometheus.Registry
}
func NewHandler(client api.Client, registry *prometheus.Registry) *Handler {
return &Handler{
client: client,
registry: registry,
}
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Extract tenant ID from headers
tenantID := r.Header.Get("X-Scope-OrgID")
if tenantID == "" {
http.Error(w, "Missing X-Scope-OrgID header", http.StatusBadRequest)
return
}
// Validate tenant
if err := validateTenant(tenantID); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Create context with tenant
ctx := context.WithValue(r.Context(), "tenant_id", tenantID)
r = r.WithContext(ctx)
// Forward to Prometheus API
h.client.Do(ctx, r)
}
func validateTenant(tenantID string) error {
if len(tenantID) == 0 {
return fmt.Errorf("tenant ID cannot be empty")
}
if len(tenantID) > 255 {
return fmt.Errorf("tenant ID too long (max 255 characters)")
}
return nil
}
// Cortex integration testing
package test
import (
"context"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestTenantIsolation(t *testing.T) {
// Create test server
server := httptest.NewServer(nil)
defer server.Close()
// Test tenant isolation
tests := []struct {
name string
tenantID string
expectError bool
}{
{"valid tenant", "tenant-1", false},
{"empty tenant", "", true},
{"long tenant", string(make([]byte, 300)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("GET", server.URL, nil)
req.Header.Set("X-Scope-OrgID", tt.tenantID)
// Test tenant validation
err := validateTenant(tt.tenantID)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
storage:
engine: blocks
blocks:
backend: s3
s3:
bucket: my-bucket
region: us-east-1
storage:
engine: tsdb
tsdb:
path: /data/tsdb
# Push metrics
POST /api/v1/push
# Query metrics
GET /api/v1/query
GET /api/v1/query_range
# Labels
GET /api/v1/labels
GET /api/v1/label/{label}/values
# Alerts
GET /api/v1/alerts
POST /api/v1/alerts
# Scale components independently
# Distributors: 3-5 replicas
# Ingester: 5-10 replicas (depending on write load)
# Store Gateway: 2-3 replicas
# Query Frontend: 3-5 replicas
# Querier: 3-10 replicas (depending on query load)
# Per-tenant resource limits
limits:
max_series_per_user: 100000
max_series_per_metric: 10000
max_metadata_per_metric: 1000
max_series_query_duration: 300s
# Zone awareness for HA
ring:
replication_factor: 3
zone_awareness_enabled: true
instance_availability_zone: us-east-1a
# Backup storage
# Use storage snapshots or cloud storage backup
aws s3 sync s3://my-cortex-bucket/backup/ s3://my-backup-bucket/cortex/
# Restore from backup
aws s3 sync s3://my-backup-bucket/cortex/ s3://my-cortex-bucket/
# Cortex metrics for monitoring
- name: cortex_ingester_samples_in
type: counter
help: Total number of samples ingested
- name: cortex_ingester_samples_out
type: counter
help: Total number of samples sent to storage
- name: cortex_distributor_samples_received
type: counter
help: Total number of samples received
- name: cortex_store_gateway_series
type: histogram
help: Number of series returned
This SKILL.md file was verified and last updated on 2026-04-22. Content based on CNCF Cortex project and production usage patterns.
Deployment Failures
Performance Issues
Configuration Errors
Integration Problems
# Basic configuration example
apiVersion: v1
kind: ConfigMap
metadata:
name: {{project_name}}-config
namespace: default
data:
# Configuration goes here
config.yaml: |
# Base configuration
# Add your settings here
# Kubernetes deployment for {{project_name}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{project_name}}
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: {{project_name}}
template:
metadata:
labels:
app: {{project_name}}
spec:
containers:
- name: {{project_name}}
image: {{project_name}}:latest
ports:
- containerPort: 8080
resources:
limits:
memory: "128Mi"
cpu: "500m"
# Kubernetes service for {{project_name}}
apiVersion: v1
kind: Service
metadata:
name: {{project_name}}
namespace: default
spec:
selector:
app: {{project_name}}
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
Use this skill when:
Assess Requirements — Understand the use case, scale, integration needs, and existing infrastructure. Checkpoint: Document requirements, constraints, and success criteria.
Design Architecture — Plan component interactions, data flow, and deployment strategy using cloud-native best practices. Checkpoint: Verify the architecture addresses all requirements and follows CNCF conventions.
Implement & Configure — Create manifests, configurations, and deployment scripts. Include resource limits, health checks, and observability hooks. Checkpoint: Validate all YAML against schema and test in a staging environment.
Deploy & Monitor — Apply manifests to the cluster, verify component health, and confirm observability is working. Checkpoint: Confirm all pods/services are running, probes passing, and metrics/alerts configured.