Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: restructure documentation #1466

Merged
merged 3 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 9 additions & 91 deletions docs/docs/_index.md
Original file line number Diff line number Diff line change
@@ -1,104 +1,22 @@
---
title: "Documentation"
title: "Introduction"
linkTitle: "Documentation"
weight: 20
menu:
main:
weight: 20
---

Our official documentation for the operator.
Hopefully you will find everything you need in here, if not feel free to open an issue, write on slack or even better submit a pr.
The Grafana operator allows you to:
* ⚙️ Deploy & Manage Grafana Instances inside of Kubernetes with ease
* 🌐 Manage externally hosted instances using Kubernetes resources (for example Grafana Cloud)

## Examples

Just like in v4 we have a number of [examples](examples/) to look at.

## ResyncPeriod

Grafana doesn't have any webhooks or similar ways of giving information to the operator that a grafana resource, like a dashboard, has been changed.
Due to this the Grafana operator has to constantly check the Grafana API to see if something changed in the dashboard.

That is why we introduced `spec.resyncPeriod`, this is a configuration that makes it possible to tell the operator
how often it should check with the Grafana instance if the dashboard matches the settings that are defined in the Kubernetes CR.

So, if for example, a dashboard is changed, the operator will come in and overwrite those settings after `5m` by default.
If you never want the operator to check if the dashboards have changed you need to set this value to `0m`:

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafanadashboard-from-url
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
url: "https://grafana.com/api/dashboards/7651/revisions/44/download"
resyncPeriod: 0m
```

This can of course be annoying for your dashboard developers. But we recommend that before doing any change to a dashboard in the Grafana UI that you first copy the existing dashboard and work on the copy instead.
When you are finished with your changes export the changes and update the dashboard CR.

## InstanceSelector

For the operator to know which dashboard, datasource or folder that should be applied to a specific Grafana instance we use `instanceSelectors`.

It's the normal label selector that is built in to [Kubernetes](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) and for example used in deployments.
So you should hopefully be fairly used to how it works.

But in short you define a label on your Grafana instance.

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
labels:
dashboards: "grafana" # Notice the label
spec: ...
```

And for example in the dashboard we define a instanceSelector.

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafanadashboard-sample
spec:
resyncPeriod: 30s
instanceSelector:
matchLabels:
dashboards: "grafana" # Notice the label
json: ...
```

## Cross namespace grafana instances

As described in [#44](https://github.com/grafana-operator/grafana-operator-experimental/issues/44) we didn't want it
to be to easy to get access to a grafana datasource that wasn't defined the same namespace as the grafana instance.

To solve this we introduced `spec.allowCrossNamespaceImport` option to, dashboards, datasources and folders to be false by default.
This setting makes it so a grafana instance in another namespace don't get the grafana resources applied to it even if the label matches.

This is because especially the data sources contain secret information and we don't want another team to be able to use your datasource unless defined to do so in both CR:s.

## Using a proxy server

The Operator can use a proxy server when fetching URL-based / Grafana.com dashboards or making requests to external Grafana instances.
The proxy settings can be controlled through environment variables as documented [here](https://pkg.go.dev/golang.org/x/net/http/httpproxy#FromEnvironment).

## Deleting resources with a finalizer

The operator marks some resources with [finalizers](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/) to clean up resources on deletion.
If the operator is not running, marked resources are unable to be deleted. This is intended.
However, this behavior can cause issues if, for example, you uninstalled the operator and now can't remove resources.
To manually remove the finalizer, use the following command:
To install the Grafana Operator in your Kubernetes cluster, Run the following command in your terminal:

```bash
kubectl patch GrafanaAlertRuleGroup <rule-group-name> -p '{"metadata":{"finalizers":null}}' --type=merge
helm upgrade -i grafana-operator oci://ghcr.io/grafana/helm-charts/grafana-operator --version {{<param version>}}
```

After running this, the resource can be deleted as usual.
For a detailed installation guide, refer to [the installation documentation]({{<relref installation>}}).

To get started, take a look at the [quick start guide]({{<relref quick-start.md>}}).
26 changes: 26 additions & 0 deletions docs/docs/alerting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Alerting
weight: 13
---
{{% pageinfo color="primary" %}}
Alerting resources require Grafana version 9.5 or higher.
{{% /pageinfo %}}

The Grafana Operator currently only supports _Grafana Managed Alerts_.

For data source managed alerts, refer to the documentation and tooling available for the respective data source.
{{% alert title="Note" color="primary" %}}
When using Mimir/Prometheus, you can use the [`mimir.rules.kubernetes`](https://grafana.com/docs/agent/latest/flow/reference/components/mimir.rules.kubernetes/) component of the Grafana Agent to deploy rules as Kubernetes resources.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG, I didn't know about this feature. This just got bumped to the top of our TODO internally <3

{{% /alert %}}


## Alert rule groups

Alert Rule Groups contain a list of alerts which should evaluate at the same interval.
Every rule group must belong to a folder and contain at least one rule.

The easiest way to get the YAML specification for an alert rule is to use the [modify export feature](https://grafana.com/docs/grafana/latest/alerting/set-up/provision-alerting-resources/export-alerting-resources/), introduced in Grafana 10.

The following snippet shows an example alert rule group with a single alert that fires when the temperature is below zero degrees.

{{< readfile file="examples/alertrulegroups/resources.yaml" code="true" lang="yaml" >}}
2 changes: 1 addition & 1 deletion docs/docs/api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: API Reference
weight: 1
weight: 100
---

Packages:
Expand Down
91 changes: 91 additions & 0 deletions docs/docs/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: Common options
weight: 11
---

## ResyncPeriod

Grafana doesn't have any webhooks or similar ways of giving information to the operator that a Grafana resource, like a dashboard, has changed.
Due to this the Grafana operator has to constantly poll the Grafana API to test for changes in the dashboard.

To avoid control how often this polling should occur, you can set the `spec.resyncPeriod` field.
This field tells the operator how often it should poll the Grafana instance for changes.

So, if for example, a dashboard has changed, the operator comes in and overwrite those settings after `5m` by default.
If you never want the operator to poll for changes in the dashboards you need to set this value to `0m`:

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafanadashboard-from-url
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
url: "https://grafana.com/api/dashboards/7651/revisions/44/download"
resyncPeriod: 0m
```

This can of course be annoying for your dashboard developers. The recommended workflow is to copy the dashboard and work on the copy instead.
When you finish your changes, export the changes and update the dashboard CR.

## InstanceSelector

The `spec.instanceSelectors` field is used to tell the operator which Grafana instance the resource applies to.

It's a regular [Kubernetes label selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) and for example used in deployments.

To link resources to instances, first define a label on your Grafana instance:

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
labels:
dashboards: "grafana" # Notice the label
spec: ...
```

And in the resource, set the `spec.instanceSelector` to match the previously set labels.

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafanadashboard-sample
spec:
resyncPeriod: 30s
instanceSelector:
matchLabels:
dashboards: "grafana" # Notice the label
json: ...
```

## Cross namespace Grafana instances

To avoid exposing possible sensitive data sources to arbitrary instances, resources only affect instances in the same namespace.

In case you need this functionality for your specific setup, use the `spec.allowCrossNamespaceImport` field of the Grafana instance.
This setting allows resources in arbitrary namespaces to be applied to the Grafana instance.

More information can be found in [#44](https://github.com/grafana-operator/grafana-operator-experimental/issues/44).

## Using a proxy server

The Operator can use a proxy server when fetching URL-based / Grafana.com dashboards or making requests to external Grafana instances.
[Environment variables](https://pkg.go.dev/golang.org/x/net/http/httpproxy#FromEnvironment) control the proxy

## Deleting resources with a finalizer

The operator marks some resources with [finalizers](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/) to clean up resources on deletion.
If the operator isn't running, marked resources are unable to be deleted. This is intended.
However, this behavior can cause issues if, for example, you uninstalled the operator and now can't remove resources.
To manually remove the finalizer, use the following command:

```bash
kubectl patch GrafanaAlertRuleGroup <rule-group-name> -p '{"metadata":{"finalizers":null}}' --type=merge
```

After running this, the resource can be deleted as usual.
144 changes: 144 additions & 0 deletions docs/docs/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: Quick Start
weight: 5
---

This guide will help you get started using the Grafana Operator.

To follow along, you will need:

* Cluster admin access to a Kubernetes cluster
* The Helm CLI installed locally

## Installing the Operator
To install the Grafana Operator in your Kubernetes cluster, Run the following command in your terminal:

```bash
helm upgrade -i grafana-operator oci://ghcr.io/grafana/helm-charts/grafana-operator --version {{<param version>}}
```

This will install the grafana operator in the current namespace.

For a detailed installation guide, check out [the installation documentation]({{<relref installation>}}).

## Creating a Grafana instance

The `Grafana` custom resource describes the deployment of a single Grafana instance. A minimal starting point looks like this:

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
labels:
dashboards: "grafana"
spec:
config:
security:
admin_user: root
admin_password: secret
```

Save this to a file called `grafana.yaml` and apply it using `kubectl apply -f grafana.yaml`

This creates a Grafana deployment in the same namespace as the `Grafana` resource.

Run `kubectl get pods -w` to see the status of the deployment. Once the `grafana-deployment` pod is ready, continue to the next step.

## Adding a data source

The operator uses the `GrafanaDatasource` resource to configure data sources in Grafana.

An example data source connecting to a Prometheus backend is provided below:
```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: prometheus
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
datasource:
name: prom1
type: prometheus
access: proxy
url: http://prometheus-service:9090
isDefault: true
jsonData:
'tlsSkipVerify': true
'timeInterval': "5s"
editable: true
```

Save the file to `datasource.yaml` and apply it using `kubectl apply -f datasource.yaml`

It is important that the `instanceSelector` matches the `metadata.labels` field of the Grafana instance.
Otherwise the data source will not show up.


## Adding a dashboard

Adding a dashboard works the same way data sources do.
The `GrafanaDashboard` resource provides the dashboard specification as well as the `instanceSelector`.

Dashboards can be defined through JSON, jsonnet, a grafana.com dashboard catalog ID or a remote url.
For more information, check out our examples.

Using JSON directly embedded into the resource is the simplest approach.
The following resource defines a dashboard with a single panel:

```yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: example-dashboard
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
json: >
{
"annotations": {},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 222,
"links": [],
"panels": [
{
"gridPos": {
"h": 3,
"w": 8,
"x": 8,
"y": 0
},
"id": 1,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "# Greetings from the Grafana Operator!",
"mode": "markdown"
},
"type": "text"
}
],
"schemaVersion": 39,
"tags": [],
"time": {
"from": "now-6h",
"to": "now"
},
"timeRangeUpdatedDuringEditOrView": false,
"timepicker": {},
"timezone": "browser",
"title": "Example Dashboard",
"weekStart": ""
}
```
Save the file to `dashboard.yaml` and apply it using `kubectl apply -f dashboard.yaml`

You will find the dashboard in a folder with the same name as your namespace.
2 changes: 1 addition & 1 deletion hugo/templates/frontmatter-grafana-operator.tmpl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: {{or .Metadata.Title "API Reference"}}
weight: {{or .Metadata.Weight 1 }}
weight: {{or .Metadata.Weight 100 }}
{{- if .Metadata.Description}}
description: {{.Metadata.Description}}
{{- end}}
Expand Down
Loading