diff --git a/docs/docs/_index.md b/docs/docs/_index.md index 7c3180483..9be60dc7c 100644 --- a/docs/docs/_index.md +++ b/docs/docs/_index.md @@ -1,5 +1,5 @@ --- -title: "Documentation" +title: "Introduction" linkTitle: "Documentation" weight: 20 menu: @@ -7,98 +7,16 @@ menu: 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 -p '{"metadata":{"finalizers":null}}' --type=merge +helm upgrade -i grafana-operator oci://ghcr.io/grafana/helm-charts/grafana-operator --version {{}} ``` -After running this, the resource can be deleted as usual. +For a detailed installation guide, refer to [the installation documentation]({{}}). + +To get started, take a look at the [quick start guide]({{}}). diff --git a/docs/docs/alerting.md b/docs/docs/alerting.md new file mode 100644 index 000000000..c2ee48fbe --- /dev/null +++ b/docs/docs/alerting.md @@ -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. +{{% /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" >}} diff --git a/docs/docs/api.md b/docs/docs/api.md index e4ecfe94a..1bcae062c 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -1,6 +1,6 @@ --- title: API Reference -weight: 1 +weight: 100 --- Packages: diff --git a/docs/docs/overview.md b/docs/docs/overview.md new file mode 100644 index 000000000..b3ccec6cf --- /dev/null +++ b/docs/docs/overview.md @@ -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 -p '{"metadata":{"finalizers":null}}' --type=merge +``` + +After running this, the resource can be deleted as usual. diff --git a/docs/docs/quick-start.md b/docs/docs/quick-start.md new file mode 100644 index 000000000..50fe6031a --- /dev/null +++ b/docs/docs/quick-start.md @@ -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 {{}} +``` + +This will install the grafana operator in the current namespace. + +For a detailed installation guide, check out [the installation documentation]({{}}). + +## 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. diff --git a/hugo/templates/frontmatter-grafana-operator.tmpl b/hugo/templates/frontmatter-grafana-operator.tmpl index d8b18475a..0b9e0e460 100644 --- a/hugo/templates/frontmatter-grafana-operator.tmpl +++ b/hugo/templates/frontmatter-grafana-operator.tmpl @@ -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}}