<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Set up GEM on Grafana Labs</title><link>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/</link><description>Recent content in Set up GEM on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/enterprise-metrics/v1.7.x/setup/index.xml" rel="self" type="application/rss+xml"/><item><title>Deploy on Linux</title><link>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/linux/</link><pubDate>Mon, 11 Apr 2022 17:01:18 +0100</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/linux/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-gem-on-a-linux-host&#34;&gt;Deploy GEM on a Linux host&lt;/h1&gt;
&lt;p&gt;This guide provides a step by step process for installing Grafana Enterprise Metrics on a Linux machine. It assumes you have access to a Linux machine and the permissions required to deploy a service with network and filesystem access. At the end of this guide you will have deployed a single GEM instance on a single node.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;In order to follow this guide you will the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A valid Grafana Labs license with an associated GEM cluster name.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;setup-an-object-storage-bucket&#34;&gt;Setup an object storage bucket&lt;/h2&gt;
&lt;p&gt;To begin, you need access to an object storage backend. GEM uses object storage as a backend to store time series data as well as data related to the state of the system. This topic assumes that you are using &lt;a href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Amazon S3&lt;/a&gt; on the AWS &lt;code&gt;us-east-1&lt;/code&gt; region. If you plan on using a different region or object storage service, update the storage fields in the configuration file to match below to configure your desired service. Currently, the supported services are object storage backends that support the S3 API or Google GCS.&lt;/p&gt;
&lt;p&gt;After you have provisioned an object storage backend, be sure to pre-create two buckets: &lt;code&gt;grafana-metrics-admin&lt;/code&gt; and &lt;code&gt;grafana-metrics-tsdb&lt;/code&gt;. Those buckets will be referenced in the configuration file of this guide.&lt;/p&gt;
&lt;h2 id=&#34;prepare-your-system&#34;&gt;Prepare your system&lt;/h2&gt;
&lt;p&gt;Before running GEM, it is recommended you setup a system user and prepare the required directories on the filesystem. Run the following commands on every node as the root user. To login as the root user run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;sudo su -&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;add-dedicated-user-and-group&#34;&gt;Add dedicated user and group&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;groupadd --system ge-metrics
useradd --system --home-dir /var/lib/ge-metrics -g ge-metrics ge-metrics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;create-directories-and-assign-ownership&#34;&gt;Create directories and assign ownership&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;mkdir -p /etc/ge-metrics /var/lib/ge-metrics
chown ge-metrics:ge-metrics /etc/ge-metrics
chown ge-metrics:ge-metrics /var/lib/ge-metrics
chmod 0750 /etc/ge-metrics /var/lib/ge-metrics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;copy-the-license-file&#34;&gt;Copy the license file&lt;/h2&gt;
&lt;p&gt;You will need to ensure you license token file is copied to the path &lt;code&gt;/etc/ge-metrics/license.jwt&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;create-a-gem-configuration-file&#34;&gt;Create a GEM configuration file&lt;/h2&gt;
&lt;p&gt;Copy the following YAML config to a file called &lt;code&gt;/etc/ge-metrics/config.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;auth:
  type: enterprise

target: all

license:
  path: /etc/ge-metrics/license.jwt

admin_client:
  storage:
    type: s3
    s3:
      endpoint: s3.amazonaws.com
      bucket_name: grafana-metrics-admin
      access_key_id: # TODO: insert access key id here
      secret_access_key: # TODO: insert secret access key here
distributor:
  shard_by_all_labels: true
  pool:
    health_check_ingesters: true

memberlist:
  abort_if_cluster_join_fails: false
  bind_port: 7946

ingester:
  lifecycler:
    num_tokens: 512
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1

blocks_storage:
  tsdb:
    dir: /tmp/cortex/tsdb
  bucket_store:
    sync_dir: /tmp/cortex/tsdb-sync
  backend: s3
  s3:
    endpoint: s3.amazonaws.com
    bucket_name: grafana-metrics-tsdb
    access_key_id: # TODO: insert access key id here
    secret_access_key: # TODO: insert secret access key here

storage:
  engine: blocks&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Next you will need to update the config file and set the &lt;code&gt;blocks_storage.s3&lt;/code&gt; and &lt;code&gt;admin_client.storage.s3&lt;/code&gt; sections to include access credentials for your object storage backend.&lt;/p&gt;
&lt;h3 id=&#34;download-and-configure-the-gem-binary&#34;&gt;Download and configure the GEM binary&lt;/h3&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;curl -Lo /usr/local/bin/ge-metrics https://dl.grafana.com/gem/releases/metrics-enterprise-v1.7.0-linux-amd64
echo &amp;#34;262ca08136dc28eee92a6494981ee8de7a7dd859c7a3ea5afa53ff99a56eb42d /usr/local/bin/ge-metrics&amp;#34; | sha256sum -c
chmod 0755 /usr/local/bin/ge-metrics
setcap &amp;#39;cap_net_bind_service=&amp;#43;ep&amp;#39; /usr/local/bin/ge-metrics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;set-up-systemd-unit&#34;&gt;Set up systemd unit&lt;/h3&gt;
&lt;p&gt;Copy the following file to the path &lt;code&gt;/etc/systemd/system/ge-metrics.service&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;ini&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-ini&#34;&gt;[Unit]
After=network.target

[Service]
User=ge-metrics
Group=ge-metrics
WorkingDirectory=/var/lib/ge-metrics
ExecStart=/usr/local/bin/ge-metrics \
   -config.file=/etc/ge-metrics/config.yaml

[Install]
WantedBy=default.target&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;enable-startup-at-boot-timeand-start-grafana-enterprise-metrics&#34;&gt;Enable startup at boot timeand start Grafana Enterprise Metrics&lt;/h2&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;systemctl daemon-reload
systemctl enable ge-metrics.service
systemctl start ge-metrics.service&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;generate-an-admin-token&#34;&gt;Generate an admin token&lt;/h2&gt;
&lt;p&gt;Generate an admin token by running the following on a single node in the cluster:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;su ge-metrics -c &amp;#34;/usr/local/bin/ge-metrics \
--config.file=/etc/ge-metrics/config.yaml \
--target=tokengen&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The output of the above command should contain a token:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;Token created:  YWRtaW4tcG9saWN5LWJvb3RzdHJhcC10b2tlbjo8Ujc1IzQyfXBfMjd7fDIwMDRdYVxgeXw=&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;verify-your-cluster-is-working&#34;&gt;Verify your cluster is working&lt;/h2&gt;
&lt;p&gt;To verify your cluster is working you can run the following command using the token you generated in the previous step. For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;curl -u :YWRtaW4tcG9saWN5LWJvb3RzdHJhcC10b2tlbjo8Ujc1IzQyfXBfMjd7fDIwMDRdYVxgeXw= localhost/ready&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After running the above command you should see the following output:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;ready&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Now that you have a working GEM deployment locally, refer to &lt;a href=&#34;/docs/metrics-enterprise/latest/setup-gem-plugin-grafana/&#34;&gt;setup up the Grafana Enterprise Metrics plugin&lt;/a&gt; for instructions on how to integrate your metrics cluster with Grafana and give you a UI to interact with the &lt;a href=&#34;/docs/metrics-enterprise/latest/admin-api/&#34;&gt;Admin API&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="deploy-gem-on-a-linux-host">Deploy GEM on a Linux host&lt;/h1>
&lt;p>This guide provides a step by step process for installing Grafana Enterprise Metrics on a Linux machine. It assumes you have access to a Linux machine and the permissions required to deploy a service with network and filesystem access. At the end of this guide you will have deployed a single GEM instance on a single node.&lt;/p></description></item><item><title>Deploy on Kubernetes</title><link>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/kubernetes/</link><pubDate>Mon, 17 Mar 2025 14:18:51 +0100</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/kubernetes/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-gem-on-kubernetes&#34;&gt;Deploy GEM on Kubernetes&lt;/h1&gt;
&lt;p&gt;This guide will layout a step by step approach to deploying a Grafana Enterprise Metrics cluster on an existing Kubernetes namespace. This guide assumes you have a working Kubernetes cluster and the ability to deploy to that cluster using the &lt;code&gt;kubectl&lt;/code&gt; tool. At the end of this guide you should have a functional GEM cluster running on Kubernetes using Minio as a storage backend. If you do not currently have access to a Kubernetes cluster consider following &lt;a href=&#34;../linux&#34;&gt;Linux deployment guide instead&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;deploy-minio&#34;&gt;Deploy Minio&lt;/h2&gt;
&lt;p&gt;For this guide we will be using &lt;a href=&#34;https://minio.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Minio&lt;/a&gt; as our object storage backend. Minio is a open source S3 compatible object storage service that is freely available and easy to run on Kubernetes. If you want to follow this guide but use a different object storage backend, refer to &lt;a href=&#34;../../config/&#34;&gt;Grafana Enterprise Metrics configuration&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # This name uniquely identifies the PVC. Will be used in deployment below.
  name: minio-pv-claim
  labels:
    app: minio-storage-claim
spec:
  # Read more about access modes here: http://kubernetes.io/docs/user-guide/persistent-volumes/#access-modes
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    # This is the request for storage. Should be available in the cluster.
    requests:
      storage: 50Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: minio
spec:
  selector:
    matchLabels:
      app: minio
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        # Label is used as selector in the service.
        app: minio
    spec:
      # Refer to the PVC created earlier
      volumes:
        - name: storage
          persistentVolumeClaim:
            # Name of the PVC created earlier
            claimName: minio-pv-claim
      initContainers:
        - name: create-buckets
          image: busybox:1.28
          command:
            [
              &amp;#34;sh&amp;#34;,
              &amp;#34;-c&amp;#34;,
              &amp;#34;mkdir -p /storage/grafana-metrics-tsdb &amp;amp;&amp;amp; mkdir -p /storage/grafana-metrics-admin&amp;#34;,
            ]
          volumeMounts:
            - name: storage # must match the volume name, above
              mountPath: &amp;#34;/storage&amp;#34;
      containers:
        - name: minio
          # Pulls the default Minio image from Docker Hub
          image: minio/minio:latest
          args:
            - server
            - /storage
          env:
            # Minio access key and secret key
            - name: MINIO_ACCESS_KEY
              value: &amp;#34;minio&amp;#34;
            - name: MINIO_SECRET_KEY
              value: &amp;#34;minio123&amp;#34;
          ports:
            - containerPort: 9000
          volumeMounts:
            - name: storage # must match the volume name, above
              mountPath: &amp;#34;/storage&amp;#34;
---
apiVersion: v1
kind: Service
metadata:
  name: minio
spec:
  type: ClusterIP
  ports:
    - port: 9000
      targetPort: 9000
      protocol: TCP
  selector:
    app: minio&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Copy the above yaml into a file called &lt;code&gt;minio.yaml&lt;/code&gt; and run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create -f minio.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can confirm you have setup Minio correctly by port-forwarding it and navigating to it in your browser:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl port-forward service/minio 9000:9000&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then you can navigate to the minio admin console using your browser. The login credentials are the same as those set above, &lt;code&gt;minio&lt;/code&gt; and &lt;code&gt;minio123&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../assets/minio-in-browser.gif&#34;
  alt=&#34;minio-in-browser&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;create-a-license-secret&#34;&gt;Create a license Secret&lt;/h2&gt;
&lt;p&gt;Next you will need to take the &lt;code&gt;license.jwt&lt;/code&gt; file associated with you cluster and run the following command to load it as a Kubernetes Secret.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic ge-metrics-license --from-file license.jwt&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Verify you have successfully created the secret by running the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get secret ge-metrics-license -oyaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above command should print a kubernetes Secret object with a &lt;code&gt;license.jwt&lt;/code&gt; field with a long base64 encoded value string.&lt;/p&gt;
&lt;h2 id=&#34;create-a-gem-config-configmap&#34;&gt;Create a GEM config ConfigMap&lt;/h2&gt;
&lt;p&gt;Next you will create a configuration file for you cluster and deploy it as a Kubernetes ConfigMap. Copy the text and save it as &lt;code&gt;config.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;auth:
  type: enterprise

target: all

license:
  path: /etc/ge-metrics/license/license.jwt 

admin_client:
  storage:
    type: s3
    s3:
      endpoint: minio:9000
      bucket_name: grafana-metrics-admin 
      access_key_id: minio
      secret_access_key: minio123
      insecure: true

distributor:
  shard_by_all_labels: true
  pool:
    health_check_ingesters: true

memberlist:
  abort_if_cluster_join_fails: false
  bind_port: 7946
  join_members:
  - ge-metrics-discovery

ingester:
  lifecycler:
    num_tokens: 512
    ring:
      kvstore:
        store: memberlist
      replication_factor: 3

compactor:
  data_dir: &amp;#34;/data&amp;#34;
  sharding_enabled: true
  sharding_ring:
    kvstore:
      store: memberlist

blocks_storage:
  tsdb:
    dir: /data/cortex/tsdb
  bucket_store:
    sync_dir: /data/cortex/tsdb-sync
  backend: s3
  s3:
    endpoint: minio:9000
    bucket_name: grafana-metrics-tsdb
    access_key_id: minio
    secret_access_key: minio123 
    insecure: true 
storage:
  engine: blocks&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Next run the following command to create the ConfigMap.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create configmap ge-metrics-config --from-file=config.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;create-the-services-for-grafana-enterprise-metrics&#34;&gt;Create the services for Grafana Enterprise Metrics&lt;/h2&gt;
&lt;p&gt;Two Kubernetes Services are required to run Grafana Enterprise Metrics as a StatefulSet. First is a service to support GRPC requests between replicas. Second is a gossip service port to allow the replicas to join together and form a hash ring to coordinate work.&lt;/p&gt;
&lt;p&gt;Copy the following content into &lt;code&gt;services.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;---
apiVersion: v1
kind: Service
metadata:
  labels:
    name: ge-metrics-discovery
  name: ge-metrics-discovery
spec:
  clusterIP: None
  ports:
    - name: ge-metrics-grpc
      port: 9095
      targetPort: 9095
    - name: ge-metrics-gossip
      port: 7946
      targetPort: 7946
  publishNotReadyAddresses: true
  selector:
    name: ge-metrics
---
apiVersion: v1
kind: Service
metadata:
  labels:
    name: ge-metrics
  name: ge-metrics
spec:
  ports:
    - name: ge-metrics-http-metrics
      port: 80
      targetPort: 80
  selector:
    name: ge-metrics &lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create the services:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f services.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;deploy-the-grafana-enterprise-metrics-statefulset&#34;&gt;Deploy the Grafana Enterprise Metrics StatefulSet&lt;/h2&gt;
&lt;p&gt;Copy the following content into the &lt;code&gt;statefulset.yaml&lt;/code&gt; file, and make sure to add the &lt;code&gt;&amp;lt;version_number&amp;gt;&lt;/code&gt; of the GEM image that you would like to run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    name: ge-metrics
  name: ge-metrics
spec:
  replicas: 3
  selector:
    matchLabels:
      name: ge-metrics
  serviceName: ge-metrics
  template:
    metadata:
      labels:
        name: ge-metrics
    spec:
      containers:
      - args:
        - -config.file=/etc/ge-metrics/config.yaml
        image: grafana/metrics-enterprise:&amp;lt;version_number&amp;gt;
        imagePullPolicy: IfNotPresent
        name: metrics-enterprise
        ports:
        - containerPort: 80
          name: http-metrics
        - containerPort: 9095
          name: grpc
        - containerPort: 7946
          name: gossip
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 15
          timeoutSeconds: 1
        resources:
          requests:
            cpu: &amp;#34;2&amp;#34;
            memory: 4Gi
        volumeMounts:
        - mountPath: /data
          name: data
        - mountPath: /etc/ge-metrics
          name: ge-metrics-config
        - mountPath: /etc/ge-metrics/license
          name: ge-metrics-license
      securityContext:
        fsGroup: 10001
        runAsUser: 10001
        runAsGroup: 10001
        runAsNonRoot: true
      terminationGracePeriodSeconds: 300
      volumes:
      - name: ge-metrics-config
        configMap:
          name: ge-metrics-config
      - name: ge-metrics-license
        secret:
          secretName: ge-metrics-license
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create the StatefulSet:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f statefulset.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;start-the-gem-compactor-as-a-kubernetes-deployment&#34;&gt;Start the GEM compactor as a Kubernetes deployment&lt;/h2&gt;
&lt;p&gt;The single binary of GEM does not enable the compactor component by default. Therefore, you need to run the compactor separately as a Kubernetes StatefulSet. For more information about what the compactor does, refer to the &lt;a href=&#34;https://cortexmetrics.io/docs/blocks-storage/compactor/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Compactor&lt;/a&gt; section of the Cortex documentation.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Copy the following content into the &lt;code&gt;compactor.yaml&lt;/code&gt; file, and make sure to update the &lt;code&gt;&amp;lt;version_number&amp;gt;&lt;/code&gt; of the GEM image that you would like to run:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;  apiVersion: apps/v1
  kind: StatefulSet
  metadata:
    labels:
      name: ge-metrics-compactor
    name: ge-metrics-compactor
  spec:
    replicas: 1
    selector:
      matchLabels:
        name: ge-metrics-compactor
    serviceName: ge-metrics-compactor
    template:
      metadata:
        labels:
          name: ge-metrics-compactor
      spec:
        containers:
        - args:
          - -target=compactor
          - -config.file=/etc/ge-metrics/config.yaml
          image: grafana/metrics-enterprise:&amp;lt;version_number&amp;gt;
          imagePullPolicy: IfNotPresent
          name: ge-metrics-compactor
          ports:
          - containerPort: 80
            name: http-metrics
          - containerPort: 9095
            name: grpc
          - containerPort: 7946
            name: gossip
          readinessProbe:
            httpGet:
              path: /ready
              port: 80
            initialDelaySeconds: 15
            timeoutSeconds: 1
          resources:
            limits:
              cpu: 1200m
              memory: 2Gi
            requests:
              cpu: 1
              memory: 1Gi
          volumeMounts:
          - mountPath: /data
            name: data
          - mountPath: /etc/ge-metrics
            name: ge-metrics-config
          - mountPath: /etc/ge-metrics/license
            name: ge-metrics-license
        securityContext:
          fsGroup: 10001
          runAsUser: 10001
          runAsGroup: 10001
          runAsNonRoot: true
        terminationGracePeriodSeconds: 300
        volumes:
        - name: ge-metrics-config
          configMap:
            name: ge-metrics-config
        - name: ge-metrics-license
          secret:
            secretName: ge-metrics-license
    updateStrategy:
      type: RollingUpdate
    volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Create the compactor StatefulSet:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl apply -f compactor.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;generate-an-admin-token&#34;&gt;Generate an admin token&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To generate a token, use a Kubernetes Job.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the following content it into the &lt;code&gt;tokengen-job.yaml&lt;/code&gt; file, and make sure to update the &lt;code&gt;&amp;lt;version_number&amp;gt;&lt;/code&gt; of the GEM image that you would like to run:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: batch/v1
kind: Job
metadata:
  name: ge-metrics-tokengen
spec:
  template:
    spec:
      containers:
      - name: ge-metrics-tokengen
        image: grafana/metrics-enterprise:&amp;lt;version_number&amp;gt;
        args:
        - --config.file=/etc/ge-metrics/config.yaml
        - --target=tokengen
        volumeMounts:
        - mountPath: /etc/ge-metrics
          name: ge-metrics-config
        - mountPath: /etc/ge-metrics/license
          name: ge-metrics-license
        securityContext:
          runAsUser: 10001
          runAsGroup: 10001
          runAsNonRoot: true
      securityContext:
        fsGroup: 10001
      volumes:
      - name: ge-metrics-config
        configMap:
          name: ge-metrics-config
      - name: ge-metrics-license
        secret:
          secretName: ge-metrics-license
      restartPolicy: Never&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create the tokengen kubernetes Job:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;$ kubectl apply -f tokengen-job.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Check the status of the Pod, and after it displays &amp;lsquo;Completed&amp;rsquo;, check the logs for the new admin token:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl logs job.batch/ge-metrics-tokengen&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The output of the above command should contain a token in string in the logs:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;Token created:  Ym9vdHN0cmFwLXRva2VuOmA3PzkxOF0zfVx0MTlzMVteTTcjczNAPQ==&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Be sure to note down this token since it will be required later when setting up your cluster.&lt;/p&gt;
&lt;h2 id=&#34;verify-your-cluster-is-working&#34;&gt;Verify your cluster is working&lt;/h2&gt;
&lt;p&gt;To verify your cluster is working you can run the following command using the token you generated in the previous step.&lt;/p&gt;
&lt;p&gt;First, port-forward the ge-metrics Service to port 9000 on your machine:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl port-forward service/ge-metrics 9000:80&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;curl -u :&amp;lt;your_token&amp;gt; localhost:9000/ready&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After running the above command you should see the following output:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;ready&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;After you have a GEM deployment working locally, refer to &lt;a href=&#34;../../setup-gem-plugin-grafana/&#34;&gt;Set up the GEM plugin for Grafana&lt;/a&gt; to integrate your metrics cluster into Grafana. Doing so gives you a UI via which you can interact with the &lt;a href=&#34;../../admin-api/&#34;&gt;Admin API&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="deploy-gem-on-kubernetes">Deploy GEM on Kubernetes&lt;/h1>
&lt;p>This guide will layout a step by step approach to deploying a Grafana Enterprise Metrics cluster on an existing Kubernetes namespace. This guide assumes you have a working Kubernetes cluster and the ability to deploy to that cluster using the &lt;code>kubectl&lt;/code> tool. At the end of this guide you should have a functional GEM cluster running on Kubernetes using Minio as a storage backend. If you do not currently have access to a Kubernetes cluster consider following &lt;a href="../linux">Linux deployment guide instead&lt;/a>.&lt;/p></description></item><item><title>Deploy on Kubernetes with Tanka</title><link>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/tanka/</link><pubDate>Mon, 17 Mar 2025 14:18:51 +0100</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/tanka/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-on-kubernetes-with-tanka&#34;&gt;Deploy on Kubernetes with Tanka&lt;/h1&gt;
&lt;p&gt;To deploy Grafana Enterprise Metrics to Kubernetes using a Jsonnet library and &lt;a href=&#34;https://tanka.dev&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Grafana Tanka&lt;/a&gt;, you can use MinIO to provide object storage. It is best to leverage your cloud provider’s object storage service to avoid the operational overhead of running object storage in production.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before you begin, verify that you have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes cluster&lt;/li&gt;
&lt;li&gt;GEM license&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;deployment-instructions&#34;&gt;Deployment instructions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a namespace:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ kubectl create namespace enterprise-metrics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes Secret for your GEM license:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ kubectl --namespace=enterprise-metrics create secret generic gem-license --from-file=license.jwt&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Grafana Tanka; refer to &lt;a href=&#34;https://tanka.dev/install&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing Tanka&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;jsonnet-bundler&lt;/code&gt;; refer to the &lt;a href=&#34;https://github.com/jsonnet-bundler/jsonnet-bundler/#install&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;jsonnet-bundler&lt;/code&gt; README&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set up Tanka environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;a. Initialize Tanka:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ tk init --k8s=false
$ tk env add environments/enterprise-metrics
$ tk env set environments/enterprise-metrics \
  --namespace=enterprise-metrics \
  --server-from-context=&amp;lt;KUBECFG CONTEXT NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;b. Install &lt;code&gt;k.libsonnet&lt;/code&gt; for your version of Kubernetes:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ mkdir -p lib
$ export K8S_VERSION=1.18
$ jb install github.com/jsonnet-libs/k8s-libsonnet/${K8S_VERSION}@main
$ cat &amp;lt;&amp;lt;EOF &amp;gt; lib/k.libsonnet
import &amp;#39;github.com/jsonnet-libs/k8s-libsonnet/${K8S_VERSION}/main.libsonnet&amp;#39;
EOF&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the Grafana Enterprise Metrics Jsonnet library.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ jb install github.com/grafana/jsonnet-libs/enterprise-metrics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deploy MinIO object storage; refer to &lt;a href=&#34;../kubernetes/#deploy-minio&#34;&gt;Deploy Minio&lt;/a&gt; for the YAML manifests:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ kubectl apply --namespace enterprise-metrics -f minio.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deploy a GEM cluster using the MinIO object storage by replacing the contents of the &lt;code&gt;environments/enterprise-metrics/main.jsonnet&lt;/code&gt; file with the following configuration:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ cat &amp;lt;&amp;lt;EOF &amp;gt; environments/enterprise-metrics/main.jsonnet
local gem = import &amp;#39;github.com/grafana/jsonnet-libs/enterprise-metrics/main.libsonnet&amp;#39;;

gem {
  _config&amp;#43;:: {
    commonArgs&amp;#43;:: {
      &amp;#39;admin.client.backend-type&amp;#39;: &amp;#39;s3&amp;#39;,
      &amp;#39;admin.client.s3.access-key-id&amp;#39;: &amp;#39;minio&amp;#39;,
      &amp;#39;admin.client.s3.bucket-name&amp;#39;: &amp;#39;grafana-metrics-admin&amp;#39;,
      &amp;#39;admin.client.s3.endpoint&amp;#39;: &amp;#39;minio:9000&amp;#39;,
      &amp;#39;admin.client.s3.insecure&amp;#39;: true,
      &amp;#39;admin.client.s3.secret-access-key&amp;#39;: &amp;#39;minio123&amp;#39;,
      &amp;#39;blocks-storage.backend&amp;#39;: &amp;#39;s3&amp;#39;,
      &amp;#39;blocks-storage.s3.access-key-id&amp;#39;: &amp;#39;minio&amp;#39;,
      &amp;#39;blocks-storage.s3.bucket-name&amp;#39;: &amp;#39;grafana-metrics-tsdb&amp;#39;,
      &amp;#39;blocks-storage.s3.endpoint&amp;#39;: &amp;#39;minio:9000&amp;#39;,
      &amp;#39;blocks-storage.s3.insecure&amp;#39;: true,
      &amp;#39;blocks-storage.s3.secret-access-key&amp;#39;: &amp;#39;minio123&amp;#39;,
    },
  },
  // Run without an alertmanager or ruler.
  alertmanager:: null,
  ruler:: null,
  // Make tokengen manifests available on a first run.
  tokengen&amp;#43;::: {}
}
EOF&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deploy Grafana Enterprise Metrics.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;$ tk apply environments/enterprise-metrics/main.jsonnet&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
]]></content><description>&lt;h1 id="deploy-on-kubernetes-with-tanka">Deploy on Kubernetes with Tanka&lt;/h1>
&lt;p>To deploy Grafana Enterprise Metrics to Kubernetes using a Jsonnet library and &lt;a href="https://tanka.dev" target="_blank" rel="noopener noreferrer">Grafana Tanka&lt;/a>, you can use MinIO to provide object storage. It is best to leverage your cloud provider’s object storage service to avoid the operational overhead of running object storage in production.&lt;/p></description></item><item><title>GEM limits recommendations</title><link>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/limits/</link><pubDate>Mon, 17 Mar 2025 14:18:51 +0100</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v1.7.x/setup/limits/</guid><content><![CDATA[&lt;h1 id=&#34;gem-limits-recommendations&#34;&gt;GEM limits recommendations&lt;/h1&gt;
&lt;p&gt;You can configure GEM limits to protect a system from any data sender (be it a machine or a person) who inadvertently sends or queries too much data, which can cause the system to run out of resources and crash. The limits also ensure a quality of service and fairness of a service across your user base.&lt;/p&gt;
&lt;p&gt;GEM has the concept of &lt;em&gt;tenants&lt;/em&gt; and an API where you are able to administer the limits set for your tenants. This is the preferred way to manage your limits and keep your system stable. The GEM Plugin for Grafana allows you to easily set these limits from inside your Grafana installation.&lt;/p&gt;
&lt;p&gt;Since GEM 1.5.0, a self-monitoring &lt;code&gt;__system__&lt;/code&gt; tenant is available to help determine some of these limit values. For instructions on how to enable self-monitoring, please see the &lt;a href=&#34;../../self-monitoring/&#34;&gt;self-monitoring&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;If you do not have self-monitoring enabled or are using an earlier version of GEM, you need to query an external monitoring Prometheus to determine these values.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;gt; Note:&lt;/strong&gt; The terms &lt;em&gt;tenant&lt;/em&gt;, and &lt;em&gt;user&lt;/em&gt; are synonymous within the context of limit names; these terms all reference the same concept.&lt;/p&gt;
&lt;h2 id=&#34;global-limits-and-configuration&#34;&gt;Global limits and configuration&lt;/h2&gt;
&lt;p&gt;You can use the following configuration options in your configuration file for all relevant GEM components or you can set them via CLI flags. Before making limits changes to individual tenants, restart the system. This stabilizes the system before you configure it using the API or plugin.&lt;/p&gt;
&lt;h3 id=&#34;max-inflight-ingester-push-requests&#34;&gt;Max inflight ingester push requests&lt;/h3&gt;
&lt;p&gt;This option is a last-resort limit. If this limit is reached, &lt;code&gt;remote_write&lt;/code&gt; samples that were sent to the write path return 5xx errors, which are retried by the sender (in Prometheus and Grafana Agent). A value of &lt;code&gt;5000&lt;/code&gt; is conservative but effective, based on internal testing. If you change this setting on an already running system, you need to roll restart the ingesters, in the same way you would with any configuration change to the ingesters.&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;ingester:
  instance_limits:
    # CLI flag: -ingester.instance-limits.max-inflight-push-requests=5000
    max_inflight_push_requests: 5000 # default is 0 or unlimited in GEM 1.5.1 and earlier&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;shard-by-all-labels&#34;&gt;Shard by all labels&lt;/h3&gt;
&lt;p&gt;This option helps to evenly distribute metrics across the pool of ingesters, because the incoming data is hashed by the metric name &lt;em&gt;and&lt;/em&gt; the labels rather than only by the metric name. If you do not enable this option, some configured limits will not work correctly. If you change this setting on an already running system, you need to roll restart the distributors, in the same way you would with any configuration change to the distributors.&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;distributor:
  # CLI flag: -distributor.shard-by-all-labels=true
  shard_by_all_labels: true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;querier-max-concurrent&#34;&gt;Querier max concurrent&lt;/h3&gt;
&lt;p&gt;This option changes the number of queries a querier process is able to perform at once. A value of &lt;code&gt;8&lt;/code&gt; is recommended. If you change this setting on an already running system, you need to roll restart the queriers, in the same way you would with any configuration change to the queriers.&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;querier:
  # CLI flag: -querier.max-concurrent
  max_concurrent: 8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;default-minimal-global-settings&#34;&gt;Default minimal global settings&lt;/h3&gt;
&lt;p&gt;You can set limits for tenants above these minimal defaults. However, these limits help to keep the system stable if a new tenant is created and its limits have not been explicitly set. To keep things simple, apply these limits on every component because there are some components which embed other components and are as a result sometimes missed.&lt;/p&gt;
&lt;p&gt;To override them, based on the needs of individual tenants, see &lt;a href=&#34;#tenant-limits&#34;&gt;Tenant limits&lt;/a&gt;&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;limits:
  max_global_series_per_user: 1000000
  ingestion_rate: 142857
  ingestion_burst_size: 142857
  ingestion_rate_strategy: global
  ruler_max_rules_per_rule_group: 20
  ruler_max_rule_groups_per_tenant: 70&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;tenant-limits&#34;&gt;Tenant limits&lt;/h2&gt;
&lt;p&gt;To set the following limits on each of your tenants, use the GEM plugin. Alternatively, you can manually use the &lt;a href=&#34;../../tenant-management/limits/&#34;&gt;Tenant API&lt;/a&gt; within the Admin API:&lt;/p&gt;
&lt;h3 id=&#34;max-global-series-per-user&#34;&gt;Max global series per user&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;max_global_series_per_user&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Set the maximum number of series per tenant, which are enforced at the ingester level. This is generally described as the &amp;ldquo;number of metrics&amp;rdquo; that a tenant has. Note: The term &lt;em&gt;user&lt;/em&gt; in the metric name does not mean a person using the system; in this context, the term is synonymous with &lt;em&gt;tenant&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you are onboarding a new tenant, set this value to a low number such as &lt;code&gt;10000&lt;/code&gt; to ensure that the system has enough memory and CPU headroom before it starts accepting metrics. To determine if CPU and memory metrics for each component are below the limits that you have set, refer to the &lt;strong&gt;GEM system monitoring / GEM / Reads resources&lt;/strong&gt; and &lt;strong&gt;GEM system monitoring / GEM / Writes resources&lt;/strong&gt; dashboards. If a customer’s metrics are being discarded, slowly raise this value until the discarded samples go to zero, while checking to ensure that the system still has enough memory and CPU headroom to handle the additional load.&lt;/li&gt;
&lt;li&gt;If you are retroactively applying limits for a tenant that is sending data, and the system is stable, use the &lt;strong&gt;GEM system monitoring / GEM / Per-tenant usage&lt;/strong&gt; dashboard for each tenant to determine the value to set this to. For each tenant, choose &lt;strong&gt;Tenant&lt;/strong&gt; from the top of the dashboard, set the dashboard date in the upper right-hand corner to a preferred time frame, and choose a value higher than the maximum value of the &lt;strong&gt;Number of active time series&lt;/strong&gt; graph, which will ensure the senders&amp;rsquo; data is not discarded. You might want to add a 10% buffer on top of the maximum number to allow for some ingesters to contain slightly more metrics than others due to imperfect load balancing across ingesters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To determine if you are discarding samples for a tenant, use the Explore functionality in Grafana to perform the following query against the &lt;code&gt;GEM System Monitoring&lt;/code&gt; datasource:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum by (reason) (rate(cortex_discarded_samples_total{user=&amp;#34;TENANT-ID&amp;#34;}[1m]))&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where &lt;code&gt;TENANT-ID&lt;/code&gt; is the ID of the tenant.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;reason&lt;/code&gt; label &lt;code&gt;per_user_series_limit&lt;/code&gt; should be &lt;code&gt;0&lt;/code&gt;, otherwise GEM is rejecting samples as there is more data than allowed being sent.&lt;/p&gt;
&lt;h3 id=&#34;max-fetched-chunk-bytes-per-query&#34;&gt;Max fetched chunk bytes per query&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;max_fetched_chunk_bytes_per_query&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This limit helps guard against querier processes utilizing too much memory and causing crashes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For microservices deployments, Grafana Labs recommends leaving this limit unset. If you observe querier processes crashing frequently because they are out of memory you can consider setting this limit, but infrequent querier process crashes are tolerated by the distributed system. Alternatively, setting the querier limit &lt;code&gt;-querier.max-concurrent&lt;/code&gt; to a lower value than the default is an option to lower per querier memory usage.&lt;/li&gt;
&lt;li&gt;For single binary deployments, Grafana Labs recommends determining the value for this limit by taking the amount of memory you are willing to allocate to queries, and dividing that number of bytes by the value of the querier limit &lt;code&gt;-querier.max-concurrent&lt;/code&gt; (see &lt;a href=&#34;#querier-max-concurrent&#34;&gt;Querier max concurrent&lt;/a&gt;). Set the final value of &lt;code&gt;max_fetched_chunk_bytes_per_query&lt;/code&gt; to 50% of the calculated value to account for various factors which increase memory overhead in the system. For example, if you are allocating &lt;code&gt;20GB&lt;/code&gt; of memory to queries, and the &lt;code&gt;max-concurrent&lt;/code&gt; is set to 8, set the value to &lt;code&gt;1342177280&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ingestion-rate&#34;&gt;Ingestion rate&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ingestion_rate&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This limit helps guard against an increase in high frequency incoming samples from using too much memory on the system. The number of series and the number of series per metric limits set above are also important, but if a sender was updating a series every second, it would take more memory than one that was updated every minute.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you are onboarding a new tenant, Grafana Labs recommends setting this value to the value determined for &lt;code&gt;max_global_series_per_user&lt;/code&gt;, divided by the scraping interval in seconds, then adding a 10% buffer. For example, if you have a value of &lt;code&gt;1000000&lt;/code&gt; set for your &lt;code&gt;max_global_series_per_user&lt;/code&gt;, the scraping interval of a sender is &lt;code&gt;15s&lt;/code&gt;, you should set the &lt;code&gt;ingestion_rate&lt;/code&gt; to &lt;code&gt;73333&lt;/code&gt;. If you have higher or lower frequency data, you may want to increase or decrease this value, being sure to watch memory and CPU utilization on the system.&lt;/li&gt;
&lt;li&gt;If you are retroactively applying limits for a tenant that is sending data, and the system is stable, use the &lt;strong&gt;GEM system monitoring / GEM / Per-tenant usage&lt;/strong&gt; dashboard for each tenant to determine the value to set this to. For each tenant, choose its name in the &lt;strong&gt;Tenant&lt;/strong&gt; dropdown at the top of the dashboard, set the dashboard date in the upper right-hand corner to a preferred time frame, and choose a value higher than the maximum value of the &lt;strong&gt;Ingestion rate&lt;/strong&gt; graph, which will ensure the senders&amp;rsquo; data is not discarded. You might want to add a 10% buffer on top of the maximum number to allow for some variability in the rate of data being sent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To determine if senders are hitting the ingestion rate limit, use the Explore functionality in Grafana to perform the following query against the &lt;code&gt;GEM System Monitoring&lt;/code&gt; datasource:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum by (reason) (rate(cortex_discarded_samples_total{user=&amp;#34;TENANT-ID&amp;#34;}[1m]))&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where &lt;code&gt;TENANT-ID&lt;/code&gt; is the ID of the tenant.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;reason&lt;/code&gt; label &lt;code&gt;rate_limited&lt;/code&gt; should be &lt;code&gt;0&lt;/code&gt;, otherwise GEM is rejecting samples as there is more data than allowed being sent.&lt;/p&gt;
&lt;h3 id=&#34;ingestion-burst-size&#34;&gt;Ingestion burst size&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ingestion_burst_size&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This limit allows for some temporary influx of data to be sent above the normal ingestion rate, but for short periods of time. To be extra careful and cautious, set this value to the same value you have set for &lt;code&gt;ingestion_rate&lt;/code&gt;, which allows for no bursting. However if you have enough headroom in your system and want to hit limits less frequently if a sender temporarily bursts above, you are able to set this value. Depending on your headroom you may want to set this to a higher or lower number, but a relatively safe value would be to double it.&lt;/p&gt;
&lt;p&gt;For customers deploying using single binary or in a scenario where the queriers are part of the write path, Grafana Labs recommends setting this value equal to &lt;code&gt;ingestion_rate&lt;/code&gt;, which disables bursting.&lt;/p&gt;
&lt;h3 id=&#34;ruler-max-rules-per-rule-group&#34;&gt;Ruler max rules per rule group&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ruler_max_rules_per_rule_group&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you are using the ruler component, you should set limits around how many rules can exist in a rule group. A smaller number of rules per rule group allows for more even distribution across the rulers. Grafana Labs recommends setting this value to &lt;code&gt;20&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;ruler-max-rule-groups-per-tenant&#34;&gt;Ruler max rule groups per tenant&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ruler_max_rule_groups_per_tenant&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you are using the ruler component, you should set limits around how many rule groups a tenant is allowed. This number can be higher or lower depending on how many ruler instances you have. The effective number of rules a tenant can have is the &lt;code&gt;ruler_max_rule_groups_per_tenant&lt;/code&gt; multiplied by &lt;code&gt;ruler_max_rules_per_rule_group&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Grafana Labs recommends setting this to a lower number, such as &lt;code&gt;10&lt;/code&gt;, and increasing it if tenants need more ruler capacity.&lt;/p&gt;
&lt;p&gt;To determine if the rulers have capacity to allow an increase of rule groups, reference the &lt;code&gt;GEM System Monitoring / GEM / Reads Resources&lt;/code&gt; dashboard in the &lt;code&gt;Ruler&lt;/code&gt; section, to determine if CPU and memory metrics are beneath the hard limits you have set.&lt;/p&gt;
]]></content><description>&lt;h1 id="gem-limits-recommendations">GEM limits recommendations&lt;/h1>
&lt;p>You can configure GEM limits to protect a system from any data sender (be it a machine or a person) who inadvertently sends or queries too much data, which can cause the system to run out of resources and crash. The limits also ensure a quality of service and fairness of a service across your user base.&lt;/p></description></item></channel></rss>