<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David de Torres</title>
    <description>The latest articles on DEV Community by David de Torres (@daviddetorres).</description>
    <link>https://dev.to/daviddetorres</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F574054%2F8e91c8f3-8e22-4bf3-90cd-e0de3a045484.jpeg</url>
      <title>DEV Community: David de Torres</title>
      <link>https://dev.to/daviddetorres</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daviddetorres"/>
    <language>en</language>
    <item>
      <title>Prometheus 2.35 – What’s new?</title>
      <dc:creator>David de Torres</dc:creator>
      <pubDate>Fri, 06 May 2022 09:04:57 +0000</pubDate>
      <link>https://dev.to/daviddetorres/prometheus-235-whats-new-2m44</link>
      <guid>https://dev.to/daviddetorres/prometheus-235-whats-new-2m44</guid>
      <description>&lt;p&gt;Prometheus 2.35 &lt;a href="https://github.com/prometheus/prometheus/releases/tag/v2.35.0"&gt;was released last month&lt;/a&gt;, focusing on a better integration with cloud providers. It also improved the service discovery, performance, and resources usage. &lt;/p&gt;

&lt;p&gt;One key change was the migration to Go v1.18. It has brought some changes in the support for TLS 1.0, 1.1, and certificates signed with the SHA1 hash function.&lt;/p&gt;

&lt;p&gt;Welcome to this first edition of &lt;em&gt;What's new in Prometheus&lt;/em&gt;. We love Prometheus, the de-facto open source standard monitoring tool! &lt;/p&gt;

&lt;p&gt;In this article, we will analyze some new features, and the impact they might have on the Prometheus community. Here's our editor's pick:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10501"&gt;#10501&lt;/a&gt; Build with Go 1.18
&lt;/h2&gt;

&lt;p&gt;Go 1.18 is now the default version for building Prometheus. This has two major implications in authentication. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://go.dev/doc/go1.18#tls10"&gt;TLS 1.0 and 1.1 disabled by default client-side&lt;/a&gt;. If you are using one of these, Prometheus now allows defining the minimum TLS version with the &lt;code&gt;min_version&lt;/code&gt; config parameter (&lt;a href="https://github.com/prometheus/prometheus/pull/10610"&gt;#10610&lt;/a&gt;). &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://go.dev/doc/go1.18#sha1"&gt;Certificates signed with the SHA-1 hash function are rejected&lt;/a&gt;. This doesn't apply to self-signed root certificates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;em&gt;David Lorite - Integrations Engineer at Sysdig&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10516"&gt;#10516&lt;/a&gt;, &lt;a href="https://github.com/prometheus/prometheus/pull/10476"&gt;#10476&lt;/a&gt;, &lt;a href="https://github.com/prometheus/prometheus/pull/10365"&gt;#10365&lt;/a&gt; Better integration with cloud providers
&lt;/h2&gt;

&lt;p&gt;As in previous versions, Prometheus is adding better support to cloud providers. This release includes the libraries to authenticate with Google Cloud Platform (GCP) Kubernetes clusters (e.g. GKE) when configured in the Kubernetes service discovery.&lt;/p&gt;

&lt;p&gt;The service discovery is more stable for Azure. Before this release, when any node wasn't reachable, the service discovery for the whole cluster failed. Now, the service discovery continues with the rest of the available nodes. It also includes a metric (&lt;code&gt;prometheus_sd_azure_failures_total&lt;/code&gt;) to register when nodes aren't ready during service discovery.  You can use this new metric to configure an alert to detect problems in Azure service discovery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(prometheus_sd_azure_failures_total[5m]) &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, the Azure service discovery now includes the &lt;code&gt;ResourceGroup&lt;/code&gt; filter. This is helpful to reduce the load of Prometheus service discovery, especially when running several AKS clusters, since ARM API requests are rate-limited in Azure.&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Carlos Adiego - Integrations Engineer at Sysdig&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10080"&gt;#10080&lt;/a&gt;, &lt;a href="https://github.com/prometheus/prometheus/pull/9570"&gt;#9570&lt;/a&gt; Enhancements in Kubernetes Service Discovery
&lt;/h2&gt;

&lt;p&gt;This version includes two exciting changes in the Kubernetes service discovery. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The addition of node metadata (name, address, labels annotations) in the targets selected through the pod role (&lt;a href="https://github.com/prometheus/prometheus/pull/10080"&gt;#10080&lt;/a&gt;). This allows you to add filters in the relabeling allow list or deny list targets from specific nodes. Even more interesting, add the node labels to all metrics, which later allows you to make groupings by nodes or node labels (or annotations). There is &lt;a href="https://github.com/prometheus/prometheus/issues/9510"&gt;a proposal&lt;/a&gt; to also analogously include namespace metadata. To add all the node labels to your metrics, you can use the action &lt;code&gt;labelmap&lt;/code&gt; in the relabeling:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;action: labelmap
regex: __meta_kubernetes_node_(.+)
replacement: 'kubernetes_node_$1'
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;EndpointSlice&lt;/code&gt; Kubernetes endpoint promoted to v1 from v1Beta1, as it is deprecated in Kubernetes 1.22.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;em&gt;&lt;a href="https://twitter.com/maellyssa"&gt;David de Torres&lt;/a&gt; - Engineering manager at Sysdig&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10369"&gt;#10369&lt;/a&gt; New stats for queries computational cost
&lt;/h2&gt;

&lt;p&gt;Prometheus already had timing statistics for queries. However, as they are based on response time, the same query can have different execution times depending on the load of the system or other parallel queries. That was the motivation to include three new statistics in this version: &lt;code&gt;totalQueryableSamples&lt;/code&gt;, &lt;code&gt;totalQueryableSamplesPerStep&lt;/code&gt;, and &lt;code&gt;peakSamples&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is great news for engineers working on optimizing complex queries. Now, they can evaluate and compare the performance of the queries that they build.&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Aleksandar Ponjavic - Engineering Manager at Sysdig&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10317"&gt;#10317&lt;/a&gt;, &lt;a href="https://github.com/prometheus/prometheus/pull/10500"&gt;#10500&lt;/a&gt; Optimization of TSDB at start
&lt;/h2&gt;

&lt;p&gt;There are two enhancements in this version that involve the start of the TSDB. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deletion of temporary files (&lt;a href="https://github.com/prometheus/prometheus/pull/10317"&gt;#10317&lt;/a&gt;), something that could be skipped in some scenarios. This way, Prometheus ensures that it's not using more disk space than needed and becomes a better citizen of the cluster. &lt;/li&gt;
&lt;li&gt;A more efficient way to read the Write Ahead Log (WAL) at the start-up (&lt;a href="https://github.com/prometheus/prometheus/pull/10500"&gt;#10500&lt;/a&gt;). This significantly reduces the time Prometheus needs to update the TSDB after a non-controlled stop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;em&gt;&lt;a href="https://twitter.com/eckelon"&gt;Jesús Ángel Samitier&lt;/a&gt; - Integrations Engineer at Sysdig&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/prometheus/prometheus/pull/10498"&gt;#10498&lt;/a&gt; Automatically limit CPU usage to the container CPU limit
&lt;/h2&gt;

&lt;p&gt;Prometheus 2.35 brings a new feature to set the Go's &lt;code&gt;GOMAXPROCS&lt;/code&gt; environment variable in Go to the container CPU limits. This feature ensures that the process will never consume more than the limits. This feature is still experimental and can be enabled with &lt;code&gt;--enable-feature=auto-gomaxprocs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Carlos Arilla, Technical product manager at Sysdig&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;These were the new features chosen by our team, but there are more. You can find the full list of changes in the &lt;a href="https://github.com/prometheus/prometheus/releases/tag/v2.35.0"&gt;official release notes of Prometheus 2.35&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>opensource</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Top key metrics for monitoring MySQL</title>
      <dc:creator>David de Torres</dc:creator>
      <pubDate>Fri, 05 Nov 2021 08:39:49 +0000</pubDate>
      <link>https://dev.to/daviddetorres/top-key-metrics-for-monitoring-mysql-1ncj</link>
      <guid>https://dev.to/daviddetorres/top-key-metrics-for-monitoring-mysql-1ncj</guid>
      <description>&lt;p&gt;Monitoring MySQL with Prometheus is easy to do thanks to the MySQL Prometheus Exporter. MySQL doesn’t need an introduction – it’s one of the most used relational databases in the world, and it’s also open-source!&lt;br&gt;
​&lt;br&gt;
Being such a popular database means that the community behind it is also huge. So don’t worry: you won’t be alone.&lt;/p&gt;

&lt;p&gt;​&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsysdig.com%2Fwp-content%2Fuploads%2FBlog-How-to-monitor-MySQL-Featured-image.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsysdig.com%2Fwp-content%2Fuploads%2FBlog-How-to-monitor-MySQL-Featured-image.jpg" alt="illustration showing 5 cute little monitors with metrics in a podium"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, you’ll learn how to start monitoring a MySQL Server with Prometheus – from configuring the exporter to what are the top metrics, with alert examples. If you’re running MySQL with RDS, don’t miss our ​​&lt;a href="https://sysdig.com/blog/monitoring-amazon-rds/" rel="noopener noreferrer"&gt;top 5 key metrics for monitoring Amazon RDS&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting things up
&lt;/h2&gt;

&lt;p&gt;Before deploying the exporter in the cluster, you have to create the user and password for the exporter in the database. Enter your MySQL database and execute the following queries:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'exporter'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'YOUR-PASSWORD'&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;MAX_USER_CONNECTIONS&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;PROCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REPLICATION&lt;/span&gt; &lt;span class="n"&gt;CLIENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'exporter'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Substitute the user name and the password in the SQL sentence for your custom ones.&lt;br&gt;
​&lt;br&gt;
Once you have the user and password for the exporter in the database, you have to create a &lt;code&gt;mysql-exporter.cnf&lt;/code&gt; file with the credentials of the exporter. Also, in this file you will include the url to connect your MySQL database in the field &lt;code&gt;host&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[client]
user = exporter
password = "YOUR-PASSWORD"
host=YOUR-DB-IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your Kubernetes cluster, create the secret with the &lt;code&gt;mysql-exporter.cnf&lt;/code&gt; file. This file will be mounted in the exporter to authenticate with the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create secret generic mysql-exporter &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.my.cnf&lt;span class="o"&gt;=&lt;/span&gt;./mysql-exporter.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to deploy the MySQL Prometheus Exporter
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
To start monitoring MySQL with Prometheus, you’ll need to deploy &lt;a href="https://github.com/prometheus/mysqld_exporter" rel="noopener noreferrer"&gt;the MySQL Exporter&lt;/a&gt; in your cluster.&lt;br&gt;
​&lt;br&gt;
To deploy the exporter, you can use the example files provided below.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-exporter-exporter&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-exporter&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-exporter&lt;/span&gt;
      &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
        &lt;span class="na"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9104"&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-exporter&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prom/mysqld-exporter:latest&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--config.my-cnf=/tmp/.my.cnf&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9104&lt;/span&gt;
          &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-cnf&lt;/span&gt;
              &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp/.my.cnf&lt;/span&gt;
              &lt;span class="na"&gt;subPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.my.cnf&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256m"&lt;/span&gt;
      &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-cnf&lt;/span&gt;
          &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;defaultMode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;420&lt;/span&gt;
            &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-exporter&lt;/span&gt;
            &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.my.cnf&lt;/span&gt;
                &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.my.cnf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying the Deployment for the exporter, Prometheus will automatically start scraping the MySQL metrics as it already has the standard annotations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top 5 metrics to monitor MySQL with Prometheus
&lt;/h2&gt;

&lt;p&gt;​&lt;/p&gt;

&lt;h3&gt;
  
  
  #1 Availability
&lt;/h3&gt;

&lt;p&gt;There are two metrics that monitor the availability of your MySQL instance. The first one is &lt;code&gt;mysql_up&lt;/code&gt;. If this metric equals zero, the exporter cannot access the database, which can be a symptom of an unhealthy or failed database.&lt;br&gt;
​&lt;br&gt;
You can create an alert to notify you in case of a database down with the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;mysql_up&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, the metric &lt;code&gt;mysql_global_status_uptime&lt;/code&gt; can give you an idea of quick restarts that can pass under the radar of the previous metric. You can create an alert with the following Prometheus query to detect instances that have an uptime of less than half an hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;mysql_global_status_uptime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1800&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;/p&gt;

&lt;h3&gt;
  
  
  #2 Connections
&lt;/h3&gt;

&lt;p&gt;One of the main sources of errors in databases are connection errors. The metric &lt;code&gt;mysql_global_status_connection_errors_total&lt;/code&gt; allows you to detect when the database is generating these errors:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mysql_global_status_connection_errors_total&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One common cause of connection error is the lack of available connections. You can check the percent of available connections used with this Prometheus query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 * mysql_global_status_threads_connected / mysql_global_variables_max_connections
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this value is near 100, the database can start refusing new connections. A solution for this can be increasing the number of maximum connections. Before doing that, be sure to check the available number of open files in the system. You can check it with the following Prometheus query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql_global_variables_open_files_limit - mysql_global_variables_innodb_open_files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Want to dig deeper into PromQL? Read our &lt;a href="https://sysdig.com/blog/getting-started-with-promql-cheatsheet/" rel="noopener noreferrer"&gt;getting started with PromQL&lt;/a&gt; guide to learn how Prometheus stores data, and how to use PromQL functions and operators.&lt;/em&gt;&lt;br&gt;
​&lt;/p&gt;
&lt;h3&gt;
  
  
  #3 Slow queries
&lt;/h3&gt;

&lt;p&gt;Like many databases, MySQL keeps a log for slow queries. The number of entries in this log can be consulted with the metric &lt;code&gt;mysql_global_status_slow_queries&lt;/code&gt;. You can create an alert with the following Prometheus query to notify when there are new entries in the slow queries log, which can mean that there is a performance issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(mysql_global_status_slow_queries[5m])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  #4 Cache Hit Rate
&lt;/h3&gt;

&lt;p&gt;MySQL uses in-memory cache to optimize the disk read and write operations. A low hit rate in the cache will impact the performance of the database. This Prometheus query will give you the value of the &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/table-cache.html" rel="noopener noreferrer"&gt;open tables cache&lt;/a&gt; hit rate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(mysql_global_status_table_open_cache_hits[5m]) /
(rate(mysql_global_status_table_open_cache_hits[5m]) + rate(mysql_global_status_table_open_cache_misses[5m]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, you can monitor the &lt;a href="https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool.html" rel="noopener noreferrer"&gt;buffer pool&lt;/a&gt; cache with the following promQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mysql_global_status_innodb_buffer_pool_read_requests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mysql_global_status_innodb_buffer_pool_reads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mysql_global_status_innodb_buffer_pool_read_requests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
You can tune the buffer size for open tables and pool caches in the MySQL configuration, but keep in mind that doing so will affect the memory usage of your instance. Be sure that there is enough memory. You can check the available memory of the container using cAdvisor metrics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="n"&gt;container_memory_usage_bytes&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="s2"&gt;"POD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;kube_pod_container_resource_limits&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"memory"&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your MySQL instance is in AWS RDS, check our blog post on &lt;a href="https://sysdig.com/blog/monitoring-amazon-rds/" rel="noopener noreferrer"&gt;how to monitor your RDS instance&lt;/a&gt;&lt;br&gt;
​&lt;/p&gt;

&lt;h3&gt;
  
  
  #5 Query types
&lt;/h3&gt;

&lt;p&gt;You can get statistics of the usage of each kind of SELECT query in your MySQL database, using the metric that gives information on each of them:&lt;br&gt;
​&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.w3schools.com/sql/sql_join_full.asp" rel="noopener noreferrer"&gt;Full join&lt;/a&gt;: mysql_global_status_select_full_join&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.mysql.com/doc/internals/en/optimizer-range-join-type.html" rel="noopener noreferrer"&gt;Full range join&lt;/a&gt;: mysql_global_status_select_full_range_join&lt;/li&gt;
&lt;li&gt;  Select range check (joins without keys that check for key usage after each row): mysql_global_status_select_range_check&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/table-scan-avoidance.html" rel="noopener noreferrer"&gt;Select scan&lt;/a&gt;: mysql_global_status_select_scan
​
All of them are counters, so remember to use the function rate in Prometheus queries, like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mysql_global_status_select_full_join&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, you can also have statistics on the use of sorting queries in MySQL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://dev.mysql.com/doc/mysql-tutorial-excerpt/8.0/en/sorting-rows.html" rel="noopener noreferrer"&gt;Sort rows&lt;/a&gt;: mysql_global_status_sort_rows&lt;/li&gt;
&lt;li&gt;  The number of sorts that were done using ranges: mysql_global_status_sort_range&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.mysql.com/doc/internals/en/optimizer-index-merge-join-type.html" rel="noopener noreferrer"&gt;Sort merge&lt;/a&gt; (The number of merge passes that the sort algorithm has had to do): mysql_global_status_sort_merge_passes&lt;/li&gt;
&lt;li&gt;  The number of sorts that were done by scanning the table: mysql_global_status_sort_scan
​&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;In this article, you learned how easy it is to start monitoring MySQL with Prometheus. You just need &lt;a href="https://promcat.io/" rel="noopener noreferrer"&gt;the right exporter and configuration&lt;/a&gt;.&lt;br&gt;
You also learned the top Prometheus queries you should have in mind when monitoring MySQL with Prometheus.&lt;br&gt;
​&lt;br&gt;
If you want to get some inspiration for writing Prometheus queries, you can take a look at these &lt;a href="https://sysdig.com/blog/prometheus-query-examples/" rel="noopener noreferrer"&gt;examples for monitoring Kubernetes&lt;/a&gt;, or download our &lt;a href="https://sysdig.com/blog/getting-started-with-promql-cheatsheet/" rel="noopener noreferrer"&gt;PromQL getting started cheatsheet&lt;/a&gt;.&lt;br&gt;
​&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Trigger a Kubernetes HPA with Prometheus metrics</title>
      <dc:creator>David de Torres</dc:creator>
      <pubDate>Thu, 07 Oct 2021 16:18:33 +0000</pubDate>
      <link>https://dev.to/daviddetorres/trigger-a-kubernetes-hpa-with-prometheus-metrics-43im</link>
      <guid>https://dev.to/daviddetorres/trigger-a-kubernetes-hpa-with-prometheus-metrics-43im</guid>
      <description>&lt;p&gt;In this article, you'll learn how to configure &lt;strong&gt;Keda to deploy a Kubernetes HPA&lt;/strong&gt; that uses Prometheus metrics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Kubernetes Horizontal Pod Autoscaler can scale pods based on the usage of resources&lt;/strong&gt;, such as CPU and memory. This is useful in many scenarios, but there are other use cases where more advanced metrics are needed – like the waiting connections in a web server or the latency in an API. Also, in other cases, you might need to combine multiple metrics in a formula or make aggregations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://keda.sh/"&gt;Keda is an open source project&lt;/a&gt; that allows &lt;strong&gt;using Prometheus queries&lt;/strong&gt;, along with &lt;a href="https://keda.sh/docs/2.4/scalers/"&gt;multiple other scalers&lt;/a&gt;, to scale Kubernetes pods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes HPA
&lt;/h2&gt;

&lt;p&gt;Kubernetes HPA can scale objects by &lt;strong&gt;relying on metrics present in one of the Kubernetes metrics API endpoints&lt;/strong&gt;. You can read more about &lt;a href="https://sysdig.com/blog/kubernetes-autoscaler/"&gt;how Kubernetes HPA works in this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kubernetes HPA is very helpful, but &lt;strong&gt;it has two important limitations&lt;/strong&gt;. The first is that it &lt;strong&gt;doesn't allow combining metrics&lt;/strong&gt;. There are scenarios where combining multiple metrics is convenient, such as calculating the connection usage with the current number of established connections and the maximum number of connections.&lt;/p&gt;

&lt;p&gt;The second limitation is the &lt;strong&gt;reduced number of metrics that Kubernetes exposes by default&lt;/strong&gt;: just CPU and memory usage. Sometimes, applications expose more advanced metrics, either by themselves or through exporters. To expose more metrics, you need to publish them in the Kubernetes API metrics endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting HPA and Prometheus metrics with KEDA
&lt;/h2&gt;

&lt;p&gt;Keda is an open source project that simplifies using Prometheus metrics for Kubernetes HPA.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Keda
&lt;/h3&gt;

&lt;p&gt;The easiest way to install Keda is using &lt;a href="https://helm.sh/"&gt;Helm&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add kedacore https://kedacore.github.io/charts
helm repo update
kubectl create namespace keda
helm install keda kedacore/keda --namespace keda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check out &lt;a href="https://keda.sh/docs/2.4/deploy/"&gt;Keda's documentation page&lt;/a&gt; for other installation methods.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Keda does it?
&lt;/h3&gt;

&lt;p&gt;Keda has a Kubernetes operator that &lt;strong&gt;creates both the metrics server and the HPA&lt;/strong&gt; by defining a Custom Resource Definition (CRD) object called ScaledObject. This object allows you to define &lt;strong&gt;what you want to scale and how you want to scale it&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What to scale
&lt;/h4&gt;

&lt;p&gt;Easy: almost anything.&lt;/p&gt;

&lt;p&gt;With Keda, &lt;strong&gt;you can scale the usual Kubernetes workloads&lt;/strong&gt;, like &lt;code&gt;Deployments&lt;/code&gt; or &lt;code&gt;StatefulSets&lt;/code&gt;. Also, you can scale &lt;strong&gt;other CRDs&lt;/strong&gt; – it even has another CRD to scale jobs.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to scale
&lt;/h4&gt;

&lt;p&gt;This is where the magic is done. You can define triggers in Keda, and there are a lot of different types of them. This article is focused on the Prometheus trigger.&lt;/p&gt;

&lt;p&gt;When you set up a Prometheus trigger for a &lt;code&gt;ScaledObject&lt;/code&gt;, you define a Prometheus endpoint and a Prometheus query. &lt;strong&gt;Keda uses that information to query your Prometheus server and create a metric in the Kubernetes external metrics API&lt;/strong&gt;. Once you create the &lt;code&gt;ScaledObject&lt;/code&gt;, Keda automatically creates the Kubernetes HPA for that.&lt;/p&gt;

&lt;p&gt;That's it. You don't need to worry about publishing metrics in the Kubernetes API metrics endpoint or even creating the Kubernetes HPA object!&lt;/p&gt;

&lt;h3&gt;
  
  
  An example, please
&lt;/h3&gt;

&lt;p&gt;Imagine that you want an HPA for the &lt;code&gt;nginx-server&lt;/code&gt; deployment. You want it to scale from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;5&lt;/code&gt; replicas, based on the &lt;code&gt;nginx_connections_waiting&lt;/code&gt; metric from the &lt;a href="https://github.com/nginxinc/nginx-prometheus-exporter"&gt;Nginx exporter&lt;/a&gt;. If there are more than &lt;code&gt;500&lt;/code&gt; waiting connections, then you want to schedule a new pod.&lt;/p&gt;

&lt;p&gt;Let's create the query to trigger the HPA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sum(nginx_connections_waiting{job="nginx"})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy, right? This query just returns the sum of the nginx_connections_waiting metric value for the &lt;code&gt;nginx&lt;/code&gt; job.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about PromQL, the Prometheus query language? Check out the &lt;a href="https://sysdig.com/blog/getting-started-with-promql-cheatsheet/"&gt;PromQL getting started guide&lt;/a&gt; – it also includes a cheatsheet!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's define the &lt;code&gt;ScaledObject&lt;/code&gt; for this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keda.sh/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ScaledObject&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-scale&lt;/span&gt;
 &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keda-hpa&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-server&lt;/span&gt;
 &lt;span class="na"&gt;minReplicaCount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
 &lt;span class="na"&gt;maxReplicaCount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
 &lt;span class="na"&gt;cooldownPeriod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
 &lt;span class="na"&gt;pollingInterval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
 &lt;span class="na"&gt;triggers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
   &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;serverAddress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://prometheus_server/prometheus&lt;/span&gt;
     &lt;span class="na"&gt;metricName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx_connections_waiting_keda&lt;/span&gt;
     &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
       &lt;span class="s"&gt;sum(nginx_connections_waiting{job="nginx"})&lt;/span&gt;
     &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;metricName&lt;/code&gt; parameter. This is a custom name you set for receiving the value from the query. Keda gets the result of the query and creates the &lt;code&gt;nginx_connections_waiting_keda&lt;/code&gt; metric with it. Then, it uses this metric to trigger the escalation. Also, remember to change the &lt;code&gt;serverAddress&lt;/code&gt;. :)&lt;/p&gt;

&lt;p&gt;Now, you simply need to apply the &lt;code&gt;ScaledObject&lt;/code&gt; definition, and the HPA will start working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else does Keda offer?
&lt;/h2&gt;

&lt;p&gt;Along with all the benefits of using the metrics in your Prometheus server and applying Prometheus queries to combine them as you want, Keda has additional special features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  It allows you to scale down an object to zero, while the default Kubernetes HPA only allows a minimum value equal or greater than 1.&lt;/li&gt;
&lt;li&gt;  It allows defining the number of replicas in case it's unable to get the value from the metric, e.g. in an error connection.&lt;/li&gt;
&lt;li&gt;  It supports a secure connection with Prometheus endpoints with authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;In this article, you learned how to create a Kubernetes HPA easily, without the need to extend the Kubernetes API metrics endpoint. Just by installing and configuring Keda.&lt;/p&gt;

&lt;p&gt;In the examples, you also learned how to use a Prometheus PromQL query to trigger the autoscaler.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>prometheus</category>
      <category>keda</category>
      <category>hpa</category>
    </item>
  </channel>
</rss>
