Skip to content

Commit 15b2e6c

Browse files
authored
Reorganise the production docs (#2218)
* Reorganise the docs, make it clearer the steps needed to get Cortex into production. - Split out the capacity planning and schema docs. - Add words for HA pair handling. - Move all the production related docs into their own section. Signed-off-by: Tom Wilkie <[email protected]>
1 parent dd23765 commit 15b2e6c

17 files changed

+261
-267
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Read the [getting started guide](https://cortexmetrics.io/docs/getting-started)
2525
project. Before deploying Cortex with a permanent storage backend you
2626
should read:
2727
1. [An overview of Cortex's architecture](https://cortexmetrics.io/docs/architecture/)
28-
1. [A general guide to running Cortex](https://cortexmetrics.io/docs/guides/running-in-production/)
28+
1. [A guide to running Cortex](https://cortexmetrics.io/docs/guides/production/)
2929
1. [Information regarding configuring Cortex](https://cortexmetrics.io/docs/configuration/arguments/)
3030
1. [Steps to run Cortex with Cassandra](https://cortexmetrics.io/docs/guides/cassandra/)
3131

docs/_index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ project. Before deploying Cortex with a permanent storage backend you
3333
should read:
3434

3535
1. [An overview of Cortex's architecture](architecture.md)
36-
1. [A general guide to running Cortex](running.md)
37-
1. [Information regarding configuring Cortex](arguments.md)
36+
1. [A guide to running Cortex](production/running.md)
37+
1. [Information regarding configuring Cortex](configuration/arguments.md)
3838

3939
For a guide to contributing to Cortex, see the [contributor guidelines](contributing/).
4040

docs/architecture.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Cortex Architecture"
33
linkTitle: "Architecture"
4-
weight: 4
4+
weight: 2
55
slug: architecture
66
---
77

@@ -48,7 +48,7 @@ Internally, the access to the chunks storage relies on a unified interface calle
4848

4949
The chunk and index format are versioned, this allows Cortex operators to upgrade the cluster to take advantage of new features and improvements. This strategy enables changes in the storage format without requiring any downtime or complex procedures to rewrite the stored data. A set of schemas are used to map the version while reading and writing time series belonging to a specific period of time.
5050

51-
The current schema recommendation is the **v10 schema** (v11 is still experimental). For more information about the schema, please check out the [Schema](guides/running.md#schema) documentation.
51+
The current schema recommendation is the **v10 schema** (v11 is still experimental). For more information about the schema, please check out the [Schema](configuration/schema-config-reference.md) documentation.
5252

5353
### Blocks storage (experimental)
5454

@@ -107,7 +107,7 @@ The supported KV stores for the HA tracker are:
107107
* [Consul](https://www.consul.io)
108108
* [Etcd](https://etcd.io)
109109

110-
For more information, please refer to [config for sending HA pairs data to Cortex](guides/ha-pair-handling.md) in the documentation.
110+
For more information, please refer to [config for sending HA pairs data to Cortex](production/ha-pair-handling.md) in the documentation.
111111

112112
#### Hashing
113113

@@ -223,11 +223,11 @@ The query frontend supports caching query results and reuses them on subsequent
223223

224224
The **ruler** is an **optional service** executing PromQL queries for recording rules and alerts. The ruler requires a database storing the recording rules and alerts for each tenant.
225225

226-
Ruler is **semi-stateful** and can be scaled horizontally.
227-
Running rules internally have state, as well as the ring the rulers initiate.
228-
However, if the rulers all fail and restart,
229-
Prometheus alert rules have a feature where an alert is restored and returned to a firing state
230-
if it would have been active in its for period.
226+
Ruler is **semi-stateful** and can be scaled horizontally.
227+
Running rules internally have state, as well as the ring the rulers initiate.
228+
However, if the rulers all fail and restart,
229+
Prometheus alert rules have a feature where an alert is restored and returned to a firing state
230+
if it would have been active in its for period.
231231
However, there would be gaps in the series generated by the recording rules.
232232

233233
### Alertmanager

docs/getting-started/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Getting Started"
33
linkTitle: "Getting Started"
4-
weight: 3
4+
weight: 1
55
menu:
66
---

docs/guides/capacity-planning.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
title: "Capacity Planning"
3+
linkTitle: "Capacity Planning"
4+
weight: 104
5+
slug: capacity-planning
6+
---
7+
8+
9+
You will want to estimate how many nodes are required, how many of
10+
each component to run, and how much storage space will be required.
11+
In practice, these will vary greatly depending on the metrics being
12+
sent to Cortex.
13+
14+
Some key parameters are:
15+
16+
1. The number of active series. If you have Prometheus already you
17+
can query `prometheus_tsdb_head_series` to see this number.
18+
2. Sampling rate, e.g. a new sample for each series every minute
19+
(the default Prometheus [scrape_interval](https://prometheus.io/docs/prometheus/latest/configuration/configuration/)).
20+
Multiply this by the number of active series to get the
21+
total rate at which samples will arrive at Cortex.
22+
3. The rate at which series are added and removed. This can be very
23+
high if you monitor objects that come and go - for example if you run
24+
thousands of batch jobs lasting a minute or so and capture metrics
25+
with a unique ID for each one. [Read how to analyse this on
26+
Prometheus](https://www.robustperception.io/using-tsdb-analyze-to-investigate-churn-and-cardinality).
27+
4. How compressible the time-series data are. If a metric stays at
28+
the same value constantly, then Cortex can compress it very well, so
29+
12 hours of data sampled every 15 seconds would be around 2KB. On
30+
the other hand if the value jumps around a lot it might take 10KB.
31+
There are not currently any tools available to analyse this.
32+
5. How long you want to retain data for, e.g. 1 month or 2 years.
33+
34+
Other parameters which can become important if you have particularly
35+
high values:
36+
37+
6. Number of different series under one metric name.
38+
7. Number of labels per series.
39+
8. Rate and complexity of queries.
40+
41+
Now, some rules of thumb:
42+
43+
1. Each million series in an ingester takes 15GB of RAM. Total number
44+
of series in ingesters is number of active series times the
45+
replication factor. This is with the default of 12-hour chunks - RAM
46+
required will reduce if you set `-ingester.max-chunk-age` lower
47+
(trading off more back-end database IO)
48+
2. Each million series (including churn) consumes 15GB of chunk
49+
storage and 4GB of index, per day (so multiply by the retention
50+
period).
51+
3. Each 100,000 samples/sec arriving takes 1 CPU in distributors.
52+
Distributors don't need much RAM.
53+
54+
If you turn on compression between distributors and ingesters (for
55+
example to save on inter-zone bandwidth charges at AWS/GCP) they will use
56+
significantly more CPU (approx 100% more for distributor and 50% more
57+
for ingester).

docs/guides/ingester-handover.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Ingester Hand-over"
33
linkTitle: "Ingester Hand-over"
4-
weight: 5
4+
weight: 102
55
slug: ingester-handover
66
---
77

docs/guides/kubernetes.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
title: "Running Cortex on Kubernetes"
3+
linkTitle: "Running Cortex on Kubernetes"
4+
weight: 100
5+
slug: kubernetes
6+
---
7+
8+
Because Cortex is designed to run multiple instances of each component
9+
(ingester, querier, etc.), you probably want to automate the placement
10+
and shepherding of these instances. Most users choose Kubernetes to do
11+
this, but this is not mandatory.
12+
13+
## Configuration
14+
15+
### Resource requests
16+
17+
If using Kubernetes, each container should specify resource requests
18+
so that the scheduler can place them on a node with sufficient capacity.
19+
20+
For example an ingester might request:
21+
22+
```
23+
resources:
24+
requests:
25+
cpu: 4
26+
memory: 10Gi
27+
```
28+
29+
The specific values here should be adjusted based on your own
30+
experiences running Cortex - they are very dependent on rate of data
31+
arriving and other factors such as series churn.
32+
33+
### Take extra care with ingesters
34+
35+
Ingesters hold hours of timeseries data in memory; you can configure
36+
Cortex to replicate the data but you should take steps to avoid losing
37+
all replicas at once:
38+
39+
- Don't run multiple ingesters on the same node.
40+
- Don't run ingesters on preemptible/spot nodes.
41+
- Spread out ingesters across racks / availability zones / whatever
42+
applies in your datacenters.
43+
44+
You can ask Kubernetes to avoid running on the same node like this:
45+
46+
```
47+
affinity:
48+
podAntiAffinity:
49+
preferredDuringSchedulingIgnoredDuringExecution:
50+
- weight: 100
51+
podAffinityTerm:
52+
labelSelector:
53+
matchExpressions:
54+
- key: name
55+
operator: In
56+
values:
57+
- ingester
58+
topologyKey: "kubernetes.io/hostname"
59+
```
60+
61+
Give plenty of time for an ingester to hand over or flush data to
62+
store when shutting down; for Kubernetes this looks like:
63+
64+
```
65+
terminationGracePeriodSeconds: 2400
66+
```
67+
68+
Ask Kubernetes to limit rolling updates to one ingester at a time, and
69+
signal the old one to stop before the new one is ready:
70+
71+
```
72+
strategy:
73+
rollingUpdate:
74+
maxSurge: 0
75+
maxUnavailable: 1
76+
```
77+
78+
Ingesters provide an HTTP hook to signal readiness when all is well;
79+
this is valuable because it stops a rolling update at the first
80+
problem:
81+
82+
```
83+
readinessProbe:
84+
httpGet:
85+
path: /ready
86+
port: 80
87+
```
88+
89+
We do not recommend configuring a liveness probe on ingesters -
90+
killing them is a last resort and should not be left to a machine.

0 commit comments

Comments
 (0)