<?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: Kristijan</title>
    <description>The latest articles on DEV Community by Kristijan (@kmitevski).</description>
    <link>https://dev.to/kmitevski</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%2F641701%2F9f31e672-a49d-4617-bec1-5e026eaa74f3.jpeg</url>
      <title>DEV Community: Kristijan</title>
      <link>https://dev.to/kmitevski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kmitevski"/>
    <language>en</language>
    <item>
      <title>Traditional vs Modern Incident Response</title>
      <dc:creator>Kristijan</dc:creator>
      <pubDate>Mon, 25 Apr 2022 12:15:16 +0000</pubDate>
      <link>https://dev.to/squadcast/traditional-vs-modern-incident-response-1k8h</link>
      <guid>https://dev.to/squadcast/traditional-vs-modern-incident-response-1k8h</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;What is Incident Response?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An incident is an event (network outage, system failure, data breach, etc.) that can lead to loss of, or disruption to, an organization's operations, services or functions. Incident Response is an organization’s effort to detect, analyze and correct the hazards caused due to an incident. In the most common cases, when an incident response is mentioned, it usually relates to security incidents. Sometimes incident response and incident management are more or less used interchangeably.&lt;/p&gt;

&lt;p&gt;However, an incident can be of any nature, it doesn’t have to be tied to security, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Physical damage to hardware or systems (fire, flooding)&lt;/li&gt;
&lt;li&gt;Human error (misconfigurations, accidental deletion of data)&lt;/li&gt;
&lt;li&gt;Malicious actors (denial of service attacks, malware, ransomware)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every incident is different and may require a different response. The incident response consists of steps taken by an organization to address the outage and reinstate services to their normal operation, often in real-time. For example, treating an outage is referred to as an incident response.&lt;/p&gt;

&lt;p&gt;A good incident response plan can help your company respond quickly and effectively when an outage occurs. Keep in mind that incident response is not just a technical function to be done by a specific team. Instead, it is more of a corporate process that involves all areas of the business.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Traditional vs Modern Incident Response&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The biggest change in the world of incident response was the widespread adoption of automation.&lt;/p&gt;

&lt;p&gt;Traditionally, the incident response was a highly manual process. Everything from creating a ticket to patching a server required human interaction. It was effective until the world experienced the internet boom.&lt;/p&gt;

&lt;p&gt;Easy internet access has certainly opened up opportunities for people and businesses alike. &lt;a href="https://www.brighttalk.com/webcast/17582/506721/how-modern-service-management-reignites-business-for-service-delivery-success" rel="noopener noreferrer"&gt;According to IDC&lt;/a&gt;, 60% or more organizations have spent more on technology to embrace the digital future.&lt;/p&gt;

&lt;p&gt;The rise in use of digital platforms has resulted in complex infrastructures with multiple application dependencies. Hence, downtime and system failures for even a few minutes can incur huge monetary losses (in some cases, even millions).&lt;/p&gt;

&lt;p&gt;In order to avoid such events, organizations have resorted to dealing with incidents using teams that are on-call 24/7. This puts a lot of pressure on incident response teams as they are required to manually monitor systems, keep track of alerts and avoid fatigue. Hence automating some or most of the incident response processes can help get rid of repetitive work. It helps response teams be more effective with less effort.&lt;/p&gt;

&lt;p&gt;That's not to say that people are no longer involved with incident response. People are still involved in triage, troubleshooting, and postmortem analysis. It's just that those tasks are much less frequent than they were before automation became the norm.&lt;/p&gt;

&lt;p&gt;Incident Response used to be about reacting to what happened with a solution for an immediate ‘bleed stop’. Nowadays, it is more about being proactive and trying to prevent incidents altogether by understanding and gaining intelligence about why something has happened.&lt;/p&gt;

&lt;p&gt;Incident response and management have become more of a DevOps-based activity. Where operational issues are addressed through code and automation, rather than manual intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Responding to an Incident&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the SRE (Site Reliability Engineering) realm, the incident response can be divided into following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Detect&lt;/li&gt;
&lt;li&gt;Respond&lt;/li&gt;
&lt;li&gt;Resolution and Recovery&lt;/li&gt;
&lt;li&gt;Postmortems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s expand on those and understand how incidents were responded to in the past, and how they are now.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Detect&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This step is where you detect an issue or determine if there has been a breach. A breach or incident could originate from different sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional:&lt;/strong&gt; Primary source of detection would most likely be calls or emails from the impacted users. Monitoring and alerting tools weren’t as ubiquitous as today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern:&lt;/strong&gt; An issue will usually be caught through monitoring and alerting on metrics, or in another case by people noticing something strange while they're doing their work. With alerting tools and right schedules in place it is easier to detect such issues so they can be dealt with due process.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Respond&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This is the step where you analyze the issue at hand and take a call on whether to contain the damage or terminate the concerned services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional:&lt;/strong&gt; The limitations of technology made it difficult to connect globally. Cross-functional localized teams would come together to figure out the issue. It often led to forcing resources to quit the work at hand and focus on solving the issue. This chopping and changing would particularly impact developers the most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern:&lt;/strong&gt; Modern-day teams analyze the metrics and logs to determine how bad the outage is. Is it a brief spike in errors? Are a few nodes going offline? Or is it a full-on service disruption? This step involves analyzing metrics and logs before responding further. This is where your colleagues from other sectors would collaborate for help. Using modern ChatOps tools like Slack, Microsoft Teams helps in effective collaboration. This keeps the right people connected even globally if needed.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Resolution and Recovery&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Once you've analyzed and pinpointed the root cause, you need to resolve the issue and ensure the system has recovered, with the affected systems and devices up and running again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional:&lt;/strong&gt; The process was unstructured. There was a lack of coordination between people, which led to support people tripping over and duplicating efforts. The aim of recovery was to get the system up and running, and nothing much followed. Getting to the root cause was rarely an objective until the same issue occurred repeatedly.&lt;/p&gt;

&lt;p&gt;This changed with time as processes were put into place. But lack of automation meant that the on-call schedules were still not very efficient and there was a lot of manual work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern:&lt;/strong&gt; These days, various tools and techniques are used to deal with issues. The decision is based on the issue that is being dealt with and the team's capabilities. For example, if you're experiencing network issues and your team has access to network engineering resources, they may be able to resolve the issue quickly by adjusting settings on routers or switches.&lt;/p&gt;

&lt;p&gt;Recovery is usually coordinated by the on-call incident handler, who is responsible for implementing a solution and making sure it does not fail. The SRE team then follows up with the manager to make sure the fix works as intended and, if necessary, to mitigate any damage caused by the outage. Another goal is to prevent such incidents from happening again&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Postmortems&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A postmortem is written after the issue is resolved, and everything has calmed down. Once the postmortem write-up is ready, a meeting occurs and is led by an SRE manager or incident handler who distributes the postmortem notes to relevant parties within the organization.&lt;/p&gt;

&lt;p&gt;The goal of this meeting is to review what happened during the outage, why it happened, what was done to stop it, and how it could have been prevented in the future. The postmortem then becomes part of an organization's operational history, allowing teams to learn from past mistakes and improve their overall reliability going forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional:&lt;/strong&gt; Traditional postmortems were either internal reports that were never seen outside the company or formal reports submitted to external auditors.&lt;/p&gt;

&lt;p&gt;Both constraints made it difficult to share detailed information about what happened and why it happened. Traditional postmortems are typically tactical documents that focus on how IT personnel responds to an incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern:&lt;/strong&gt; The practice of postmortems is an established part of modern incident response and is generally written as after-the-fact documentation.&lt;/p&gt;

&lt;p&gt;Modern digital postmortems are more inclusive of all teams involved, including the stakeholders. And should be viewed as strategic points that focus on lessons learned by the entire organization.&lt;/p&gt;

&lt;p&gt;They can be used for training purposes since they document case studies from completed investigations. They allow you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze past issues&lt;/li&gt;
&lt;li&gt;Find trends and make predictions about future risks&lt;/li&gt;
&lt;li&gt;Help you learn from mistakes&lt;/li&gt;
&lt;li&gt;Prevent a recurrence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An excellent example for a postmortem template, and what should be included, &lt;a href="https://sre.google/sre-book/example-postmortem/" rel="noopener noreferrer"&gt;can be found in the first SRE book by Google&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This brings us to the end of this blog. We have successfully explored what incident response is and how it has evolved with time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Create a blameless culture by reducing the need for physical war rooms, unify internal &amp;amp; external SLIs, automate incident resolution and create a knowledge base to effectively handle incidents.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ljesGLP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c51758c58939b30a6fd3d73/60d2ec8e2d9d85d17141958f_footer_banner-2000x761.png" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>incidentresponse</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Infrastructure as Code: All you need to know</title>
      <dc:creator>Kristijan</dc:creator>
      <pubDate>Tue, 04 Jan 2022 13:42:52 +0000</pubDate>
      <link>https://dev.to/squadcast/infrastructure-as-code-all-you-need-to-know-3h85</link>
      <guid>https://dev.to/squadcast/infrastructure-as-code-all-you-need-to-know-3h85</guid>
      <description>&lt;p&gt;&lt;em&gt;Using Code to create and manage deployments is more time-efficient and less tedious when compared to using CLI or even UI. In this blog, we explore the buzz around the usage of Infrastructure as Code (IaC) and how Terraform can be used to implement IaC.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this blog post, we will explore the good, the bad, and the ugly sides of infrastructure as code so you can make an informed decision on how (and why) to incorporate it into your workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is Infrastructure as Code?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Infrastructure as code (abbreviated as IaC) is a set of practices for infrastructure management that enables it to be managed and coordinated by code, instead of the traditional way of using CLI or UI.&lt;/p&gt;

&lt;p&gt;You would want to have a solution that allows you to easily manage and provision infrastructure with reusability and templating in mind.&lt;/p&gt;

&lt;p&gt;One of its most important benefits is that infrastructure as code enables infrastructure to be easily defined, replicated, templated, and put into a version-controlled system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why should I use Infrastructure as Code?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Infrastructure as code is beneficial for several reasons including automation, infrastructure consistency across environments, and full infrastructure history over time through the use of version control.&lt;/p&gt;

&lt;p&gt;This allows you and your team to have increased collaboration since IaC templates can be stored inside git repositories and can easily be collaborated all across.&lt;/p&gt;

&lt;p&gt;It also makes it easier for new team members to ramp up on how things work in your environment; because there is less need for documentation or handoffs between teammates - everything needed will already be available, on GitHub for example.&lt;/p&gt;

&lt;p&gt;IaC enables infrastructure to scale just like software does, with definitions for multiple environments such as development, staging, and production.&lt;/p&gt;

&lt;p&gt;This means infrastructure can be quickly modified during the development process and the changes can be tested in an environment that is identical to production, hence minimizing any errors.&lt;/p&gt;

&lt;p&gt;It is much quicker to code or supply templates for new infrastructure than it is to use a CLI console or UI.&lt;/p&gt;

&lt;p&gt;Of course, there are exceptions depending on the infrastructure end goal.&lt;/p&gt;

&lt;p&gt;The tools can help you create things in parallel. Imagine creating ten instances that need having extra disks attached.&lt;/p&gt;

&lt;p&gt;Even though this goal is quite straightforward, it will take you an eternity to complete it. You would need to click through UI wizards countless times to spin up all instances.&lt;/p&gt;

&lt;p&gt;However, utilizing the potential of IaC makes this simple.&lt;/p&gt;

&lt;p&gt;The code may be used to iterate through a list of your chosen Instances and create them in a breeze.&lt;/p&gt;

&lt;p&gt;It's crucial to remember that infrastructure as code is not a magic bullet for infrastructure management.&lt;/p&gt;

&lt;p&gt;IaC is only one piece of the puzzle, as with everything, there is more to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How do I get started with Infrastructure as Code?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are many infrastructure as code tools such as Terraform, Pulumi, CloudFormation, and others which we will take a look at in a minute.&lt;/p&gt;

&lt;p&gt;To get started with IaC, you must first have established a goal and objective on how you want to manage your infrastructure.&lt;/p&gt;

&lt;p&gt;For managing the infrastructure, it is easier if it’s to be provisioned and run through a cloud provider.&lt;/p&gt;

&lt;p&gt;Although, the versatility of IaC still enables you to manage even physical infrastructure. This is no exception.&lt;/p&gt;

&lt;p&gt;In general, IaC works well with any infrastructure that can be defined using code or templates.&lt;/p&gt;

&lt;p&gt;You might use IaC to define the entirety of your infrastructure, or you may go hybrid and define some services using IaC while others through UI or CLI tooling.&lt;/p&gt;

&lt;p&gt;Keep in mind that attempting to integrate current infrastructure into IaC code is a little more challenging and will require some effort, but isn't impossible. It is much easier starting from scratch with IaC.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The pros and cons of using Infrastructure as Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Some pros and cons were already mentioned in the previous sections.&lt;/p&gt;

&lt;p&gt;However, let's clear it up and look at them compared.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as code is version controlled, which means you have a history of who did what and which changes have been done on the environment.&lt;/li&gt;
&lt;li&gt;In case of an issue, you can easily roll back to a previous state if needed.&lt;/li&gt;
&lt;li&gt;IaC enables infrastructure to be quickly modified during the development process and changes tested in an environment that is identical to production.&lt;/li&gt;
&lt;li&gt;It's much quicker for a human to code infrastructure than it is to provision infrastructure via user interfaces. Your already written code blocks and templates can be reused in the future.&lt;/li&gt;
&lt;li&gt;IaC tools are readily available which can be used for managing infrastructure across cloud providers, on-premises, or even hybrid environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is difficult to integrate current infrastructure into IaC in the case of an existing environment where you have a lot of infrastructure(s) already created.&lt;/li&gt;
&lt;li&gt;There is a learning curve and requires some effort to get infrastructure provisioned via IaC. However, it's well worth the effort spent in learning it.&lt;/li&gt;
&lt;li&gt;You must be able to define infrastructure using code or templates for IaC to work. This means learning another language, syntax, and logic.&lt;/li&gt;
&lt;li&gt;Not everything can be created and connected by the use of IaC; there are some limitations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tools for Infrastructure as Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are many IaC tools that you may use to manage infrastructure.&lt;/p&gt;

&lt;p&gt;Some of these include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; for managing infrastructure in any cloud provider or your own data center.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/cloudformation/" rel="noopener noreferrer"&gt;CloudFormation&lt;/a&gt; from Amazon AWS enables you to define resources through custom templates.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/" rel="noopener noreferrer"&gt;Pulumi&lt;/a&gt; is another open-source tool for infrastructure as code which was created by former Google employees with experience in managing infrastructure at scale.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview" rel="noopener noreferrer"&gt;Azure Resource Manager&lt;/a&gt; which is Microsoft's answer to infrastructure as code. Using ARM you can easily provision infrastructure using JSON templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most commonly used IaC tool is Terraform, as it offers a vendor-agnostic approach with extended support for different providers, services, and infrastructure components.&lt;/p&gt;

&lt;p&gt;Terraform enables you to define infrastructure using the declarative approach. By writing configuration files in its language, HCL and reusability of code through modules.&lt;/p&gt;

&lt;p&gt;You may use these building blocks for configuration management, data management, continuous delivery workflows, serverless functions, and a variety of other applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Terraform Demo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can now see how IaC can help automate creating multiple instances.&lt;/p&gt;

&lt;p&gt;To demonstrate the power of IaC, let's take on the task of creating the ten instances here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "3.89.0"
    }
  }
}

provider "google" {}

variable "instance_count" {
  default = "10"
}

resource "google_compute_instance" "instance" {
  count        = var.instance_count
  project      = "YOUR-PROJECT-ID"
  zone         = "us-central1-a"

  name         = "squadcast-instance-${count.index}"
  machine_type = "e2-medium"

  attached_disk {
    source = "instance-disk-${count.index}"
  }

  lifecycle {
    ignore_changes = [attached_disk]
  }

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network    = "default"
  }
}

resource "google_compute_disk" "instance-disk" {
  count   = var.instance_count
  project = "YOUR-PROJECT-ID"
  zone    = "us-central1-a"

  name    = "instance-disk-${count.index}"
  type    = "pd-ssd"
  size    = "50"
  physical_block_size_bytes = 4096
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three commands are executed in succession:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;terraform init&lt;/em&gt;&lt;/strong&gt; - to initialize Terraform, prepare, and download all the necessary files before running&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;terraform plan&lt;/em&gt;&lt;/strong&gt; - to print out the execution plan on what infrastructure elements will be created(or deleted)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;terraform apply&lt;/em&gt;&lt;/strong&gt; - finally applying the staged changes and executing the creation of the instances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a breeze, all the instances are created along with the extra pair of disks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2941c8003d8c7b0cab1_image3.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2941c8003d8c7b0cab1_image3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2a0deccc3555e1702ea_image1.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2a0deccc3555e1702ea_image1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2ac5c8f599d756df435_image2.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F61a0d2ac5c8f599d756df435_image2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c51758c58939b30a6fd3d73%2F60d2ec8e2d9d85d17141958f_footer_banner-2000x761.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
    </item>
    <item>
      <title>Implementing Istio in a Kubernetes cluster</title>
      <dc:creator>Kristijan</dc:creator>
      <pubDate>Mon, 25 Oct 2021 13:22:34 +0000</pubDate>
      <link>https://dev.to/squadcast/implementing-istio-in-a-kubernetes-cluster-3d69</link>
      <guid>https://dev.to/squadcast/implementing-istio-in-a-kubernetes-cluster-3d69</guid>
      <description>&lt;p&gt;&lt;em&gt;As the complexity of a microservice architecture grows, it becomes important to implement a service mesh for better insights into your cluster and microservices. In this blog, &lt;a href="https://www.linkedin.com/in/kristijan-mitevski/" rel="noopener noreferrer"&gt;Kristijan&lt;/a&gt; explains how Istio can be used as a service mesh, along with a detailed installation steps &amp;amp; configuration setup.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Service Mesh? You’ve heard about it, but does it solve something, or is it just another hot buzzword in the industry?&lt;/p&gt;

&lt;p&gt;In this article you will learn about the Istio service mesh, along with a full installation guide and configuration setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Table of contents&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What is Istio?&lt;/li&gt;
&lt;li&gt;Istio architecture&lt;/li&gt;
&lt;li&gt;Installing Istio&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Demo application&lt;/li&gt;
&lt;li&gt;Recap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before moving straight to Istio, it’s worth mentioning that in one of our previous articles - &lt;a href="https://www.squadcast.com/blog/the-age-of-service-mesh" rel="noopener noreferrer"&gt;The Age of Service Mesh&lt;/a&gt;, Gigi Sayfan explained in detail how service meshes work and what problems they solve.&lt;/p&gt;

&lt;p&gt;I highly suggest you give that article a read. Maybe even as a prequel, as it will provide you with great insight into service mesh basics and the general idea behind them.&lt;/p&gt;

&lt;p&gt;Right now, there are a plethora of options for service meshes.&lt;/p&gt;

&lt;p&gt;To name a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://istio.io/latest/" rel="noopener noreferrer"&gt;Istio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linkerd.io/" rel="noopener noreferrer"&gt;Linkerd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://traefik.io/traefik-mesh/" rel="noopener noreferrer"&gt;Traefik&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hashicorp.com/products/consul/multi-platform-service-mesh" rel="noopener noreferrer"&gt;Consul&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kuma.io/" rel="noopener noreferrer"&gt;Kuma&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each service mesh has its pros and cons, along with specific use cases that you should consider for your cluster and end goal.&lt;/p&gt;

&lt;p&gt;You can decide which “brand” of a service mesh to install.&lt;/p&gt;

&lt;h3 id="istio"&gt;&lt;b&gt;What is Istio?&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Istio is a service mesh designed to enhance and give you better insight into your cluster and microservices.&lt;/p&gt;

&lt;p&gt;One of the great things about Istio and service meshes overall is that they require absolutely no code change for them to work.&lt;/p&gt;

&lt;p&gt;Istio works by integrating itself as an additional layer inside the Kubernetes cluster and thus provides modern features that you can utilize to your advantage.&lt;/p&gt;

&lt;p&gt;Those features can include advanced load balancing, circuit breaking, mTLS traffic encryption, better authentication and authorization options, metrics, telemetry, and overall fine-grain control over the cluster’s traffic going in and out.&lt;/p&gt;

&lt;p&gt;Now Istio isn’t just a single object that you install. It’s more of a collection of entities that work together and make up the whole service mesh.&lt;/p&gt;

&lt;p&gt;Like Kubernetes, Istio has a control plane that manages everything and a data plane that handles the traffic between the services.&lt;/p&gt;

&lt;p&gt;There is more to Istio, as it isn’t bound to only work in a Kubernetes cluster. It will also work with virtual machines and supports different deployment options both for installing and running.&lt;/p&gt;

&lt;p&gt;In the next section, we will explain Istio’s components and architecture.&lt;/p&gt;

&lt;h3 id="istio-architecture"&gt;&lt;b&gt;Istio Architecture&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;As the saying goes, a picture is worth a thousand words.&lt;/p&gt;

&lt;p&gt;Consider the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rgAFsoeI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61667c91616d7eecf473416f_image2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rgAFsoeI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61667c91616d7eecf473416f_image2.png" width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://istio.io/latest/docs/ops/deployment/architecture/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;



&lt;p&gt;You can see that the traffic destined in and out of the pods doesn’t flow directly now; Instead, it first must pass through the sidecar proxies.&lt;/p&gt;

&lt;p&gt;The container sidecars are Envoy proxies that get automatically injected into your pods on startup.&lt;/p&gt;

&lt;p&gt;During installation, you instruct Istio which namespace to ‘watch’ and deploy Envoy proxies along with your applications.&lt;/p&gt;

&lt;p&gt;You will see how this is done in action when we get to the installing section.&lt;/p&gt;

&lt;p&gt;The other part is the control plane, made of multiple components bundled in one binary - &lt;a href="https://istio.io/latest/docs/ops/deployment/architecture/#istiod" rel="noopener noreferrer"&gt;istiod&lt;/a&gt;. The control plane manages the proxies, certificates, service discovery, and executing the configuration you set.&lt;/p&gt;

&lt;p&gt;The components making Istio are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;Envoy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://istio.io/v1.4/docs/ops/deployment/architecture/#pilot" rel="noopener noreferrer"&gt;Pilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://istio.io/v1.4/docs/ops/deployment/architecture/#citadel" rel="noopener noreferrer"&gt;Citadel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://istio.io/v1.4/docs/ops/deployment/architecture/#citadel" rel="noopener noreferrer"&gt;Galley&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To explain a bit better and give some analogy here.&lt;/p&gt;

&lt;p&gt;Consider the service mesh as a telephone network.&lt;/p&gt;

&lt;p&gt;The data plane consists of phones that you and your friends use to communicate with each other.&lt;/p&gt;

&lt;p&gt;You will be able to communicate without them, but you will have to yell across. Instead, this way is much more modern, secure, and with better control over the communication.&lt;/p&gt;

&lt;p&gt;Now the control plane will be the telephone service provider, and from there, all the calls get managed, routed, and billed.&lt;/p&gt;

&lt;p&gt;Everything you apply is done towards and on the control plane; the control plane will communicate that change to the sidecar proxies.&lt;/p&gt;

&lt;p&gt;The traffic traversing the data plane is only visible to the proxies; the other Istio components have no access.&lt;/p&gt;

&lt;h3 id="installing-istio"&gt;&lt;b&gt;Installing Istio&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Depending on your setup, Istio offers you different installation and &lt;a href="https://istio.io/latest/docs/ops/deployment/deployment-models/" rel="noopener noreferrer"&gt;deployment strategies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each cloud service provider has its own thing. So it’s best to go over the &lt;a href="https://istio.io/latest/docs/setup/platform-setup/" rel="noopener noreferrer"&gt;platform setup&lt;/a&gt; and check if any prerequisites or dependencies are needed before installing.&lt;/p&gt;

&lt;p&gt;The install options can range from using helm, istioctl, or using an operator.&lt;/p&gt;

&lt;p&gt;You can look into them &lt;a href="https://istio.io/latest/docs/setup/install/" rel="noopener noreferrer"&gt;at the following link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this guide, we will install Istio using the &lt;code&gt;istioctl&lt;/code&gt; tool.&lt;/p&gt;

&lt;p&gt;First, you’ll need to download the binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -L https://istio.io/downloadIstio | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate into the newly created folder, export the path to the binary, and verify that it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd istio-1.11.1/
$ export PATH=$PWD/bin:$PATH
$ istioctl version

no running Istio pods in "istio-system"
1.11.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, that’s okay, you still haven’t installed Istio.&lt;/p&gt;

&lt;p&gt;It is a good idea to run the pre-flight check to verify if your cluster doesn’t have any issues running the Istio service mesh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ istioctl x precheck

Install Pre-Check passed! The cluster is ready for Istio installation. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before moving forward, you should assess which type of profile you want Istio to be installed with.&lt;/p&gt;

&lt;p&gt;There are six of them at the time of this writing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;li&gt;Minimal&lt;/li&gt;
&lt;li&gt;External&lt;/li&gt;
&lt;li&gt;Empty&lt;/li&gt;
&lt;li&gt;Preview&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can view each profile with an extended description &lt;a href="https://istio.io/latest/docs/setup/additional-setup/config-profiles/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will go with the default profile intended for production environments.&lt;/p&gt;

&lt;p&gt;Each profile is just a set of features that Istio will enable when installed.&lt;/p&gt;

&lt;p&gt;If you want to test every feature, you can install it using the &lt;code&gt;demo&lt;/code&gt; profile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Installing profiles that include the Ingress or Egress Gateway will automatically spin up an external load balancer.&lt;/p&gt;

&lt;p&gt;Istio also offers customizations and custom third-party add-ons you can include in the profile.&lt;/p&gt;

&lt;p&gt;Suppose none of the above profiles meet your requirements, you can &lt;a href="https://istio.io/latest/docs/setup/install/istioctl/#generate-a-manifest-before-installation" rel="noopener noreferrer"&gt;use istioctl to generate and create custom manifests&lt;/a&gt; to fit your needs.&lt;/p&gt;

&lt;p&gt;To install using the default profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ istioctl install --set profile=default -y

✔ Istio core installed             
✔ Istiod installed                                                         
✔ Egress gateways installed  
✔ Ingress gateways installed
✔ Installation complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excellent! You’ve installed Istio successfully!&lt;/p&gt;

&lt;p&gt;You are halfway there.&lt;/p&gt;

&lt;p&gt;Now you will need to label which namespace Istio will control and inject sidecar proxies in the pods.&lt;/p&gt;

&lt;p&gt;For example, to label the default namespace for sidecar injection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl label namespace default istio-injection=enabled

namespace/default labeled

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now verify this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get ns --show-labels

NAME            STATUS      AGE      LABELS
default         Active      119d     istio-injection=enabled
[other output truncated]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, you completed the Istio core components installation.&lt;/p&gt;

&lt;h3 id="observability"&gt;&lt;b&gt;Observability&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;I installed Istio, and now what?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next comes the observability part.&lt;/p&gt;

&lt;p&gt;The Envoy proxies will send off telemetry and other data that you can use to visualize the traffic in the mesh.&lt;/p&gt;

&lt;p&gt;Like the Prometheus and the Grafana setup, you will need Istio paired with a visualization tool to display the data.&lt;/p&gt;

&lt;p&gt;You will use the &lt;a href="https://kiali.io/" rel="noopener noreferrer"&gt;Kiali&lt;/a&gt; dashboard to visualize and see what’s going on in the cluster.&lt;/p&gt;

&lt;p&gt;There is one caveat, however. Kiali requires that you have a running Prometheus instance in your cluster.&lt;/p&gt;

&lt;p&gt;You can deploy one or supply the address of the existing one if you have it already deployed.&lt;/p&gt;

&lt;p&gt;For simplicity and example purposes, the following section will use the demo manifests for deploying Kiali, &lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;, &lt;a href="https://prometheus.io/" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt;, and &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Keep in mind that you shouldn’t rely on this setup for running in production environments!&lt;/p&gt;

&lt;p&gt;Further below, there will be an explanation of how to set up Kiali to work with an existing Prometheus instance.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Installing the Kiali dashboard&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Navigate to the Istio folder and apply the manifests located under &lt;code&gt;samples/addons&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;$  kubectl apply -f samples/addons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applying the above will deploy many objects, so give them a couple of minutes to start.&lt;/p&gt;

&lt;p&gt;Check on the Kiali pod if it’s started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n istio-system get pods -l app=kiali

NAME                           READY    STATUS    RESTARTS      AGE
kiali-787bc487b7-fbxwm         1/1      Running   0             2m10s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it’s running, you can now access the dashboard using &lt;code&gt;kubectl&lt;/code&gt; and &lt;code&gt;port-forward&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, &lt;code&gt;istioctl&lt;/code&gt; offers a much simpler way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ istioctl dashboard kiali

http://localhost:20001/kiali 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;open &lt;a href="http://localhost:20001/kiali" rel="noopener noreferrer"&gt;http://localhost:20001/kiali&lt;/a&gt; in your browser.&lt;/p&gt;

&lt;p&gt;As you can see, there is no traffic running in the selected namespace, and Kiali will show no connections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VvAUU8wj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616684f1618edf702efa6eba_image4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VvAUU8wj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616684f1618edf702efa6eba_image4.png" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to access the other dashboards - Grafana and Jaeger, you can again use &lt;code&gt;istioctl dashboard&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;$ istioctl dashboard grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3jb27wZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/6166859af9a3b12e27b0ffbb_image7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3jb27wZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/6166859af9a3b12e27b0ffbb_image7.png" width="800" height="392"&gt;&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;$ istioctl dashboard jaeger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DSbQ1IoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616685e77fab1b7f6fc90b66_image5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DSbQ1IoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616685e77fab1b7f6fc90b66_image5.png" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Kiali tips&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;There are also other ways to deploy Kiali that are more inclined to production use, where you can customize and set your own parameters.&lt;/p&gt;

&lt;p&gt;Installing Kiali can be done by deploying the &lt;a href="https://kiali.io/documentation/v1.39/installation-guide/#_kiali_only_install" rel="noopener noreferrer"&gt;Kiali-server&lt;/a&gt; or the &lt;a href="https://kiali.io/documentation/latest/installation-guide/#_helm_chart" rel="noopener noreferrer"&gt;Kiali-operator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can find the GitHub link for both Helm charts &lt;a href="https://github.com/kiali/helm-charts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned in the previous section, you can specify external instances of Prometheus and the other tools.&lt;/p&gt;

&lt;p&gt;It’s best to install all the tooling Kiali needs for you to have the most benefit and greater observability in the service mesh.&lt;/p&gt;

&lt;p&gt;Those are the Prometheus instance, Grafana, and Jaeger for tracing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Refer to the Jaeger documentation as it requires additional configuration to have full distributed tracing in your apps.&lt;/p&gt;

&lt;p&gt;Grafana and Jaeger are optional for Kiali and not required for it to work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KGWS3LmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616686624a51663a95303cf7_image6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KGWS3LmJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616686624a51663a95303cf7_image6.png" width="701" height="394"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://kiali.io/documentation/latest/architecture/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;



&lt;p&gt;You can specify every connection to the other systems during installation.&lt;/p&gt;

&lt;p&gt;Example, for specifying an &lt;a href="https://kiali.io/documentation/v1.36/runtimes-monitoring/#_using_another_prometheus_instance" rel="noopener noreferrer"&gt;existing Prometheus instance&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 install kiali-server kiali-server --repo https://kiali.org/helm-charts \
  -n istio-system \
  --set auth.strategy="anonymous" \
  --set external_services.custom_dashboards.prometheus.url="http://prometheus-k8s.monitoring:9090/" \
  --set external_services.prometheus.url="http://prometheus-k8s.monitoring:9090/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Kiali authentication options are available &lt;a href="https://kiali.io/documentation/latest/configuration/authentication/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;anonymous&lt;/code&gt; option used above provides free unauthenticated access to the dashboard.&lt;/p&gt;

&lt;h3 id="demo-application"&gt;&lt;b&gt;Demo application&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;You’ve deployed Istio, have a running service mesh inside your cluster, and you also installed the Kiali dashboard to observe the traffic.&lt;/p&gt;

&lt;p&gt;Let’s now deploy a simple demo application.&lt;/p&gt;

&lt;p&gt;You can use the following &lt;a href="https://github.com/paulbouwer/hello-kubernetes" rel="noopener noreferrer"&gt;hello-world web app&lt;/a&gt; that will display a simple web page for testing.&lt;/p&gt;

&lt;p&gt;Apply the following deployment and service manifests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
spec:
  selector:
    matchLabels:
      name: hello-kubernetes
  template:
    metadata:
      labels:
        name: hello-kubernetes
    spec:
      containers:
      - name: app
        image: paulbouwer/hello-kubernetes:1.10
        ports:
          - containerPort: 8080
        env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: KUBERNETES_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: KUBERNETES_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
---
apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    name: hello-kubernetes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that the pod is running and the service is deployed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pod,svc

NAME                                     READY   STATUS        RESTARTS      AGE
pod/hello-kubernetes-78c896db9c-hrcc8    2/2     Running       0             46s

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP    PORT(S)     AGE
service/hello-kubernetes    ClusterIP   10.0.12.41       &amp;lt;none&amp;gt;         80/TCP      47s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, for testing, you can use port-forward to access the application. However, a more permanent solution would be to use a load balancer or an ingress.&lt;/p&gt;

&lt;p&gt;Istio has its own ingress controller that you can utilize and test the application.&lt;/p&gt;

&lt;p&gt;The following ingress manifest will expose the application on the &lt;code&gt;/&lt;/code&gt; path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: istio
  name: ingress-hello-kubernetes
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-kubernetes
            port:
              number: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Notice the ingress class annotation; you specify that the Istio ingress controller will pick up this object.&lt;/p&gt;

&lt;p&gt;You can get the IP address using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n istio-system get svc -l release=istio

NAME                    TYPE            CLUSTER-IP      EXTERNAL-IP    
istio-egressgateway     ClusterIP       10.0.12.240     &amp;lt;none&amp;gt;                                                                              
istio-ingressgateway    LoadBalancer    10.0.13.159     34.140.202.188   
istiod                  ClusterIP       10.0.8.208      &amp;lt;none&amp;gt;      
[other output truncated]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visiting the external IP of the ingress gateway will open up the web application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ylOHYF6M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668ab0effdf12585af95cc_image1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ylOHYF6M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668ab0effdf12585af95cc_image1.png" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see some activity in the Kiali dashboard, you first need to generate some traffic.&lt;/p&gt;

&lt;p&gt;The simplest way is to use curl and a while loop:&lt;/p&gt;

&lt;p&gt;From another terminal run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ while true; do curl 34.140.202.188 ; sleep 1; done;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And check the Kiali dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wgqa8wXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668b16adf50676c468e783_image3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wgqa8wXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668b16adf50676c468e783_image3.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Success!!&lt;/p&gt;

&lt;p&gt;You can now see that Kiali displays the traffic, and it reaches the web application without any issues.&lt;/p&gt;

&lt;h3 id="recap"&gt;&lt;b&gt;Recap&lt;/b&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You learned what is Istio and how it works&lt;/li&gt;
&lt;li&gt;Got your hands dirty by installing and configuring Istio in a cluster&lt;/li&gt;
&lt;li&gt;In addition to that, you installed Kiali to visualize the traffic in the mesh&lt;/li&gt;
&lt;li&gt;You deployed a demo application and connected it using Istio’s ingress
‍&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ljesGLP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c51758c58939b30a6fd3d73/60d2ec8e2d9d85d17141958f_footer_banner-2000x761.png" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>observability</category>
    </item>
    <item>
      <title>Infrastructure monitoring using kube-prometheus operator</title>
      <dc:creator>Kristijan</dc:creator>
      <pubDate>Wed, 09 Jun 2021 12:36:29 +0000</pubDate>
      <link>https://dev.to/squadcast/infrastructure-monitoring-using-kube-prometheus-operator-3kkg</link>
      <guid>https://dev.to/squadcast/infrastructure-monitoring-using-kube-prometheus-operator-3kkg</guid>
      <description>&lt;p&gt;&lt;em&gt;Prometheus has emerged as the de-facto open source standard for monitoring Kubernetes implementations. In this tutorial, &lt;a href="https://www.linkedin.com/in/kristijan-mitevski/" rel="noopener noreferrer"&gt;Kristijan Mitevski&lt;/a&gt; shows how infrastructure monitoring can be done using kube-prometheus operator. The blog also covers how the Prometheus Alertmanager cluster can be used to route alerts to Slack using webhooks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial by Squadcast, you will learn how to install and configure infrastructure monitoring for your Kubernetes cluster using the kube-prometheus operator, displaying metrics with Grafana, and configuring alerting with Alertmanager.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Infrastructure Monitoring&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the key principles of running clusters in production is Monitoring.&lt;/p&gt;

&lt;p&gt;You must be aware of the resource allocation and limits of each component that is a part of the cluster.&lt;/p&gt;

&lt;p&gt;It is of crucial importance to have insight and observability in your cluster be it a Kubernetes one, bare metal, virtual machines, or any other.&lt;/p&gt;

&lt;p&gt;A good monitoring solution paired with a set of metrics and alerting will provide a safe environment for your workloads.&lt;/p&gt;

&lt;p&gt;It’s safe to say that monitoring a Kubernetes cluster comes in two parts - infrastructure and workload monitoring.&lt;/p&gt;

&lt;p&gt;The first part covers the actual infrastructure that supports your workloads. These will be the nodes or instances that host your applications. And by collecting and observing the metrics you will be very well aware of the node's health, usage, and capacity.&lt;/p&gt;

&lt;p&gt;The other part that needs to be covered are the workloads and the microservices that you deploy on the cluster.&lt;/p&gt;

&lt;p&gt;These can be defined in your applications or in the Kubernetes ecosystem - the pods and  containers.&lt;/p&gt;

&lt;p&gt;Monitoring just the instances is not enough, since Kubernetes abstracts and adds additional layers for container management, this also needs to be taken into account.&lt;/p&gt;

&lt;p&gt;The Pods are entities of their own, each with different resource requirements, limits, and usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Prometheus Operator&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before moving on to installing the monitoring stack, let’s have a brief intro on what the Kubernetes Operators and Custom Resources are.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://www.squadcast.com/blog/kubernetes-operators-for-automated-sre" rel="noopener noreferrer"&gt;one of our previous blogs&lt;/a&gt;, we explained in detail what and how Kubernetes Operators and Custom Resources are used.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/" rel="noopener noreferrer"&gt;Kubernetes operators&lt;/a&gt; take the Kubernetes controller pattern that manages native Kubernetes resources (Pods, Deployments, Namespaces, Secrets, etc) and lets you apply it to your own custom resources.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-resources" rel="noopener noreferrer"&gt;Custom resources&lt;/a&gt; are Kubernetes objects that you define via &lt;a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions" rel="noopener noreferrer"&gt;CRDs (Custom Resource Definitions)&lt;/a&gt;. Once a CRD is defined, you can create custom resources based on the definition and they are stored by Kubernetes. And you can interact with them through the Kubernetes API or kubectl, just like existing resources.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you’ve read, both of these resources are extensions to the Kubernetes API and are not available by default like those of Deployment or StatefulSet kinds.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/prometheus-operator/prometheus-operator" rel="noopener noreferrer"&gt;Prometheus Operator&lt;/a&gt; will manage and configure a Prometheus cluster for you. Bear in mind that this contains only the core components.&lt;/p&gt;

&lt;p&gt;And instead, in this tutorial, you will deploy the more enhanced - kube-prometheus operator.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://prometheus-operator.dev/" rel="noopener noreferrer"&gt;kube-prometheus operator&lt;/a&gt; will deploy all the core components plus exporters, extra configurations, dashboards, and everything else required to get your cluster monitoring up to speed.&lt;/p&gt;

&lt;p&gt;These configurations can then be easily modified to suit your needs.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart" rel="noopener noreferrer"&gt;follow the official link&lt;/a&gt; if you wish to compare the differences between the operator deployment options.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; Manually deploying the Prometheus stack is still an option. However, you will need to deploy every component separately. This creates operational toil and will require a lot of manual steps until all services are configured and connected properly.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Installing the kube-prometheus operator&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Although Kubernetes Operators may sound complex and scary, fear not, their installation is a breeze!&lt;/p&gt;

&lt;p&gt;The people contributing to the Prometheus Operator project made its install straightforward.&lt;/p&gt;

&lt;p&gt;Just a couple of commands need to be executed and you will have your monitoring set up in the cluster.&lt;/p&gt;

&lt;p&gt;Let’s start.&lt;/p&gt;

&lt;p&gt;To install the kube-prometheus operator, first clone the repository containing all the necessary files with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/prometheus-operator/kube-prometheus.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now from inside the &lt;code&gt;kube-prometheus&lt;/code&gt; folder, apply the manifests located in the &lt;code&gt;manifests/setup&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;$ kubectl apply -f manifests/setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does is, first it’s creating the &lt;code&gt;monitoring&lt;/code&gt; namespace that will contain all deployments for the monitoring stack.&lt;/p&gt;

&lt;p&gt;Second, it will create all the necessary &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" rel="noopener noreferrer"&gt;RBAC&lt;/a&gt; roles, role bindings, and service accounts that are required for the monitoring services to have proper privileges for access and metrics gathering.&lt;/p&gt;

&lt;p&gt;And finally, it will create the aforementioned custom resources and custom resource definitions for the Prometheus Operator, and deploy them.&lt;/p&gt;

&lt;p&gt;With the previous command you deployed the files for the Operator &lt;strong&gt;itself&lt;/strong&gt;, but not for its services.&lt;/p&gt;

&lt;p&gt;Wait a bit until the &lt;code&gt;prometheus-operator&lt;/code&gt; pod is up and running.&lt;/p&gt;

&lt;p&gt;You can check on it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;NAME&lt;/th&gt;
&lt;th&gt;READY&lt;/th&gt;
&lt;th&gt;STATUS&lt;/th&gt;
&lt;th&gt;RESTARTS&lt;/th&gt;
&lt;th&gt;AGE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;prometheus-operator-7775c66ccf-74fn5&lt;/td&gt;
&lt;td&gt;2/2&lt;/td&gt;
&lt;td&gt;Running&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;58s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now you will need to deploy the services next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f manifests/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the above command will deploy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus with High Availability&lt;/li&gt;
&lt;li&gt;Alertmanager with High Availability&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;li&gt;Node exporters&lt;/li&gt;
&lt;li&gt;Blackbox exporter&lt;/li&gt;
&lt;li&gt;Prometheus adapter&lt;/li&gt;
&lt;li&gt;Kube-state-metrics&lt;/li&gt;
&lt;li&gt;And all other supporting services and configurations for the monitoring stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a couple of minutes, all the pods should get into a running state. You can verify again using the &lt;code&gt;kubectl get pods&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;You can now &lt;code&gt;port-forward&lt;/code&gt; and open the Prometheus, Grafana, and Alertmanager services locally:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Prometheus&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring port-forward svc/prometheus-k8s 9090
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Grafana&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring port-forward svc/grafana 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Alertmanager&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring port-forward svc/alertmanager-main 9093
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s best to check and open all of them, just to verify that everything works as expected.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; The default user and password for Grafana are admin/admin, after which you will be prompted to create a new password.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are greeted by the &lt;code&gt;services&lt;/code&gt; user interface, that means the install was successful and you can now explore, and configure the services to fit your needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60accb950a5bd91db35c20c3_image7.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60accb950a5bd91db35c20c3_image7.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before moving on, let’s understand how the services are interconnected and what role they serve in the monitoring stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Service Interaction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Consider the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e7c690691277941ce1f5_1.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e7c690691277941ce1f5_1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The high-level overview of the stack goes like this:&lt;/p&gt;

&lt;p&gt;Prometheus will periodically scrape (or pull) metrics via the configured exporters and metrics servers on the nodes using HTTP.&lt;/p&gt;

&lt;p&gt;The exporters don’t send out the data to Prometheus, instead, Prometheus pulls that data from endpoints set by exporters.&lt;/p&gt;

&lt;p&gt;The scraped metrics gets time-stamped and stored as time-series data, which get written to a persistent volume for storage, and later for analysis.&lt;/p&gt;

&lt;p&gt;A Config Map contains the rules and configurations for Prometheus.&lt;/p&gt;

&lt;p&gt;This configuration contains the rules, alerts, scraping jobs, and targets that Prometheus needs to do proper monitoring.&lt;/p&gt;

&lt;p&gt;Prometheus uses its own language called &lt;a href="https://www.squadcast.com/blog/infrastructure-monitoring-using-kube-prometheus-operator#" rel="noopener noreferrer"&gt;PromQL&lt;/a&gt; in which alerts can be set, and data queried.&lt;/p&gt;

&lt;p&gt;Example of a PromQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api_http_requests_total{method="POST", handler="/messages"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To visualize and display the data stored by Prometheus, Grafana comes into the picture.&lt;/p&gt;

&lt;p&gt;Grafana connects to Prometheus, sets it as the data source, fetches this data, and displays it through a custom dashboard.&lt;/p&gt;

&lt;p&gt;Alertmanager is used to notify us of any alerts. Rules set in Prometheus get evaluated, and once a violation occurs Prometheus pushes this alert notification to Alertmanager.&lt;/p&gt;

&lt;p&gt;Once Alertmanager receives this notification, based on its own rules for routing and grouping, it will then send it over to the configured Receivers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Similar to Prometheus, the Alertmanager rules also get stored separately either in Config Maps or Secrets.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These receivers can be either &lt;a href="https://app.squadcast.com/register" rel="noopener noreferrer"&gt;Squadcast Platform&lt;/a&gt;, Slack, Email, or any other configurable incident receiver.&lt;/p&gt;

&lt;p&gt;Let’s examine this Prometheus alerting rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;kubernetes-system-kubelet&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;rules:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;alert:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;KubeNodeNotReady&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;annotations:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$labels.node&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="err"&gt;has&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;been&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;unready&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;than&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;minutes.'&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;runbook_url:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://github.com/prometheus-operator/kube-prometheus/wiki/kubenodenotready&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;summary:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ready.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;expr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;kube_node_status_condition&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;job=&lt;/span&gt;&lt;span class="s2"&gt;"kube-state-metrics"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;condition=&lt;/span&gt;&lt;span class="s2"&gt;"Ready"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;status=&lt;/span&gt;&lt;span class="s2"&gt;"true"&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="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;for:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="err"&gt;m&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;labels:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;severity:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;warning&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;name - The name of the rule group; you can have multiple alerts under the same group&lt;/li&gt;
&lt;li&gt;rules - Configured rules under the rule group&lt;/li&gt;
&lt;li&gt;alert - Name of the actual Alert and how it will be displayed once it is firing&lt;/li&gt;
&lt;li&gt;annotations - Under annotations, you can set more details and summaries about the alert firing&lt;/li&gt;
&lt;li&gt;expr - The expression for the alert in PromQL language that gets evaluated&lt;/li&gt;
&lt;li&gt;for - How long will Prometheus wait from first encountering the alert until a notification is sent. If the alert is running for 15minutes or longer, Prometheus will send a notification to Alertmanager&lt;/li&gt;
&lt;li&gt;labels - additional labeling that you can attach to the alert&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the Go templating language, you can further detail your alert and give a clearer description.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Adding a custom alerting rule&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that you’ve learned more about how the whole Prometheus setup operates, you can modify its configuration and add your own custom alerting rules.&lt;/p&gt;

&lt;p&gt;As explained above, Prometheus gets its configuration data from a Config Map.&lt;/p&gt;

&lt;p&gt;If you describe the &lt;code&gt;prometheus-k8s&lt;/code&gt; Stateful Set, you will see the &lt;code&gt;prometheus-k8s-rule-files-0&lt;/code&gt; Config Map that contains the config rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;monitoring&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;statefulsets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prometheus-k&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;truncated&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;prometheus-k&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;s-rulefiles&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;populated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ConfigMap)&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;Name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prometheus-k&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;s-rulefiles&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;Optional:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now edit the config map and add your custom alert.&lt;/p&gt;

&lt;p&gt;Keep in mind that the config map will have a lot of lines!&lt;/p&gt;

&lt;p&gt;It’s best to save it and edit it offline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring get configmap prometheus-k8s-rulefiles-0 -o yaml &amp;gt; prometheus-k8s-rulefiles.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration inside will be split under separate YAML files. And each file will contain a group of alerts based on common alert targets.&lt;/p&gt;

&lt;p&gt;In this case, the example will cover adding an alerting rule under a new group.&lt;/p&gt;

&lt;p&gt;But if you like, you can add it under one of the existing alert groups.&lt;/p&gt;

&lt;p&gt;Add the following sample alert under the data block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;custom-alert-rules.yaml:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;groups:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;custom.rules&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;rules:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;alert:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;AlertTestJobFailed&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;expr:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;kube_job_status_failed&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;job_name=&lt;/span&gt;&lt;span class="s2"&gt;"alert-test"&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="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;for:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;m&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;labels:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;severity:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;warning&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;annotations:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;summary:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Alert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Job&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(instance&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="err"&gt;$labels.instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Job {{$labels.namespace}}/{{$labels.exported_job}} failed to complete&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; VALUE = {{ $value }}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; LABELS = {{ $labels }}"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The alert will fire if our Kubernetes job fails to execute. Which you will test in a moment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now comes the tricky part.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since the owner of the Config Map is the Prometheus Operator, you will need to remove the file ownership data.&lt;/p&gt;

&lt;p&gt;Otherwise, any modifications to the Config Map will be reverted back without any changes!&lt;/p&gt;

&lt;p&gt;Under the config map &lt;code&gt;metadata&lt;/code&gt; field remove anything but the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;namespace&lt;/code&gt;, leave those as they are.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;apiVersion:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;kind:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;metadata:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prometheus-k&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;s-rulefiles&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;namespace:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;monitoring&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;truncated&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;You can also &lt;a href="https://ufile.io/elmz1zwn" rel="noopener noreferrer"&gt;find the link to the edited config map here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, replace the existing Config Map with the new one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl replace -f prometheus-k8s-rulefiles.yaml
configmap/prometheus-k8s-rulefiles-0 replaced
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prometheus will automatically reload the Config Map, and after waiting a bit check on the UI to verify that the alerting rule is created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring port-forward svc/prometheus-k8s 9090
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1a311526dee144b742d_2.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1a311526dee144b742d_2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now run the test job to check if the alert will fire correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create job alert-test --image=busybox -- sh -c "sleep 10; exit 139"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The job will create a pod that will sleep for ten seconds and exit with status 139, thus failing the job and triggering the alert.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1b79795f4759afb54d6_3.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1b79795f4759afb54d6_3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Setting up Slack Webhook&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Since the monitoring stack is now working, it’s a good idea to configure a receiver and see how alert notifications can be made easier for human view.&lt;/p&gt;

&lt;p&gt;Creating a Slack workspace and channel for testing purposes is easy.&lt;/p&gt;

&lt;p&gt;If you do not already have a Slack account you can &lt;a href="https://slack.com/intl/en-mk/get-started#/createnew" rel="noopener noreferrer"&gt;sign up and create one here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once logged in, on the left side, in the &lt;code&gt;Channels&lt;/code&gt; tab click on the plus sign and create a separate channel for alerts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd7f59b30a344fc0339e4_image9.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd7f59b30a344fc0339e4_image9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, to configure a webhook click on &lt;code&gt;Browse Slack&lt;/code&gt;, then &lt;code&gt;Apps&lt;/code&gt;, and in the search bar search for &lt;code&gt;webhooks&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Make sure to select the &lt;code&gt;Incoming Webhooks&lt;/code&gt;, this is extremely important.&lt;/p&gt;

&lt;p&gt;Incoming - it means that data will be sent &lt;code&gt;to&lt;/code&gt; Slack, and not received from it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd84ccb0d4396135b5f04_image4.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd84ccb0d4396135b5f04_image4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click on &lt;code&gt;Add&lt;/code&gt;, you will be redirected to the Slack webhook webpage.&lt;/p&gt;

&lt;p&gt;Just confirm with &lt;code&gt;Add to Slack&lt;/code&gt;, and choose the previously created alert channel. In our case &lt;code&gt;#prometheus_alerts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1c7999dc1df75ce9421_4.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60b5e1c7999dc1df75ce9421_4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that is done on the next page, you will be given the webhook URL.&lt;/p&gt;

&lt;p&gt;That looks something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://hooks.slack.com/services/XXXXXXXXXX/XXXXX/XXXXX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Keep this URL a secret, and treat it like a password!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anyone that gets his / her hands on this URL can send anything to your channel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the bottom, there will be an example with &lt;code&gt;curl&lt;/code&gt; that you can use to send a request and verify if the webhook integration works.&lt;/p&gt;

&lt;p&gt;Going back to your channel, If you see the famous ghost emoji, this means that the webhook configuration is successful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd8d66900e22f5eb0a387_image8.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acd8d66900e22f5eb0a387_image8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: If you received an &lt;strong&gt;SSL certificate problem&lt;/strong&gt; when running the test request, add the &lt;code&gt;-k&lt;/code&gt; option to curl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -k -X POST {rest of the command}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Configuring Alertmanager&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With the Slack channel configured with a webhook, what's left is to integrate it in the Alertmanager configuration.&lt;/p&gt;

&lt;p&gt;In other, non-operator deployments, usually the configuration will be stored inside a Config Map.&lt;/p&gt;

&lt;p&gt;However, deployed through the Prometheus Operator the configuration will be defined inside a &lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/" rel="noopener noreferrer"&gt;Kubernetes secret&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which is much better since its contents are encoded and not left in plain-text format. On another note, some additional steps are required when there is a configuration change.&lt;/p&gt;

&lt;p&gt;You have two options for editing the Alertmanager configuration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can modify the existing secret that Alertmanager uses to store its configuration.&lt;/li&gt;
&lt;li&gt;You can replace that secret with a new one that contains your updated configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first option is a bit tedious process since you will need to decode and encode back the contents every time you want to change some of the configurations.&lt;/p&gt;

&lt;p&gt;With the second option, you can define and store your configuration in plain YAML format. Once there is a new configuration needed, you can generate the Alertmanager secret, directly from that file.&lt;/p&gt;

&lt;p&gt;First, you will need to grab the default configuration that’s deployed with Alertmanager.&lt;/p&gt;

&lt;p&gt;You will use that as a base for further editing.&lt;/p&gt;

&lt;p&gt;You can output the Alertmanager secret with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring get secret alertmanager-main -o yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The secret will look messy at first glance.&lt;/p&gt;

&lt;p&gt;What you are interested in is in the data field, under the &lt;code&gt;alertmanager.yaml&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;That’s the configuration that Alertmanager uses.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For sake of clarity, the other fields will be truncated.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;alertmanager.yaml:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Imdsb&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;JhbCI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;CiAgInJlc&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="err"&gt;sdmVfdGltZW&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="err"&gt;dCI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICI&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;bSIKImluaGliaXRfcnVsZXMiOgotICJlcXVhbCI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;CiAgLSAibmFtZXNwYWNlIgogIC&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;gImFsZXJ&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;bmFtZSIKICAic&lt;/span&gt;&lt;span class="mi"&gt;291&lt;/span&gt;&lt;span class="err"&gt;cmNlX&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="err"&gt;hdGNoIjoKICAgICJzZXZlcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;eSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJjcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;aWNhbCIKICAidGFyZ&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;V&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;X&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="err"&gt;hdGNoX&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;JlIjoKICAgICJzZXZlcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;eSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJ&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;YXJuaW&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;nfGluZm&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;iCi&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;gImVxdWFsIjoKICAtICJuYW&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;lc&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;BhY&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;UiCiAgLSAiYWxlcnRuYW&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;lIgogICJzb&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;VyY&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;VfbWF&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;Y&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;giOgogICAgInNldmVyaXR&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;IjogIndhcm&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;pbmciCiAgInRhcmdldF&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;tYXRjaF&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;yZSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;CiAgICAic&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;V&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;ZXJpdHkiOiAiaW&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;mbyIKInJlY&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;VpdmVycyI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;Ci&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;gIm&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;hbWUiOiAiRGVmYXVsdCIKLSAibmFtZSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJXYXRjaGRvZyIKLSAibmFtZSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJDcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;aWNhbCIKInJvdXRlIjoKICAiZ&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;JvdXBfYnkiOgogIC&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;gIm&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;hbWVzcGFjZSIKICAiZ&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;JvdXBfaW&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="err"&gt;ZXJ&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;YWwiOiAiNW&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;iCiAgImdyb&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;VwX&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;dhaXQiOiAiMzBzIgogICJyZWNlaXZlciI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJEZWZhdWx&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;IgogICJyZXBlYXRfaW&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="err"&gt;ZXJ&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;YWwiOiAiMTJoIgogICJyb&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;V&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;ZXMiOgogIC&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;gIm&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;hdGNoIjoKICAgICAgImFsZXJ&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;bmFtZSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJXYXRjaGRvZyIKICAgICJyZWNlaXZlciI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJXYXRjaGRvZyIKICAtICJtYXRjaCI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;CiAgICAgICJzZXZlcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;eSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJjcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;aWNhbCIKICAgICJyZWNlaXZlciI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ICJDcml&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;aWNhbCI=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this state, you can’t do anything, since the data stored is encoded in base64.&lt;/p&gt;

&lt;p&gt;You can either decode it using online free decoders available on the web.&lt;/p&gt;

&lt;p&gt;Or you can do it through the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo “Imdsb2JhbCI6CiAgInJlc29sdmVfdGltZW91dCI6ICI1bSIKImluaGliaXRfcnVsZXMiOgotICJlcXVhbCI6CiAgLSAibmFtZXNwYWNlIgogIC0gImFsZXJ0bmFtZSIKICAic291cmNlX21hdGNoIjoKICAgICJzZXZlcml0eSI6ICJjcml0aWNhbCIKICAidGFyZ2V0X21hdGNoX3JlIjoKICAgICJzZXZlcml0eSI6ICJ3YXJuaW5nfGluZm8iCi0gImVxdWFsIjoKICAtICJuYW1lc3BhY2UiCiAgLSAiYWxlcnRuYW1lIgogICJzb3VyY2VfbWF0Y2giOgogICAgInNldmVyaXR5IjogIndhcm5pbmciCiAgInRhcmdldF9tYXRjaF9yZSI6CiAgICAic2V2ZXJpdHkiOiAiaW5mbyIKInJlY2VpdmVycyI6Ci0gIm5hbWUiOiAiRGVmYXVsdCIKLSAibmFtZSI6ICJXYXRjaGRvZyIKLSAibmFtZSI6ICJDcml0aWNhbCIKInJvdXRlIjoKICAiZ3JvdXBfYnkiOgogIC0gIm5hbWVzcGFjZSIKICAiZ3JvdXBfaW50ZXJ2YWwiOiAiNW0iCiAgImdyb3VwX3dhaXQiOiAiMzBzIgogICJyZWNlaXZlciI6ICJEZWZhdWx0IgogICJyZXBlYXRfaW50ZXJ2YWwiOiAiMTJoIgogICJyb3V0ZXMiOgogIC0gIm1hdGNoIjoKICAgICAgImFsZXJ0bmFtZSI6ICJXYXRjaGRvZyIKICAgICJyZWNlaXZlciI6ICJXYXRjaGRvZyIKICAtICJtYXRjaCI6CiAgICAgICJzZXZlcml0eSI6ICJjcml0aWNhbCIKICAgICJyZWNlaXZlciI6ICJDcml0aWNhbCI=” | base64 -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will echo the contents and pipe them through base64 with the &lt;code&gt;-d&lt;/code&gt; option for decoding.&lt;/p&gt;

&lt;p&gt;The final, cleaned up configuration will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"global"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolve_timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5m"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"inhibit_rules"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"equal"&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="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"namespace"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alertname"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"critical"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target_match_re"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warning|info"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"equal"&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="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"namespace"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alertname"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target_match_re"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"receivers"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Default"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Watchdog"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Critical"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"route"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"group_by"&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="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"namespace"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"group_interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5m"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"group_wait"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30s"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"receiver"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Default"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repeat_interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12h"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"routes"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alertname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Watchdog"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"receiver"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Watchdog"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"critical"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"receiver"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Critical"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to add the Slack webhook, a couple of edits will be needed to the configuration.&lt;/p&gt;

&lt;p&gt;On the &lt;a href="https://prometheus.io/docs/alerting/latest/configuration/#slack_config" rel="noopener noreferrer"&gt;following link from the official docs&lt;/a&gt;, you can see what options are available.&lt;/p&gt;

&lt;p&gt;Copy the configuration output from above, to a new file named &lt;code&gt;alertmanager.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In that file, you will need to add three separate configs for Alertmanager in order to send alerts on Slack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the Slack webhook URL created previously, and you will add it under the global config as &lt;code&gt;slack_api_url&lt;/code&gt; value.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"global"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolve_timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5m"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slack_api_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://hooks.slack.com/services/xxxxxxxxxxxx/xxxxxxxxxx/x"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;truncated&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;ul&gt;
&lt;li&gt;Under the &lt;code&gt;route&lt;/code&gt; section, replace the default receiver &lt;code&gt;Default&lt;/code&gt; with &lt;code&gt;slack&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"receiver"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"slack"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;truncated&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;ul&gt;
&lt;li&gt;Create a separate receiver for Slack alerts. Under the channel, add the &lt;code&gt;alert channel name you created earlier&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"receivers"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"slack"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"slack_configs"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#prometheus_alerts"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"send_resolved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;summary: {{ .CommonAnnotations.summary }}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;description: {{ .CommonAnnotations.description }}"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;truncated&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;Victory is close!&lt;/p&gt;

&lt;p&gt;For you to be able to add this new configuration as a new secret, you must first delete the existing one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring delete secret alertmanager-main
secret "alertmanager-main" deleted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a new secret with the &lt;code&gt;exact same name&lt;/code&gt;, and using the &lt;code&gt;alertmanager.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl -n monitoring create secret generic alertmanager-main --from-file=alertmanager.yaml
secret/alertmanager-main created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, be patient and wait a bit for Alertmanager to load the new configuration.&lt;/p&gt;

&lt;p&gt;If all is configured properly, you should now see some alerts on your Slack alert channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acfddb7ef92f48fda45dfd_image1.png" 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%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F60acfddb7ef92f48fda45dfd_image1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Alertmanager options are endless, there are a lot of tweaks and fine-tuning that can be done.&lt;/p&gt;

&lt;p&gt;You can set the intervals, group methods, different receivers, alert severity, you can even configure the alerting messages however you like.&lt;/p&gt;

&lt;p&gt;Above is just a sample to showcase the basic configuration options.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Recap&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s recap on what you’ve learned from this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You learned more about Infrastructure Monitoring&lt;/li&gt;
&lt;li&gt;Got familiar with Kubernetes Operators&lt;/li&gt;
&lt;li&gt;Installed kube-prometheus operator as a monitoring solution on your cluster&lt;/li&gt;
&lt;li&gt;You learned how the Prometheus components communicate with each other&lt;/li&gt;
&lt;li&gt;Added your own custom alerting rule&lt;/li&gt;
&lt;li&gt;Configured Alertmanager to send alerts to a Slack channel using webhooks&lt;/li&gt;
&lt;li&gt;From the team at Squadcast, we encourage you to keep on learning!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c51758c58939b30a6fd3d73%2F5e16013f80ad26b00925d758_image--5--1.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>kubernetes</category>
      <category>bestpractices</category>
    </item>
  </channel>
</rss>
