<?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: Ruturaj Kadikar</title>
    <description>The latest articles on DEV Community by Ruturaj Kadikar (@ruturaj_k).</description>
    <link>https://dev.to/ruturaj_k</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%2F405427%2F42c4a367-56c9-40b5-bdc6-b44505da69b3.jpg</url>
      <title>DEV Community: Ruturaj Kadikar</title>
      <link>https://dev.to/ruturaj_k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ruturaj_k"/>
    <language>en</language>
    <item>
      <title>Metrics at a Glance for Production Clusters</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Mon, 31 Mar 2025 14:18:50 +0000</pubDate>
      <link>https://dev.to/infracloud/metrics-at-a-glance-for-production-clusters-5e35</link>
      <guid>https://dev.to/infracloud/metrics-at-a-glance-for-production-clusters-5e35</guid>
      <description>&lt;p&gt;Keeping a close eye on your production clusters is not just good practice—it’s essential for survival. Whether you’re managing applications at scale or ensuring robust service delivery, understanding the vital signs of your clusters through metrics is like having a dashboard in a race car, giving you real-time insights and foresight into performance bottlenecks, resource usage and the operational health of your car.&lt;/p&gt;

&lt;p&gt;However, too much happens in any cluster. There are so many metrics to track that the huge observability data you may collect could become another obstacle to viewing what is actually happening with your cluster. That’s why you should only collect the important metrics that offer you a complete picture of your cluster’s health without overwhelming you.&lt;/p&gt;

&lt;p&gt;In this blog post, we will cut through the complexity and spotlight the essential metrics you need on your radar to quickly detect and address issues as they arise. From CPU usage to network throughput, we’ll break down each metric, show you how to monitor them effectively and provide the queries that get you the data you need. Before we dive into the specifics of which metrics to monitor, let's understand the foundational monitoring principles that guide our approach. We'll explore the RED and USE methods along with the Four Golden Signals, providing a robust framework for what to measure and why it matters in maintaining the health of your production clusters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Principles
&lt;/h2&gt;

&lt;p&gt;Effective monitoring is the cornerstone of maintaining the health and performance of your production clusters. It helps you catch issues early, optimize resource usage, and ensure that your systems are running smoothly. In this section, we introduce two essential monitoring frameworks — USE and RED — and the Four Golden Signals. These principles provide a structured approach to monitoring, making it easier to interpret vast amounts of data and identify critical performance metrics. By understanding and applying these principles, you can transform raw data into actionable insights that keep your systems in top shape.&lt;/p&gt;

&lt;h3&gt;
  
  
  RED and USE method
&lt;/h3&gt;

&lt;p&gt;In modern systems, keeping track of numerous metrics can be overwhelming, especially when troubleshooting or simply checking for issues. To make this easier, you can use two helpful acronyms: &lt;a href="https://orangematter.solarwinds.com/2017/10/05/monitoring-and-observability-with-use-and-red/" rel="noopener noreferrer"&gt;USE and RED&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.brendangregg.com/usemethod.html" rel="noopener noreferrer"&gt;The USE Method (Utilization, Saturation, Errors) was introduced by Brendan Gregg,&lt;/a&gt; a renowned performance engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilization: Measures how busy your resources are.&lt;/li&gt;
&lt;li&gt;Saturation: Shows how much backlog or congestion there is.&lt;/li&gt;
&lt;li&gt;Errors: Counts the number of error events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://grafana.com/blog/2018/08/02/the-red-method-how-to-instrument-your-services" rel="noopener noreferrer"&gt;The RED Method was introduced by Tom Wilkie&lt;/a&gt;. Drawing from his experiences at Google, Wilkie developed this methodology to focus on three key metrics for monitoring microservices (Rate, Errors, and Duration):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate: Measures the request throughput.&lt;/li&gt;
&lt;li&gt;Errors: Tracks the error rates.&lt;/li&gt;
&lt;li&gt;Duration: Measures how long requests take to be processed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The USE method focuses on resource performance from an internal perspective, while the RED method looks at request performance from an external, workload-focused perspective. Together, they give you a comprehensive view of system health by covering both resource usage and workload behavior. By using these standard performance metrics, USE and RED provide a solid foundation for monitoring and diagnosing issues in complex systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Four Golden Signals
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://sre.google/sre-book/monitoring-distributed-systems/" rel="noopener noreferrer"&gt;Four Golden Signals&lt;/a&gt;&lt;/strong&gt; — &lt;strong&gt;Latency&lt;/strong&gt;, &lt;strong&gt;Traffic&lt;/strong&gt;, &lt;strong&gt;Errors&lt;/strong&gt;, and &lt;strong&gt;Saturation&lt;/strong&gt; — are foundational metrics introduced in Google's Site Reliability Engineering (SRE) practices to monitor system performance and reliability. According to this method. dashboards should address all the fundamental questions about your service. These signals are essential for understanding system performance and should be prioritized when selecting metrics to monitor.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency: Refers to the time taken to handle a request, distinguishing between successful and failed requests.&lt;/li&gt;
&lt;li&gt;Traffic: Measures the demand placed on the system, typically quantified by metrics like HTTP requests per second or network I/O rate.&lt;/li&gt;
&lt;li&gt;Errors: Represents the rate of failed requests, including explicit errors like HTTP 500s and implicit errors like incorrect content responses.&lt;/li&gt;
&lt;li&gt;Saturation: Indicates how "full" the service is, emphasizing the most constrained resources and predicting impending saturation for proactive maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7q9d1oib1ruqggn43dh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7q9d1oib1ruqggn43dh.png" alt="Four Golden Signals" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By monitoring these four golden signals and promptly alerting administrators or support engineers when issues arise, your cluster will benefit from comprehensive monitoring coverage, ensuring reliability and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Four Golden Signals for Comprehensive Monitoring
&lt;/h2&gt;

&lt;p&gt;If you're managing a production Kubernetes cluster, you know the importance of staying on top of your monitoring game. We’re here to simplify your monitoring approach by integrating the RED and USE methods with Google's Four Golden Signals, enabling comprehensive monitoring from a single dashboard. This approach allows you to swiftly spot and address issues, ensuring your cluster operates smoothly without the hassle of jumping between multiple dashboards. To get started, you can download the &lt;a href="https://grafana.com/grafana/dashboards/21073-monitoring-golden-signals/" rel="noopener noreferrer"&gt;Monitoring Golden Signals for Kubernetes Grafana dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c3jqs1hxv5wapcu28ko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c3jqs1hxv5wapcu28ko.png" alt="Monitoring Golden Signals for Kubernetes Grafana dashboard" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s jump into each golden signal to understand what metrics should be monitored to track them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic: What is it and how to monitor it?
&lt;/h3&gt;

&lt;p&gt;If we consider Kubernetes a city's road system, then pods will be cars, nodes will be streets, and services will be traffic lights that manage the flow. In this case, monitoring in Kubernetes is like using traffic cameras and sensors at crossroads to keep everything moving smoothly and avoid traffic jams.&lt;/p&gt;

&lt;p&gt;Network I/O is like the main roads that handle cars coming into and going out of the city. If these roads are too busy, it slows everything down. The API server is like a Regional Transport Office (RTO), regulating and overseeing all operations within the cluster, much like traffic and vehicle management in a region. Monitoring traffic to external services such as databases is also important, similar to watching vehicles travel to other cities. You can use tools like the &lt;a href="https://www.infracloud.io/blogs/monitoring-endpoints-kubernetes-blackbox-exporter/" rel="noopener noreferrer"&gt;blackbox exporter to keep an eye on traffic leaving Kubernetes&lt;/a&gt;. This highlights the importance of pinpointing key areas for monitoring traffic flow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff30aefts9o0it4pyca7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff30aefts9o0it4pyca7v.png" alt="How to monitor traffic" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below, we outline the primary and general metrics for monitoring the traffic.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;br&gt;(Dashboard Title)&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Why Monitor this Metric&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ingress Traffic (Istio)&lt;/td&gt;
&lt;td&gt;istio_requests_total&lt;/td&gt;
&lt;td&gt;Tracks the total number of requests handled by Istio, essential for understanding ingress controller load and overall health.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Traffic&lt;/td&gt;
&lt;td&gt;apiserver_request_total&lt;/td&gt;
&lt;td&gt;Measures the number of API server requests, which helps in monitoring control plane load and identifying potential bottlenecks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Traffic&lt;/td&gt;
&lt;td&gt;workqueue_adds_total&lt;/td&gt;
&lt;td&gt;Indicates the total number of items added to work queues, helping identify workload spikes and manage resource allocation effectively.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Traffic&lt;/td&gt;
&lt;td&gt;node_network_receive_bytes_total&lt;br&gt;node_network_transmit_bytes_total&lt;/td&gt;
&lt;td&gt;Monitors data received/transmitted by nodes, which is crucial for identifying and addressing network capacity issues.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Traffic&lt;/td&gt;
&lt;td&gt;node_network_receive_packets_total&lt;br&gt;node_network_transmit_packets_total&lt;/td&gt;
&lt;td&gt;Monitors the number of packets received/transmitted, important for analyzing network traffic, identifying issues, and maintaining robust network communication.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workload Traffic&lt;/td&gt;
&lt;td&gt;container_network_receive_bytes_total&lt;br&gt;container_network_transmit_bytes_total&lt;/td&gt;
&lt;td&gt;Vital for monitoring the amount of network traffic received/transmitted by containers, ensuring proper traffic handling and performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Operations&lt;/td&gt;
&lt;td&gt;storage_operation_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Provides insights into storage operation performance, helping diagnose and address slow disk access issues.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CoreDNS Requests/s&lt;/td&gt;
&lt;td&gt;coredns_dns_requests_total&lt;/td&gt;
&lt;td&gt;Monitors the number of DNS queries handled by CoreDNS, ensuring reliable service discovery and network performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Latency: What is it and how to monitor it?
&lt;/h3&gt;

&lt;p&gt;To understand the latency in Kubernetes, let's take the previous example of traffic system. Latency in Kubernetes is like delays in a city’s traffic system, where slowdowns at various points affect overall efficiency. If a major road is under construction or blocked due to an accident (slow data processing), cars must take detours, increasing travel time. Similarly, when a microservice is overloaded, requests pile up, causing system-wide slowdowns.&lt;/p&gt;

&lt;p&gt;Traffic lights that take too long to change (rate-limited APIs or overloaded queues) create long waiting lines, much like API call delays that hold up processing. Similarly, pod startup delays are like traffic signals malfunctioning cars remain idle, and congestion builds up, just as new pods taking too long to initialize slow down request handling.&lt;/p&gt;

&lt;p&gt;During rush hour congestion, roads get overwhelmed, making travel slower for everyone. In Kubernetes, when resources like CPU and memory are exhausted, requests are delayed, affecting performance. Likewise, a single-lane road with no passing option (sequential processing) forces cars to crawl behind slow-moving vehicles, just as inefficient sequential request handling slows down application performance.&lt;/p&gt;

&lt;p&gt;Just as city planners use traffic monitoring and smart infrastructure to optimize flow, engineers must track key latency metrics to prevent bottlenecks in Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F578qwxeu9t4jiw8illwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F578qwxeu9t4jiw8illwg.png" alt="How to monitor latency" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component (Dashboard Title)&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Why Monitor This Metric&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pod Start Duration&lt;/td&gt;
&lt;td&gt;kubelet_pod_start_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Monitors time taken for pods to start, crucial for optimizing scaling and recovery processes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pod Startup Latency&lt;/td&gt;
&lt;td&gt;kubelet_pod_worker_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Tracks duration of pod operations, important for assessing pod management efficiency.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ETCD Cache Duration 99th Quantile&lt;/td&gt;
&lt;td&gt;etcd_request_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Essential for monitoring ETCD request processing latency, impacts overall cluster performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Request Duration 99th Quantile&lt;/td&gt;
&lt;td&gt;apiserver_request_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Important for understanding API server response times, indicates control plane health.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Work Queue Latency&lt;/td&gt;
&lt;td&gt;workqueue_queue_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Measures delays in API server work queues, vital for spotting potential processing issues.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Work Queue Depth&lt;/td&gt;
&lt;td&gt;workqueue_depth&lt;/td&gt;
&lt;td&gt;Provides insight into API server queue load, critical for preventing system overloads.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CoreDNS Request Duration&lt;/td&gt;
&lt;td&gt;coredns_dns_request_duration_seconds_bucket&lt;/td&gt;
&lt;td&gt;Tracks CoreDNS DNS request processing times, key for efficient network resolution.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Errors: What is it and how to monitor it?
&lt;/h3&gt;

&lt;p&gt;Again, continuing our analogy, let's consider a Kubernetes cluster like a city’s road system. Everything needs to move smoothly for the city to function well. But what happens when things go wrong?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CoreDNS crashes: It’s like traffic signals failing. Without proper directions, cars (data) can’t find their way, leading to confusion and delays.&lt;/li&gt;
&lt;li&gt;API Server goes down: This is like losing the central traffic control center. The entire system becomes unresponsive, and nothing moves.&lt;/li&gt;
&lt;li&gt;Pod failures: These are like car breakdowns. A few stalled cars won’t stop the whole city, but they slow down traffic in specific lanes (services).&lt;/li&gt;
&lt;li&gt;Node issues (like DiskPressure): Imagine a major road being closed. Cars (pods) have to reroute, leading to congestion and bottlenecks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just as traffic disruptions cause delays and frustration, Kubernetes failures impact SLAs, SLOs, and user experience. That’s why monitoring errors is like a real-time traffic control system. It detects problems early and helps keep everything running smoothly. The following metrics will help monitor the errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzv596bfaesyv4nmmqi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzv596bfaesyv4nmmqi4.png" alt="How to monitor errors" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component (Dashboard Title)&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Why Monitor this Metric&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CoreDNS&lt;/td&gt;
&lt;td&gt;coredns_cache_misses_total&lt;/td&gt;
&lt;td&gt;Tracks cache misses in CoreDNS, important for identifying DNS resolution issues affecting cluster connectivity and performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Server Errors&lt;/td&gt;
&lt;td&gt;apiserver_request_total&lt;/td&gt;
&lt;td&gt;Monitors API server request errors, crucial for detecting and diagnosing failures in handling cluster management tasks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nodes&lt;/td&gt;
&lt;td&gt;kube_node_spec_unschedulable&lt;/td&gt;
&lt;td&gt;Counts nodes that are unschedulable, essential for understanding cluster capacity and scheduling issues.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nodes&lt;/td&gt;
&lt;td&gt;kube_node_status_condition&lt;/td&gt;
&lt;td&gt;Tracks node conditions like 'OutOfDisk', 'DiskPressure', 'MemoryPressure', important for preemptive system health alerts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubelet&lt;/td&gt;
&lt;td&gt;kubelet_runtime_operations_errors_total&lt;/td&gt;
&lt;td&gt;Measures error rates in kubelet operations, key for maintaining node and pod health.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workloads&lt;/td&gt;
&lt;td&gt;kube_pod_status_phase&lt;/td&gt;
&lt;td&gt;Monitors pods in failed states, critical for identifying failed workloads and ensuring reliability.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;node_network_receive_errs_total, node_network_transmit_errs_total&lt;/td&gt;
&lt;td&gt;Monitors network errors in data transmission and reception, vital for maintaining robust network communication.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Saturation: What is it and how to monitor it?
&lt;/h3&gt;

&lt;p&gt;To explain saturation, we will take you to the example of the city traffic system again. CPU and memory utilization are akin to monitoring the flow of vehicles — too much traffic causes congestion, slowing down the city. Node resource exhaustion is similar to key intersections getting overwhelmed, which can halt traffic across the city. Network capacity matches the width and condition of roads; inadequate capacity leads to bottlenecks. Monitoring the top ten nodes and pods with the highest resource utilization is like tracking the busiest areas in the city to prevent and manage traffic jams more effectively. This approach ensures smooth operation and prevents system slowdowns.&lt;/p&gt;

&lt;p&gt;The following metrics help to quickly identify the possible slowdowns in Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rrk8l0p0w67hbbzdff0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rrk8l0p0w67hbbzdff0.png" alt="How to monitor saturation" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component (Dashboard Title)&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Importance of Monitoring that Metric&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cluster Memory Utilization&lt;/td&gt;
&lt;td&gt;node_memory_MemFree_bytes, node_memory_MemTotal_bytes, node_memory_Buffers_bytes, node_memory_Cached_bytes&lt;/td&gt;
&lt;td&gt;Tracks memory usage metrics to prevent saturation and ensure resource availability.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cluster CPU Utilization&lt;/td&gt;
&lt;td&gt;node_cpu_seconds_total&lt;/td&gt;
&lt;td&gt;Monitors CPU usage to prevent overload and maintain performance efficiency.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Count&lt;/td&gt;
&lt;td&gt;kube_node_labels&lt;/td&gt;
&lt;td&gt;Counts the number of nodes, essential for scaling and resource allocation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PVCs&lt;/td&gt;
&lt;td&gt;kube_persistentvolumeclaim_info&lt;/td&gt;
&lt;td&gt;Tracks persistent volume claims, important for storage resource management.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Parameters&lt;/td&gt;
&lt;td&gt;node_filefd_maximum&lt;br&gt;node_filefd_allocated&lt;/td&gt;
&lt;td&gt;Tracks maximum file descriptors, prevents resource exhaustion.&lt;br&gt;Tracks allocated file descriptors, prevents resource exhaustion.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Parameters&lt;/td&gt;
&lt;td&gt;node_sockstat_sockets_used&lt;/td&gt;
&lt;td&gt;Monitors sockets in use, crucial for system stability.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node Parameters&lt;/td&gt;
&lt;td&gt;node_nf_conntrack_entries&lt;br&gt;node_nf_conntrack_entries_limit&lt;/td&gt;
&lt;td&gt;Tracks active network connections, ensures capacity isn't exceeded.&lt;br&gt;Monitors conntrack entries limit, prevents network tracking overload.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note: This dashboard is designed specifically for infrastructure monitoring. To cover application insights, you need to create similar dashboards from application metrics, assuming the relevant metrics are available. Additionally, you can generate metrics from logs as needed and incorporate them into these dashboards to achieve a unified view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By meticulously applying these Four Golden Signals in our monitoring strategy, we ensure a proactive approach to infrastructure management. This not only helps in quick problem resolution but also aids in efficient resource utilization, ultimately enhancing the performance and stability of your Kubernetes cluster. With this comprehensive view provided by this single-dashboard approach, Kubernetes administrators and SREs can effortlessly manage cluster health, allowing them to focus on strategic improvements and innovation. No more navigating through complex monitoring setups—everything you need is now in one place, streamlined for efficiency and effectiveness.&lt;/p&gt;

&lt;p&gt;I hope you found this post informative and engaging. I’d love to hear your thoughts on this post; let’s connect and start a conversation on &lt;a href="https://www.linkedin.com/in/ruturaj-kadikar/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>monitoring</category>
      <category>sre</category>
      <category>devops</category>
    </item>
    <item>
      <title>Prometheus vs CloudWatch for Cloud Native Applications (Updated in 2024)</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Thu, 10 Oct 2024 06:19:23 +0000</pubDate>
      <link>https://dev.to/infracloud/prometheus-vs-cloudwatch-for-cloud-native-applications-updated-in-2024-4na3</link>
      <guid>https://dev.to/infracloud/prometheus-vs-cloudwatch-for-cloud-native-applications-updated-in-2024-4na3</guid>
      <description>&lt;p&gt;Many companies are &lt;a href="https://www.infracloud.io/kubernetes-consulting-partner/" rel="noopener noreferrer"&gt;moving to Kubernetes&lt;/a&gt; as the platform of choice for running software workloads. When an organization using VMs in AWS earlier decides to move to Kubernetes (Either EKS or self-managed in AWS), one of the questions that come up is whether one should continue to use Amazon CloudWatch or switch to some other tool like Prometheus? Many organizations think managing Prometheus can be challenging and bring more overheads. Recently, AWS launched a managed Prometheus service for such organizations. While CloudWatch vs Prometheus is not an exact apple to apple comparison, there are reasons to explore this and choose tooling that is built for the future. This post will explore various aspects and pros and cons, including costs of all three options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why compare Prometheus and CloudWatch?
&lt;/h2&gt;

&lt;p&gt;Prometheus and Amazon CloudWatch are very different in the problem they solve, and a 1-1 comparison may seem unfair, but as you start &lt;a href="https://www.infracloud.io/cloud-native-consulting/" rel="noopener noreferrer"&gt;moving to cloud-native stack&lt;/a&gt;, Prometheus starts popping up in conversations and for many right reasons. Before we start comparing the two technologies, let’s do a quick high-level overview of both.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS CloudWatch overview
&lt;/h2&gt;

&lt;p&gt;AWS CloudWatch is a native service within the suite of AWS services. It helps collect metrics, logs, and events, enabling users to visualize data through customizable dashboards, set alarms for operational thresholds, and respond to system-wide performance changes. In very simplistic terms, CloudWatch acts as a metrics sink for AWS services to publish metrics . These metrics are then used to configure alarms and statistics. The services which publish metrics to CloudWatch are listed in the &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html" rel="noopener noreferrer"&gt;documentation here&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhgrpwi301zmcvn8ev3w.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhgrpwi301zmcvn8ev3w.png" alt="AWS CloudWatch overview" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Working of AWS CloudWatch
&lt;/h3&gt;

&lt;p&gt;An application or service publishes metrics (a set of data points ordered by time) in a namespace (a construct to provide isolation of metrics, for e.g., &lt;em&gt;AWS/EC2&lt;/em&gt; or &lt;em&gt;AWS/APIGateway&lt;/em&gt;) with dimensions (an identity key/value pair used to filter and lookup metrics). Statistics are the aggregations performed over the reported unit (value) of the metrics over a period of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Prometheus?
&lt;/h2&gt;

&lt;p&gt;Prometheus is an application used for &lt;a href="https://www.infracloud.io/blogs/prometheus-architecture-metrics-use-cases/" rel="noopener noreferrer"&gt;monitoring and alerting&lt;/a&gt;, along with &lt;a href="https://www.infracloud.io/grafana-consulting/" rel="noopener noreferrer"&gt;Grafana for dashboarding&lt;/a&gt;. It’s a popular and actively CNCF supported open source project, and it enjoys a lot of community support and integrations with other applications in the monitoring ecosystem.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1kfgtn041ayxy7eapjv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1kfgtn041ayxy7eapjv.png" alt="Prometheus architecture overview" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Working of Prometheus
&lt;/h3&gt;

&lt;p&gt;An application exposes metrics (or uses the exporter to do so) at a specific endpoint scraped by the Prometheus server (this also acts as a sink for storing metric time-series data). Prometheus works on a pull-based mechanism where it scrapes metrics exposed by applications at a specific endpoint. It also supports a Push gateway component which is used to allow shortlived jobs such as cron and batch jobs to export their metrics. Prometheus exporters provide support for applications in exposing metrics in the Prometheus format. An Alert manager component provides support for managing alerts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon Managed Service for Prometheus (AMP)
&lt;/h2&gt;

&lt;p&gt;Amazon Managed Service for Prometheus, is a fully managed, scalable, and highly available service that enables organizations to monitor their containerized applications. Built on the open-source Prometheus project, it allows users to ingest, store, query, and visualize time series metrics from various sources like Kubernetes clusters. AWS Managed Prometheus integrates seamlessly with AWS services like Amazon EKS, ECS, and Fargate, making it ideal for cloud-native environments. It helps users to observe their distributed applications without needing to handle the complexity of scaling or maintaining their Prometheus infrastructure. AWS also offers secure integration with IAM for fine-grained access control, making it easier to manage permissions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working of AMP
&lt;/h3&gt;

&lt;p&gt;AWS Managed Prometheus works by ingesting metrics from Kubernetes clusters and other data sources through the Prometheus Remote Write API. AMP does not natively scrape operational metrics from containerized workloads in a Kubernetes cluster. Instead, users need to deploy and manage a standard Prometheus server or use an &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry agent&lt;/a&gt;, such as the &lt;a href="https://aws-otel.github.io/docs/getting-started/collector" rel="noopener noreferrer"&gt;AWS Distro for OpenTelemetry Collector&lt;/a&gt;, within their cluster to handle the metric scraping. Once ingested, the metrics are stored in a scalable, multi-tenant, and highly available time-series database. Users can query the stored metrics using PromQL, Prometheus' powerful query language, to analyze application performance and resource utilization. AWS handles all the infrastructure management tasks, such as scaling, patching, and backup. Users can visualize the metrics using Amazon Managed Grafana or other compatible dashboards.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7oeji1y9x19y7vxz9fh.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7oeji1y9x19y7vxz9fh.png" alt="Working of AMP" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s compare CloudWatch vs Prometheus
&lt;/h2&gt;

&lt;p&gt;We will compare the two technologies primarily aimed at Kubernetes based cloud native platforms and explore which one fits the use cases better. One of the goals is also to find out the cost for each tool keeping the reference of a mid-sized cluster. When we say “cost” here, it is not just the $ value – there are multiple aspects to it. We will include a comparison table to give you a brief idea of cost incurred by all three tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric support in CloudWatch vs Prometheus
&lt;/h3&gt;

&lt;p&gt;You can have core metric or custom metric at a standard resolution (granularity of a minute) or high resolution (granularity of a second). Specifically, for pod autoscaling to work, you will have to write an adapter and publish the metrics to the &lt;a href="https://www.infracloud.io/kubernetes-school/basics-of-kubernetes/how-does-kube-api-server-work/" rel="noopener noreferrer"&gt;Kubernetes API server&lt;/a&gt;. From integration to other tools such as PagerDuty, etc., you will have to integrate using AWS SQS or similar tooling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.infracloud.io/prometheus-monitoring-support/" rel="noopener noreferrer"&gt;Prometheus supports&lt;/a&gt; scraping Kubernetes metrics natively and is well integrated with the API server for autoscaling. It also comes with support for custom metrics, and the most commonly used use cases will have a community developed adapter ready to use.&lt;/p&gt;

&lt;p&gt;One of the areas where CloudWatch still needs to be used in combination with Prometheus is for managed services such as RDS. The metrics from RDS are directly exported to CloudWatch, and from there, you can use a Prometheus exporter to push metrics to Prometheus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alerting in Prometheus vs CloudWatch
&lt;/h3&gt;

&lt;p&gt;Alerting in Prometheus and Amazon CloudWatch takes different approaches suited to their ecosystems. Prometheus uses Alertmanager to handle alerts based on custom PromQL queries, offering flexibility in defining rules and integrating with various notification channels like Slack and email. This setup is ideal for complex, dynamic environments. Note that AMP will also have similar approach but by using Alertmanager from Amazon managed Grafana service. CloudWatch, on the other hand, employs CloudWatch Alarms to monitor metrics and logs, triggering notifications or automated actions when thresholds are met. It integrates with AWS services and supports notifications through Amazon SNS and automated responses via AWS Lambda. While CloudWatch provides a seamless experience within AWS, Prometheus excels with its granular, flexible alerting capabilities that are suitable for diverse or multi-cloud setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Querying and Dashboarding in Prometheus vs CloudWatch
&lt;/h3&gt;

&lt;p&gt;Querying and Dashboarding is one area where Prometheus – with &lt;a href="https://www.infracloud.io/grafana-consulting/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt; as the dashboarding tool and &lt;a href="https://www.infracloud.io/blogs/promql-prometheus-guide/" rel="noopener noreferrer"&gt;Prometheus query language&lt;/a&gt; wins hands down. With dashboards that are beautifully backed by a query language that is rich, the dashboarding in Prometheus world is far better. Also, CloudWatch and Amazon managed Grafana do charge for each additional dashboard, and in a self-managed Prometheus setup, there is no reason not to create a dashboard if you need to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big question: Cost! in CloudWatch vs Prometheus
&lt;/h2&gt;

&lt;p&gt;One of the final areas that we want to discuss is the cost comparison of using all the three tools that we are discussing in post. The cost here is not just the dollar value paid for infrastructure but also the engineering and skill cost of the engineering bandwidth. There are also other aspects, such as cloud lock-in, multi-cloud deployments, hybrid deployments, etc. Let’s start with pure data-driven costs and then dive into other areas. Please note that the cost comparison is done based on the pricing of CloudWatch and Prometheus in September 2024 and should be confirmed before making a business decision&lt;/p&gt;

&lt;p&gt;When evaluating Prometheus and CloudWatch for Kubernetes monitoring, it's helpful to start with a few assumptions based on a medium-sized organization operating in a single environment. For this comparison, we’ve used data from a 100-node Amazon EKS (Elastic Kubernetes Service) cluster with over 4,000 running pods.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  CloudWatch
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Amazon CloudWatch Agents are deployed as DaemonSets on all nodes in the cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics collection&lt;/strong&gt;: These agents collect cluster metrics and export them to the ContainerInsights namespace in CloudWatch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention period&lt;/strong&gt;: &lt;a href="https://aws.amazon.com/blogs/aws/amazon-cloudwatch-update-extended-metrics-retention-user-interface-update/" rel="noopener noreferrer"&gt;CloudWatch retains these metrics for approximately 63 days with a scraping interval of 5 minutes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric count&lt;/strong&gt;: For our EKS cluster, we recorded around 19,000 metrics across various namespaces, such as ContainerInsights, EC2, AutoScaling Group, and EBS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Prometheus and Thanos
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Prometheus is deployed on the EKS cluster alongside Thanos for long-term storage, along with all other components, including node exporters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention period&lt;/strong&gt;: Prometheus is configured with a 3-day in-memory retention period for metrics. Thanos then stores these metrics in an Amazon S3 bucket for long-term storage (for our comparison, it will be for 2 months).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We compared the two metrics monitoring tools with a reference setup of 100 nodes and a storage duration of 60 days (2 months). Below is a summary of key parameters used for this comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Parameter&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;AMP&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Number of Nodes
   &lt;/td&gt;
   &lt;td&gt;100
   &lt;/td&gt;
   &lt;td&gt;100
   &lt;/td&gt;
   &lt;td&gt;100
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Time Series Definition
   &lt;/td&gt;
   &lt;td&gt;Metrics x labels
   &lt;/td&gt;
   &lt;td&gt;Namespace x Metrics x dimension
   &lt;/td&gt;
   &lt;td&gt;Metrics x labels
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Time Series
   &lt;/td&gt;
   &lt;td&gt;~1.5 M
   &lt;/td&gt;
   &lt;td&gt;~19 K
   &lt;/td&gt;
   &lt;td&gt;~1.5 M
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Metrics Storage Duration
   &lt;/td&gt;
   &lt;td&gt;60 days
   &lt;/td&gt;
   &lt;td&gt;60 days
   &lt;/td&gt;
   &lt;td&gt;60 days
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Scrape Duration
   &lt;/td&gt;
   &lt;td&gt;20 s
   &lt;/td&gt;
   &lt;td&gt;5 min
   &lt;/td&gt;
   &lt;td&gt;20 s
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since CloudWatch is a managed service, there is minimal overhead in managing resources, aside from the CloudWatch Agent DaemonSets. In contrast, using Prometheus requires managing the Prometheus and Thanos StatefulSets, as well as additional components like Node Exporter DaemonSets for scraping cluster metrics. The table below highlights the major components to consider for resource management.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Resource&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;AMP&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Agents (DaemonSets)
   &lt;/td&gt;
   &lt;td&gt;1 GiB x 100 Nodes
   &lt;/td&gt;
   &lt;td&gt;512 MiB x 100 Nodes
   &lt;/td&gt;
   &lt;td&gt;1 GiB x 100 Nodes
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Prometheus Pod
   &lt;/td&gt;
   &lt;td&gt;~25 GiB
   &lt;/td&gt;
   &lt;td rowspan="6"&gt;Not Applicable
   &lt;/td&gt;
   &lt;td rowspan="6"&gt;Not Applicable
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Retention Period
   &lt;/td&gt;
   &lt;td&gt;3 days
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Prometheus EBS Storage
   &lt;/td&gt;
   &lt;td&gt;~40 GiB
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Thanos Pod
   &lt;/td&gt;
   &lt;td&gt;~20 GiB
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Thanos EBS Storage
   &lt;/td&gt;
   &lt;td&gt;~40 GiB
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;S3 Storage
   &lt;/td&gt;
   &lt;td&gt;~1 TB (500 MB x 2months)
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Based on these resources, we conducted a cost analysis. For CloudWatch, the cost calculation is straightforward and can be directly estimated using the &lt;a href="https://calculator.aws" rel="noopener noreferrer"&gt;AWS Cost Calculator&lt;/a&gt; by inputting the number of metrics. We included the cost of the agents, assuming a t4g.nano instance type, which offers the lowest cost for provisioning 512 MiB of memory. For Prometheus and Thanos, we used r6g.2xlarge instances to accommodate both StatefulSets. For node exporters, we assumed t4g.nano instances, which provide the lowest cost for provisioning 1 GiB of memory. EBS and S3 storage costs were calculated according to the resource usage mentioned in the table above. The following table presents a cost comparison of the two methods under discussion.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Cost Component&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;AMP&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Agents
   &lt;/td&gt;
   &lt;td&gt;$613.2 (Considering t4g.micro instance)
   &lt;/td&gt;
   &lt;td&gt;$306.6 (Considering t4g.nano instance)
   &lt;/td&gt;
   &lt;td&gt;$613.2 (Considering t4g.micro instance)
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;AWS Calculator Estimate
   &lt;/td&gt;
   &lt;td&gt;Not Applicable
   &lt;/td&gt;
   &lt;td&gt;$7,800
   &lt;/td&gt;
   &lt;td&gt;$14,227.86
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Instance (r6g.2xlarge for 2 monthsx 2 instances)
   &lt;/td&gt;
   &lt;td&gt;$1,177.34
   &lt;/td&gt;
   &lt;td rowspan="3"&gt;Not Applicable
   &lt;/td&gt;
   &lt;td rowspan="3"&gt;Not Applicable
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;S3
   &lt;/td&gt;
   &lt;td&gt;$47.1
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;EBS
   &lt;/td&gt;
   &lt;td&gt;$59.6
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Total Cost
   &lt;/td&gt;
   &lt;td&gt;$1,897.24
   &lt;/td&gt;
   &lt;td&gt;$8,106.60
   &lt;/td&gt;
   &lt;td&gt;$14,841.06
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When considering monitoring tools, it's crucial to factor in the cost of dashboards and visualizations, as they play a significant role in monitoring effectiveness. The cost can vary based on how often metrics are fetched and displayed. When considering the cost of monitoring and visualization, it's important to account for the number of requests made to fetch metrics each month. Let’s break this down with some assumptions. Suppose you have 100 dashboards, each used by 100 users, and each dashboard refreshes every minute. This means each dashboard generates 60 requests per hour, resulting in 1,440 requests per day. Over a month, this totals around 432 million requests (60 requests/hour × 24 hours/day × 30 days × 100 dashboards × 100 users).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Parameters&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;AMP&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Monthly requests
   &lt;/td&gt;
   &lt;td colspan="3"&gt;432 million requests
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Grafana
   &lt;/td&gt;
   &lt;td&gt;T3.medium (Self-managed), $30.37
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
   &lt;td&gt;Considering AWS managed Grafana
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;EBS (Volume for Grafana)
   &lt;/td&gt;
   &lt;td&gt;$7.45
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;S3
   &lt;/td&gt;
   &lt;td&gt;$2,160 (PUT, COPY, POST, LIST requests to S3 Standard)
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;AWS Calculator Estimate
   &lt;/td&gt;
   &lt;td&gt;NA
   &lt;/td&gt;
   &lt;td&gt;432M (GetMetricData: Number of metrics requested) \
291 (100 dashboards)
   &lt;/td&gt;
   &lt;td&gt;$509 (1 Admin and 100 viewers)
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Total
   &lt;/td&gt;
   &lt;td&gt;$2197.82
   &lt;/td&gt;
   &lt;td&gt;$4611
   &lt;/td&gt;
   &lt;td&gt;$509
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Total (2months)
   &lt;/td&gt;
   &lt;td&gt;$4395.64
   &lt;/td&gt;
   &lt;td&gt;$9222
   &lt;/td&gt;
   &lt;td&gt;$1,018
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Total with Metrics (from previous table)
   &lt;/td&gt;
   &lt;td&gt;$6292.88
   &lt;/td&gt;
   &lt;td&gt;$17,328.6
   &lt;/td&gt;
   &lt;td&gt;$15,859.06
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Monthly Cost
   &lt;/td&gt;
   &lt;td&gt;$3,146.44
   &lt;/td&gt;
   &lt;td&gt;$8,664.3
   &lt;/td&gt;
   &lt;td&gt;$7,929.53
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzif5n9nhekcy64fjcfti.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzif5n9nhekcy64fjcfti.png" alt="Self-Managed-Prometheus pricing" width="800" height="303"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvxff4pfud0jnvlb5l9w.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvxff4pfud0jnvlb5l9w.png" alt="AWS CloudWatch pricing" width="800" height="229"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2p2babzsv6iuz4w65y4u.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2p2babzsv6iuz4w65y4u.png" alt="AWS managed Prometheus pricing" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These pricing estimates are provided as json &lt;a href="https://github.com/infracloudio/cloudwatch-prometheus-blog" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To be fair, this is, again, not an exact apple-to-apple comparison. The cost of engineering effort and skills to run self-managed Prometheus has to be accounted for. Also, the cost of instances considered here is for on-demand and might vary for reserved or spot instances, which have lower costs – and that is something we are not taking into account. Overall, it is clear from the calculation that the cost of running a self-managed Prometheus stack gets cheaper beyond a certain threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pricing estimates&lt;/strong&gt;: The prices mentioned in this blog are calculated using the AWS Pricing Calculator and are accurate as of the time of writing. However, AWS pricing may change over time, so it's recommended to verify current costs through the AWS Pricing Page or directly in the AWS Pricing Calculator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Discounts and offers&lt;/strong&gt;: AWS frequently offers discounts or credits, especially for long-term commitments (e.g., Reserved Instances or Savings Plans). Depending on the usage and business agreements, the actual cost may be lower than the on-demand pricing used in this comparison.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Additional costs&lt;/strong&gt;: This comparison focuses on the core infrastructure and monitoring services. Additional services such as data transfer, storage, or advanced features (like cross-region metrics replication or higher retention periods) might incur extra costs, depending on the specific use case and setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key takeaways - Prometheus Vs CloudWatch
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you are starting out a new organization or a new product – you definitely might want to use a managed service such as CloudWatch or Amazon-managed Prometheus.&lt;/li&gt;
&lt;li&gt;Once you &lt;a href="https://www.infracloud.io/cloud-native-consulting/" rel="noopener noreferrer"&gt;start embracing cloud-native technologies&lt;/a&gt; and also thinking of multi-cloud or cloud-agnostic infrastructure, then it is better to start thinking about Prometheus.&lt;/li&gt;
&lt;li&gt;If you are doing anything of non-trivial scale – there might be benefits to using Prometheus. The benefits can be economic as well as beyond economics, such as feature richness.&lt;/li&gt;
&lt;li&gt;For some AWS managed services, such as RDS – you will need to use CloudWatch for native monitoring and then use Prometheus exporters to get the data into Prometheus servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We would love to hear the stories of using CloudWatch vs Prometheus or other services and how you make the decision of choosing one over the other. Let’s start a conversation with &lt;a href="https://www.linkedin.com/in/hrishikesh-deodhar/" rel="noopener noreferrer"&gt;Hrishikesh&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/ruturaj-kadikar/" rel="noopener noreferrer"&gt;Ruturaj&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking for help with observability stack implementation and consulting? Do check out how we’re helping startups &amp;amp; enterprises as an &lt;a href="https://www.infracloud.io/observability-consulting/" rel="noopener noreferrer"&gt;observability consulting services provider&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>cloudnative</category>
      <category>kubernetes</category>
      <category>prometheus</category>
    </item>
    <item>
      <title>Building Resilience with Chaos Engineering and Litmus</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Sat, 10 Jun 2023 13:51:07 +0000</pubDate>
      <link>https://dev.to/infracloud/building-resilience-with-chaos-engineering-and-litmus-3cpl</link>
      <guid>https://dev.to/infracloud/building-resilience-with-chaos-engineering-and-litmus-3cpl</guid>
      <description>&lt;p&gt;Microservices architecture is a popular choice for businesses today due to its scalability, agility, and continuous delivery. However, microservices architectures are not immune to outages. Outages can be caused by a variety of factors, including network communication, inter-service dependencies, external dependencies, and scalability issues.&lt;/p&gt;

&lt;p&gt;Several well-known companies, such as &lt;a href="https://www.spiceworks.com/tech/tech-general/news/slack-outage-service-disruption/#:~:text=On%20Tuesday%2C%20the%20business%20communication,out%20from%20the%20desktop%20application."&gt;Slack&lt;/a&gt;, &lt;a href="https://techcrunch.com/2023/05/04/twitters-mobile-web-app-is-currently-down-for-some/"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.usatoday.com/story/money/markets/2021/06/30/robinhood-fined-70-million-over-outages-and-misleading-customers/7811627002/"&gt;Robinhood Trading&lt;/a&gt;, &lt;a href="https://www.crn.com/news/cloud/amazon-alexa-down-more-than-15-000-reports-of-outages"&gt;Amazon&lt;/a&gt;, &lt;a href="https://www.bleepingcomputer.com/news/microsoft/microsoft-365-hit-by-new-outage-causing-connectivity-issues/"&gt;Microsoft&lt;/a&gt;, &lt;a href="https://www.financialexpress.com/life/technology-google-outage-services-back-up-for-us-users-confirms-company-3053719/"&gt;Google&lt;/a&gt;, and &lt;a href="https://www.crn.com/news/cloud/the-10-biggest-cloud-outages-of-2022-so-far-"&gt;many more&lt;/a&gt; have recently experienced &lt;a href="https://uptimeinstitute.com/about-ui/press-releases/2022-outage-analysis-finds-downtime-costs-and-consequences-worsening"&gt;outages that caused significant downtime costs&lt;/a&gt;. These outages highlight the diverse sources of outages in microservices architectures, which can range from configuration errors and database issues to infrastructure scaling failures and code problems.&lt;/p&gt;

&lt;p&gt;To minimize the impact of outages and improve system availability, businesses should prioritize resiliency principles in the design, development, and operation of microservices architectures. In this article, we will learn how to improve the resiliency of a system with the help of chaos engineering to minimize system outages. &lt;br&gt;
I recently spoke at &lt;a href="https://chaoscarnival.io/"&gt;Chaos Carnival&lt;/a&gt; on the same topic, you can also watch my talk &lt;a href="https://www.infracloud.io/cloud-native-talks/testing-resiliency-within-beyond-kubernetes/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Chaos Engineering?
&lt;/h2&gt;

&lt;p&gt;Chaos engineering is a method for testing the resiliency and reliability of complex systems by intentionally introducing controlled failures into them. The goal of chaos engineering is to identify and highlight faults in a system before they can cause real-world problems such as outages, data loss, or security breaches.&lt;/p&gt;

&lt;p&gt;This is done by simulating various failure scenarios, such as network outages, server failures, or unexpected spikes in traffic, and observing how the system responds. By intentionally inducing failure in a controlled environment, chaos engineering enables teams to better understand the limits and failure domains of their systems and develop strategies to mitigate or avoid such failures in the future.&lt;/p&gt;

&lt;p&gt;Many big companies like Netflix, Amazon, Google, Microsoft, etc. are emphasizing chaos engineering as the crucial part of site reliability. &lt;a href="https://netflixtechblog.com/tagged/chaos-engineering"&gt;Netflix introduced tools to test chaos like Chaos Monkey, Chaos Kong, and ChAP&lt;/a&gt; at different infrastructure levels to maintain their SLAs. Amazon incorporated the concept of &lt;a href="https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.concept.gameday.en.html"&gt;Gamedays&lt;/a&gt; in their &lt;a href="https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/index.en.html"&gt;AWS Well-Architected Framework&lt;/a&gt;, wherein various teams collaborate and test chaos in their environment to educate, and reinforce the system knowledge in order to increase the overall reliability.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Resiliency Testing?
&lt;/h2&gt;

&lt;p&gt;Resiliency testing is primarily concerned with evaluating a system's ability to recover from disruptions or failures and continue to function as intended. The goal of resiliency testing is to improve the overall reliability and availability of a system and minimize the impact of potential disruptions or failures. By identifying and addressing potential vulnerabilities or weaknesses in system design or implementation, resiliency testing can help ensure that the system continues to function in the face of unexpected events or conditions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why should I test Resiliency?
&lt;/h2&gt;

&lt;p&gt;Resiliency testing is essential for a number of reasons. Here are a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoiding costly downtime:&lt;/strong&gt; Resiliency testing helps identify potential points of failure in a system, that can lead to costly downtime if not addressed. By testing a system's ability to recover from disruptions or failures, you can ensure that it'll continue to function as intended even when unexpected events occur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increase reliability:&lt;/strong&gt; It will help improve the overall reliability of a system. By identifying and addressing potential vulnerabilities, you can build a more robust and resilient system that is less likely to fail or be disrupted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improve the user experience:&lt;/strong&gt; A system that is resilient and can recover quickly from disruptions or outages is likely to provide a better user experience. It's less likely to experience outages or data loss, which can increase user satisfaction with the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compliance requirements:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/pulse/cloud-resilience-testing-ana-biazetti/"&gt;Many industries and regulations require that systems have a certain level of resilience and uptime&lt;/a&gt;. You can use this testing to ensure your system meets these requirements and avoids potential legal or regulatory issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, testing resiliency is important to ensure that your system is reliable, available, and able to recover quickly from failures or outages. By identifying and fixing potential failure points, you can build a more robust and resilient system that provides a better user experience and meets regulatory requirements.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why should I test Resiliency in Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Testing resiliency in Kubernetes is important because Kubernetes is a complex and distributed system designed for large-scale, mission-critical applications. Kubernetes provides many features to ensure resiliency, such as &lt;a href="https://www.infracloud.io/blogs/3-autoscaling-projects-optimising-kubernetes-costs/"&gt;automatic Kubernetes scaling&lt;/a&gt;, self-healing, and rolling updates, but it's still possible for a Kubernetes cluster to experience glitches or failures.&lt;/p&gt;

&lt;p&gt;Here are the top reasons why we should test resiliency in Kubernetes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Underlying infrastructure is critical to your application:&lt;/strong&gt; If your application relies on Kubernetes to manage and orchestrate its components, any disruption to the Kubernetes cluster can lead to downtime or data loss. You can use resiliency testing to ensure that your Kubernetes cluster can recover from disruptions and continue to function as intended.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Distributed system:&lt;/strong&gt; Kubernetes consists of many components such as nodes, controllers, and APIs that work together to create a unified platform for deploying and managing applications. Auditing the resilience of Kubernetes can help identify potential points of failure in this complex system and ensure that it can recover from disruptions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constant evolution:&lt;/strong&gt; Kubernetes is a rapidly evolving platform, with new features and updates being released regularly. You can use resiliency testing to ensure that your Kubernetes cluster can handle these changes and updates without downtime or disruption.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considering all of this, testing resiliency in Kubernetes is important to ensure that your application can handle interruptions and continue to function as intended.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chaos vs Resiliency vs Reliability
&lt;/h2&gt;

&lt;p&gt;Chaos, resiliency, and reliability are related concepts, but they aren't interchangeable. Here you'll find an overview of each concept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chaos:&lt;/strong&gt; Chaos is the intentional introduction of controlled failures or disruptions into a system to test its resilience and identify potential vulnerabilities. chaos engineering is a method of simulating these failures and evaluating the system's response.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resiliency:&lt;/strong&gt; Resiliency refers to the ability of a system to recover from disruptions or failures and continue to function as intended. Resilience testing is about evaluating a system's ability to recover from failures and identify potential failure points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability:&lt;/strong&gt; Reliability refers to the consistency and predictability of a system's performance over time. A reliable system can be relied upon to perform as intended, without unexpected failures or interruptions. Reliability is typically measured in terms of uptime, availability, and mean time between failures (MTBF).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a nutshell, chaos engineering is a way to build failures into your system to test resilience, which is the ability of a system to recover from failures, while reliability is a measure of the consistent and predictable performance of a system over time. All three concepts are important for building and maintaining robust and trustworthy systems, and each plays a different role in ensuring the overall quality and resilience of a system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LgILfmMJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pd0fv9svnh4w9yyprkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LgILfmMJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pd0fv9svnh4w9yyprkp.png" alt="chaos-resilience-reliability" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What are available Tools to Test System Resiliency?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/litmuschaos/litmus"&gt;Litmus&lt;/a&gt;, &lt;a href="https://www.gremlin.com/chaos-engineering/"&gt;Gremlin&lt;/a&gt;, &lt;a href="https://chaos-mesh.org/"&gt;Chaos Mesh&lt;/a&gt;, and &lt;a href="https://netflix.github.io/chaosmonkey/"&gt;Chaos Monkey&lt;/a&gt; are all popular open-source tools used for chaos engineering. As we will be using AWS cloud infrastructure, we will also explore AWS &lt;a href="https://aws.amazon.com/fis/"&gt;Fault Injection Simulator&lt;/a&gt; (FIS). While they share the same goals of testing and improving the resilience of a system, there are some differences between them. Here are some comparisons:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Chaos Mesh&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Chaos Monkey&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Litmus&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Gremlin&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;AWS FIS&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes-native&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud-native&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (AWS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baremetal&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in Library&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Extensive&lt;/td&gt;
&lt;td&gt;Extensive&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customization&lt;/td&gt;
&lt;td&gt;Using YAML&lt;/td&gt;
&lt;td&gt;Using YAML&lt;/td&gt;
&lt;td&gt;Using Operator&lt;/td&gt;
&lt;td&gt;Using DSL&lt;/td&gt;
&lt;td&gt;Using &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/documents.html"&gt;SSM docs&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSS&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The bottom line is that while all four tools share similar features, we choose Litmus as it provides flexibility to leverage &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-document.html"&gt;AWS SSM documents&lt;/a&gt; to execute chaos in our AWS infrastructure. &lt;br&gt;
Now let’s see how we can use Litmus to execute chaos like terminating pods and EC2 instances in Kubernetes and AWS environments respectively.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Litmus in Kubernetes
&lt;/h2&gt;

&lt;p&gt;At first, we will see how to install Litmus in Kubernetes to execute chaos in an environment.&lt;/p&gt;

&lt;p&gt;Here are the basic installation steps for LitmusChaos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set up a Kubernetes cluster: LitmusChaos requires a running Kubernetes cluster. If you don't already have one set up, you can use a tool like kubeadm or kops to set up a cluster on your own infrastructure or use a managed Kubernetes service like GKE, EKS, or AKS. For this article, we will use k3d.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;k3d cluster create
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```sh
$ kubectl cluster-info

Kubernetes control plane is running at https://0.0.0.0:38537

CoreDNS is running at https://0.0.0.0:38537/api/vl/namespaces/kube-system/services/kube-dns:dns/proxy

Metrics-server is running at https://0.0.0.0:38537/api/vl/namespaces/kube-system/services/https:metrics-server:https/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster—info dump’.
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Helm: Helm is a package manager for Kubernetes that you'll need to use to install Litmus. You can install Helm by following the instructions on the &lt;a href="https://helm.sh"&gt;Helm website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add the LitmusChaos chart repository: Run the following command to add the LitmusChaos chart repository:&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install LitmusChaos: Run the following command to install LitmusChaos:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;litmuschaos litmuschaos/litmus &lt;span class="nt"&gt;--namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;litmus
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This will install the LitmusChaos control plane in the &lt;code&gt;litmus&lt;/code&gt; namespace. You can change the namespace to your liking.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the installation: Run the following command to verify that LitmusChaos is running:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; litmus
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-nlitmus&lt;/span&gt;
NAME                            READY  STATUS   RESTARTS  AGE
chaos-litmus-frontend-6££c95c884-x2452  1/1   Running     0       6m22s
chaos-litmus-auth-server-b8dcdf66b-v8hf9  1/1  Running  0       6m22s
chaos-litmus-server-585786dd9c-16x37  1/1   Running     0       6m22s
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This should show the LitmusChaos control plane pods running.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Login into the Litmus portal using port-forwarding.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward svc/chaos-litmus-frontend-service &lt;span class="nt"&gt;-nlitmus&lt;/span&gt; 9091:9091
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v5jt_ntC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjkeyczuoo68wjw0a2o6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v5jt_ntC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjkeyczuoo68wjw0a2o6.png" alt="Litmus chaos installed" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Once you log in, a webhook will install litmus-agent (called self-agent) components in the cluster. Verify it.

Output:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```sh
$  kubectl get pods -n litmus
NAME                                    STATUS  RESTARTS   AGE   READY
chaos-litmus-frontend-6£fc95c884-x245z Running   0         9m6s  1/1
chaos-litmus-auth-server-b8dcdf66b-v8he9  Running   0       9m6s  1/1
chaos-litmus-server-585786dd9c-16x37    Running   0         9m6s  1/1
subscriber-686d9b8dd9-bjgih             Running   0         9m6s  1/1
chaos-operator-ce-84bc885775-kzwzk      Running   0         92s   1/1
chaos-exporter-6c9b5988cd-1wmpm         Running   0         94s   1/1
event-tracker-744b6fd8cf-rhrfc          Running   0         94s   1/1
workflow-controller-768b7d94dc-xr6vy    Running   0         92s   1/1
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these steps, you should have LitmusChaos installed and ready to use on your Kubernetes cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimenting with chaos
&lt;/h2&gt;

&lt;p&gt;Experimenting with chaos within a cloud-native environment typically involves using a chaos engineering tool to simulate various failure scenarios and test the resilience of the system. Most of the cloud-native application infrastructure consists of Kubernetes and corresponding Cloud components. For this article, we will see chaos in Kubernetes and in the cloud environment i.e. AWS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaos in Kubernetes
&lt;/h3&gt;

&lt;p&gt;In order to evaluate the resilience of a Kubernetes cluster we can test the following failure scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubernetes node failure:&lt;/strong&gt; Simulate the failure of a Kubernetes node by shutting down a node or disconnecting it from the network. This tests whether the cluster can withstand the failure of a node and whether the affected pods can be moved to other nodes. The delay in migrating the pods from one node to another may cause any cascading failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pod failure:&lt;/strong&gt; We can simulate the failure of a pod by shutting it down or introducing a fault into the pod's container. This tests the cluster's ability to detect and recover from a pod failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network failure:&lt;/strong&gt; This consists of simulating network partitioning or network congestion to test the cluster's ability to handle communication failures between nodes and pods. You can use &lt;a href="https://man7.org/linux/man-pages/man8/tc.8.html"&gt;Linux Traffic Control&lt;/a&gt; tool to manipulate traffic flowing in and out of your system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource saturation:&lt;/strong&gt; Simulate resource saturation, such as CPU or memory exhaustion, to test the cluster's ability to handle resource contention and prioritize critical workloads. You can use &lt;a href="https://manpages.ubuntu.com/manpages/bionic/man1/stress-ng.1.html"&gt;stress-ng&lt;/a&gt; tool to hog memory or CPU utilization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DNS failure:&lt;/strong&gt; Introduce DNS failures to test the cluster's ability to resolve DNS names and handle service lookup failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cluster upgrades:&lt;/strong&gt; Simulate upgrades to the Kubernetes cluster, including the control plane and worker nodes, to test the cluster's ability to perform rolling upgrades and maintain availability during the upgrade process.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By testing these failure scenarios, you can identify potential vulnerabilities in the cluster's resilience and improve the system to ensure high availability and reliability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Scenario: Killing a Pod
&lt;/h4&gt;

&lt;p&gt;In this experiment, we will kill a pod using Litmus. We will use an Nginx deployment for a sample application under test (AUT).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create deploy nginx &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx &lt;span class="nt"&gt;-nlitmus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get deploy &lt;span class="nt"&gt;-nlitmus&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;nginx

NAME   READY   UP-TO-DATE   AVAILABLE   AGE
nginx  1/1  1           1           109m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to Litmus portal, and click on Home.&lt;/p&gt;

&lt;p&gt;Click on Schedule a Chaos Scenario and select Self Agent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kPLbWhs0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/taps3ul3lv9hqen6eolf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kPLbWhs0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/taps3ul3lv9hqen6eolf.png" alt="Schedule Chaos Scenario" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, select chaos experiment from ChaosHubs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HXXvWXwy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdnlb1u2gdn7nc0ho6zz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HXXvWXwy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdnlb1u2gdn7nc0ho6zz.png" alt="Select chaos experiment from ChaosHubs" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, name the scenario as ‘kill-pod-test’.&lt;/p&gt;

&lt;p&gt;Next, click on ‘Add a new chaos Experiment’.&lt;/p&gt;

&lt;p&gt;Choose generic/pod-delete experiment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bKFf_Nbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ox80z98cvftnme2gpps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bKFf_Nbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ox80z98cvftnme2gpps.png" alt="Choose experiment" width="644" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tune the experiment parameters to select the correct deployment labels and namespace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8kToUNkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zywhc4mbfv1smn4vl3sj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8kToUNkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zywhc4mbfv1smn4vl3sj.png" alt="Tune the selected chaos scenario" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enable Revert Schedule and click Next.&lt;/p&gt;

&lt;p&gt;Assign the required weight for the experiment, for now, we will keep 10 points.&lt;/p&gt;

&lt;p&gt;Click Schedule Now and then Finish. The execution of the Chaos Scenario will start.&lt;/p&gt;

&lt;p&gt;To view the Chaos Scenario, click on ‘Show the Chaos Scenario’.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1NwENLbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olt7ef3a67c3x4i76grz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1NwENLbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olt7ef3a67c3x4i76grz.png" alt="View Chaos scenario" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see the Chaos Scenario and experiment crds getting deployed and the corresponding pods getting created.&lt;/p&gt;

&lt;p&gt;Once the Chaos Scenario is completed, you will see that the existing Nginx pod is deleted and a new pod is up and running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---qDTlEKR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydhxijbw2fwyenz2w9vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---qDTlEKR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydhxijbw2fwyenz2w9vp.png" alt="New Pod" width="800" height="156"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-nlitmus&lt;/span&gt;
NAME                                        READY   STATUS  RESTARTS   AGE
chaos-litmus-frontend-6ffc95c884-x245z      1/1     Running   0         32m
chaos-mongodb-68f8b9444c-w2kkm              1/1     Running   0         32m
chaos-litmus-auth-server-b8dcdf66b-v8hf9    1/1     Running   0         32m
chaos-litmus-server-585786dd9c-16xj7        1/1     Running   0         32m
subscriber-686d9b8dd9-bjgjh                 1/1     Running   0         24m
chaos-operator-ce-84bc885775-kzwzk          1/1     Running   0         24m
chaos-exporter-6c9b5988c4-1wmpm             1/1     Running   0         24m
event-tracker-744b6fd8cf-rhrfc              1/1     Running   0         24m
workflow-controller-768f7d94dc-xr6vv        1/1     Running   0         24m
kill-pod-test-1683898747-869605847          0/2     Completed 0         9m36s
kill-pod-test-1683898747-2510109278         2/2     Running   0         5m49s
Pod-delete-tdoklgkv-runner          1/1 Running   0         4m29s
Pod-delete-swkok2-pj48x         1/1 Running   0         3m37s
nginx-76d6c9b8c-mnk8f                       1/1     Running   0         4m29s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify the series of events to understand the entire process. Some of the main events are shown below stating experiment pod was created, the nginx pod (AUT) getting deleted, the nginx pod getting created again, and the experiment was successfully executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get events &lt;span class="nt"&gt;-nlitmus&lt;/span&gt;                                              
66s   Normal    Started            pod/pod-delete-swkok2-pj48x                  Started container pod-delete-swkok2                                                 
62s   Normal    Awaited            chaosresult/pod-delete-tdoklgkv-pod-delete   experiment: pod-delete, Result: Awaited
58s   Normal    PreChaosCheck      chaosengine/pod-delete-tdok1gkv              AUT: Running                                                                        
58s   Normal    Killing            pod/nginx-76d6c9b8c-c8vv7                    Stopping container nginx                                                            
58s   Normal    Successfulcreate   replicaset/nginx-76d6c9b8c                   Created pod: nginx-76d6c9b8c-mnk8f                                                                                                             
44s   Normal    Killing            pod/nginx-76d6c9b8c-mnk8f                    Stopping container nginx                                                            
44s   Normal    Successfulcreate   replicaset/nginx-76d6c9b8c                   Created pod: nginx-76d6c9b8c-kqtgq                                                  
43s   Normal    Scheduled          pod/nginx-76d6c9b8c-kqtgq                    Successfully assigned litmus/nginx-76d6c9b8c-kqtgq to k3d-k3s-default-server-0         
128   Normal    PostChaosCheck     chaosengine/pod-delete-tdok1gkv              AUT: Running                                                                        
8s    Normal    Pass               chaosresult/pod-delete-tdoklgkv-pod-delete   experiment: pod-delete, Result: Pass
8s    Normal    Summary            chaosengine/pod-delete-tdok1gkv              pod-delete experiment has been Passed                                               
3s    Normal    Completed          job/pod-delete-swkok2                        Job completed  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Chaos in AWS
&lt;/h3&gt;

&lt;p&gt;Here are some potential problems that can be simulated to assess the ability of an application running on AWS to recover from failures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Availability zone failure:&lt;/strong&gt; Simulate the failure of an availability zone in an AWS region to test the application's ability to withstand data center failure. You can simulate this type of failure by changing the NACL or Route table rules and restoring them back again. &lt;br&gt;
Note: You need to be extremely cautious while doing such activities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instance failure:&lt;/strong&gt; Simulate the failure of an EC2 instance by terminating the instance to test the application's ability to handle node failures and maintain availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto-Scaling group failure:&lt;/strong&gt; Simulate the failure of an auto-scaling group by suspending or terminating all instances in the group to test the application's ability to handle scaling events and maintain availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network failure:&lt;/strong&gt; Simulate network failures, such as network congestion or network partitioning, to test the application's ability to handle communication failures between nodes. You can also simulate &lt;a href="https://www.techtarget.com/searchnetworking/definition/Network-Time-Protocol"&gt;Network Time Protocol&lt;/a&gt; (NTP) asynchronization and see the effect when one node or set of nodes are out of sync.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database failure:&lt;/strong&gt; Simulate database failure by shutting down the database or introducing a fault into the database system to test the application's ability to handle database failures and maintain data consistency. You can check whether your backup and restore mechanisms are working fine or not. You can verify whether the secondary node is being promoted to primary in case of failures and how much time it takes for the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security breach:&lt;/strong&gt; Simulate security breaches, such as unauthorized access or data breaches, to test the application's ability to handle security incidents and maintain data confidentiality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Scenario: Terminate EC2 instance
&lt;/h4&gt;

&lt;p&gt;In this scenario, we will include one chaos experiment of terminating an EC2 instance. Litmus leverages AWS SSM documents for executing experiments in AWS. For this scenario, we will require two manifest files; one for configMap consisting of the script for the SSM document and the other consisting of a complete workflow of the scenario. Both these manifest files can be found &lt;a href="https://github.com/rutu-k/litmus-ssm-docs/tree/main"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Apply the configMap first in the ‘litmus’ namespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/rutu-k/litmus-ssm-docs/main/terminate-instance-cm.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, go to the Litmus portal, and click on Home.&lt;/p&gt;

&lt;p&gt;Click on Schedule a Chaos Scenario and select Self Agent. (Refer Installation and Chaos in Kubernetes)&lt;/p&gt;

&lt;p&gt;Now, instead of selecting chaos experiment from ChaosHubs, we will select Import a Chaos Scenario using YAML and upload our workflow manifest.&lt;/p&gt;

&lt;p&gt;Click Next and Finish.&lt;/p&gt;

&lt;p&gt;To View the Chaos Scenario, click on Show the Chaos Scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wcCrrPOS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl5h24tb10d48jey2282.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wcCrrPOS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl5h24tb10d48jey2282.png" alt="Chaos scenario" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see the Chaos Scenario and experiment crds getting deployed and the corresponding pods getting created.&lt;/p&gt;

&lt;p&gt;Verify the logs of the experiment pods. It will show the overall process and status of each step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl logs aws-ssm-chaos-by-id-vSoazu-w6tmj &lt;span class="nt"&gt;-n&lt;/span&gt; litmus &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:05:10Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Experiment Name: aws-ssm-chaos-by-id"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:05:14Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"The instance information is as follows"&lt;/span&gt; Chaos &lt;span class="nv"&gt;Namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;litmus Instance &lt;span class="nv"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;i-0da74bcaa6357ad60 &lt;span class="nv"&gt;Sequence&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;parallel Total Chaos &lt;span class="nv"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;960
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:05:14Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Info]: The instances under chaos(IUC) are: [i-0da74bcaa6357ad60]"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:07:252"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Status]: Checking SSM command status"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:07:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"The ssm command status is Success"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:07:28Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Wait]: Waiting for chaos interval of 120s"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:28Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Info]: Target instanceID list, [i-0da74bcaa6357ad60]"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:28Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Chaos]: Starting the ssm command"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:28Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Wait]: Waiting for the ssm command to get in InProgress state”
time="&lt;/span&gt;2023-05-11T13:09:28Z&lt;span class="s2"&gt;" level=info msg="&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Status]: Checking SSM &lt;span class="nb"&gt;command &lt;/span&gt;status”
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:30Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"The ssm command status is InProgress”
time="&lt;/span&gt;2023-05-11T13:09:32Z&lt;span class="s2"&gt;" level=info msg="&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Wait]: waiting &lt;span class="k"&gt;for &lt;/span&gt;the ssm &lt;span class="nb"&gt;command &lt;/span&gt;to get completed”
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:32Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"[Status]: Checking SSM command status"&lt;/span&gt;
&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-05-11T13:09:32Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"The ssm command status is Success"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the Chaos Scenario is completed, you will see that the SSM document is executed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n1RvWpDP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43g2ivv3qmsm6jci0l30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n1RvWpDP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43g2ivv3qmsm6jci0l30.png" alt="SSM document is executed" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can verify that the EC2 instance is being terminated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--86avmYZW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b3mok5k1of5x4695trc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--86avmYZW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b3mok5k1of5x4695trc.png" alt="EC2 instance is terminated" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do next?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Design a Resiliency Framework
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EZh-4jpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qe63ot6r7lqb0a1oavnu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EZh-4jpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qe63ot6r7lqb0a1oavnu.png" alt="Resiliency Framework" width="672" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A resiliency framework refers to a structured approach or set of principles and strategies leveraging chaos engineering to build resilience and ensure overall reliability. The following is a detailed description of the typical steps or lifecycle involved in the resiliency framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define steady state:&lt;/strong&gt; The steady state of a system refers to a state where the system is in equilibrium and operating normally under typical conditions. It represents a stable and desired outcome where the system's components, services, and dependencies are functioning correctly and fulfilling their intended roles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define the hypothesis:&lt;/strong&gt; In this step, you have to hypothesize or predict the behavior of your system when subjected to specific chaos like high load, failure of a specific component or network disruptions, and many more. Suppose we have strategically distributed our workloads across four distinct availability zones (AZs) to ensure robust availability. Now, imagine a scenario where we deliberately introduce chaos into the system, causing one of the AZs to fail. In such a situation, can the system effectively handle and adapt to this unexpected event while maintaining its overall functionality? .&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Formulate and execute the experiment:&lt;/strong&gt; Determine the scope and parameters of the experiment. This includes identifying the specific type of chaos to be introduced (such as network latency, resource exhaustion, or random termination of pods/instances), the duration of the experiment, and any constraints or safety measures to be put in place. Implement the chaos experiment by introducing controlled disruptions or failures into the target system. The chaos should be introduced gradually and monitored closely to ensure it remains within acceptable boundaries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Revert chaos:&lt;/strong&gt; Revert the chaos induced in your system and bring the system back to a steady state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify steady state:&lt;/strong&gt; Analyze the data collected during the chaos experiment to determine the system's resilience and identify any weaknesses or vulnerabilities. Compare the observed behavior with expected outcomes (hypothesis) and evaluate the system's ability to recover and maintain its desired level of performance and functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Report:&lt;/strong&gt; Document the experiment details, findings, and recommendations for future reference. Share the results with the broader team or organization to foster a culture of learning and continuous improvement. This documentation can serve as a valuable resource for future chaos engineering experiments,  improve your understanding of the system, and help build institutional knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Periodic resiliency checks:&lt;/strong&gt; This is an ongoing process rather than a one-time event. Regularly repeat the above steps to validate system resilience, especially after making changes or updates to the system. Gradually scale up the complexity and intensity of the experiments as confidence in the system's resilience grows. Based on the insights gained from the experiment, make necessary adjustments and improvements to the system's architecture, design, or operational procedures. This could involve fixing identified issues, optimizing resource allocation, enhancing fault tolerance mechanisms, or refining automation and monitoring capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Assign a Resiliency Score
&lt;/h3&gt;

&lt;p&gt;The resiliency score is a metric used to measure and quantify the level of resiliency or robustness of a system (refer). The Resiliency Score is typically calculated based on various factors, including the system's architecture, its mean time to recover (MTTR), its mean time between failures (MTBF), redundancy measures, availability, scalability, fault tolerance, monitoring capabilities, and recovery strategies. It varies from system to system and organization to organization depending upon their priorities and requirements.&lt;/p&gt;

&lt;p&gt;The resiliency score helps organizations evaluate their system's resiliency posture and identify areas that need improvement. A higher resiliency score indicates a more resilient system, capable of handling failures with minimal impact on its functionality and user experience. Organizations can track their progress in improving system resiliency over time by continuously measuring and monitoring the resiliency score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gamedays
&lt;/h3&gt;

&lt;p&gt;Gamedays are controlled and planned events where organizations simulate real-world failure scenarios and test their system's resiliency in a safe and controlled environment. During a Gameday, a team deliberately introduces failures or injects chaos into the system to observe and analyze its behavior and response. &lt;/p&gt;

&lt;p&gt;The organization should practice Gamedays as they offer a chance for teams to practice and improve their incident response and troubleshooting skills. It enhances team collaboration, communication, and coordination during high-stress situations, which are valuable skills when dealing with real-world failures or incidents. It demonstrates an organization's proactive approach in ensuring that the system can endure unexpected events and continue operating without experiencing significant disruptions.&lt;/p&gt;

&lt;p&gt;Overall, Gamedays serve as a valuable practice to improve system resiliency, validate recovery mechanisms, and build a culture of preparedness and continuous improvement within organizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incorporate Resiliency Checks in CI/CD Pipelines
&lt;/h3&gt;

&lt;p&gt;Integrating resiliency checks into CI/CD pipelines offers several advantages, helping to enhance the overall robustness and reliability of software systems. Here are some key benefits of incorporating resiliency checks in these pipelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early detection of resiliency issues:&lt;/strong&gt; By including resiliency checks in the CI/CD pipeline, organizations can identify potential resiliency issues early in the software development lifecycle. This allows teams to address these issues proactively before they manifest as critical failures in production environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced user experience:&lt;/strong&gt; Resilient software systems are better equipped to handle failures without affecting the end-user experience. Organizations can identify and mitigate issues that could impact user interactions, ensuring a seamless and uninterrupted user experience by incorporating resiliency checks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increased system stability:&lt;/strong&gt; Resiliency checks pertaining to the system’s stability can be validated in CI/CD pipelines. This helps prevent cascading failures and ensures that the system remains stable and performs optimally even under challenging conditions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better preparedness for production environments:&lt;/strong&gt; CD pipelines provide an environment for simulating real-world scenarios, including failures and disruptions. By including resiliency checks, teams can better prepare their software for production environments, allowing them to identify and address resiliency gaps before deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost savings:&lt;/strong&gt; By addressing resiliency issues early in the CD pipeline, organizations can mitigate potential financial losses resulting from system failures in production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compliance requirements:&lt;/strong&gt; By integrating resiliency checks into the CI/CD pipeline, organizations can ensure that their software systems meet compliance requirements like &lt;a href="https://www.tigera.io/blog/extend-ci-cd-with-cr-for-continuous-app-resilience/"&gt;SoC/SoX&lt;/a&gt; requirements and demonstrate their adherence to industry standards.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Improve Observability Posture
&lt;/h3&gt;

&lt;p&gt;It is presumed that the system is actively monitored, and relevant &lt;a href="https://www.infracloud.io/blogs/prometheus-architecture-metrics-use-cases/"&gt;metrics&lt;/a&gt;, &lt;a href="https://www.infracloud.io/blogs/grafana-loki-log-monitoring-alerting/"&gt;log&lt;/a&gt;, &lt;a href="https://www.infracloud.io/blogs/opentelemetry-auto-instrumentation-jaeger/"&gt;traces&lt;/a&gt;, and other events are captured and analyzed before inducing chaos in the system. Make sure your observability tools and processes provide visibility into the system's health, performance, and potential issues, triggering alerts or notifications when anomalies or deviations from the steady state are detected. &lt;/p&gt;

&lt;p&gt;In case, there is no visibility for any issue that occurs during the chaos, you have to incorporate and improve your observability measures accordingly. With several different chaos experiments, you can analyze missing observability data and add it to your system accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we learned what is chaos engineering, resiliency, reliability, and how all three are related to each other. We saw what are available tools for executing chaos and why we chose Litmus for our use case.&lt;/p&gt;

&lt;p&gt;Further, we explored what types of chaos experiments we can execute in Kubernetes and AWS environments. We also saw a demo of chaos experiments executed in both environments. In addition to this, we have learned how we can design a resiliency framework and incorporate resiliency scoring, gamedays, and resiliency checks to improve the overall observability of a platform.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Hope you found this blog post helpful. If you have any questions or suggestions, please do reach out to &lt;a href="https://www.linkedin.com/in/ruturaj-kadikar/"&gt;Ruturaj&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/devops/chaos-engineering-on-amazon-eks-using-aws-fault-injection-simulator/"&gt;Chaos engineering on Amazon EKS using AWS Fault Injection Simulator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/architecture/chaos-engineering-in-the-cloud/"&gt;Chaos Engineering in the cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opensource.com/downloads/chaos-engineering-kubernetes"&gt;Chaos engineering for Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.container-solutions.com/comparing-chaos-engineering-tools"&gt;Comparing Chaos Engineering Tools for Kubernetes Workloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.in/DevOps-Toolkit-Kubernetes-Chaos-Engineering/dp/B086Y5M9CW"&gt;The DevOps Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/the-cloud-architect/the-chaos-engineering-collection-5e188d6a90e2"&gt;The Chaos Engineering Collection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sre</category>
      <category>kubernetes</category>
      <category>devops</category>
      <category>chaosengineering</category>
    </item>
    <item>
      <title>EdgeX Foundry on K3s - the Initiation</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Wed, 24 Nov 2021 18:33:01 +0000</pubDate>
      <link>https://dev.to/infracloud/edgex-foundry-on-k3s-the-initiation-1lo5</link>
      <guid>https://dev.to/infracloud/edgex-foundry-on-k3s-the-initiation-1lo5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post is part 2 of a series of articles about how to deploy and operate EdgeX Foundry - an open source software framework for IoT Edge on K3s - a lightweight, highly available, and secured orchestrator.&lt;/em&gt;&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;In the first part of this series, we have seen all the pre-requisites that are needed to proceed with the hands-on. We will extend the &lt;a href="https://docs.edgexfoundry.org/1.2/examples/LinuxTutorial/EdgeX-Foundry-tutorial-ver1.0.pdf"&gt;EdgeX Foundry tutorial by Jonas Werner&lt;/a&gt; and deploy the EdgeX Foundry services on K3s. We have already learned that K3s will be a good lightweight solution to manage and orchestrate the EdgeX microservices. We will use the &lt;code&gt;Geneva&lt;/code&gt; version of EdgeX Foundry.&lt;/p&gt;

&lt;p&gt;The scope of this post is to demonstrate an Edge use case that will consume the sensor data e.g. ambient temperature. This sensor data will then be processed by EdgeXFoundry services hosted on K3s. This sensor data will be pushed to a cloud-based MQTT broker called &lt;a href="https://www.hivemq.com/"&gt;HiveMQ&lt;/a&gt;. From here, the data can be stored and processed in the cloud. The configurations and manifests used in these posts are available in this &lt;a href="https://github.com/rutu-k/edgex-k3s"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;The end-to-end setup looks like Fig.1. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ya7PRbGn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fbqug2w5ebb0gxzrlx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ya7PRbGn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fbqug2w5ebb0gxzrlx0.png" alt="Fig. 1: showing end to end setup" width="755" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DHT-22 with Raspberry-Pi (Edge Device)
&lt;/h3&gt;

&lt;p&gt;We will use a DHT-22 sensor that captures ambient temperature and humidity. Note that the sensor doesn't require a breadboard or resistor, it is all mounted on the SMD (Surface Mounted Devices). DHT sensor will be connected to GPIO (General-purpose I/O) pins of Raspberry Pi.&lt;/p&gt;

&lt;p&gt;The following changes are made in the script that captures temperature and sends the sensor data to the EdgeX. The &lt;code&gt;EdgeX IP&lt;/code&gt;, &lt;code&gt;DHT sensor type&lt;/code&gt;, &lt;code&gt;GPIO&lt;/code&gt; pin of the Raspberry-Pi, and NodePort of &lt;code&gt;edge-device-rest&lt;/code&gt; service as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Adafruit_DHT&lt;/span&gt;

&lt;span class="n"&gt;edgexip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"192.168.1.179"&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="c1"&gt;# Update to match DHT sensor type and GPIO pin
&lt;/span&gt;    &lt;span class="n"&gt;rawHum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rawTmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Adafruit_DHT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;urlTemp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'http://%s:32536/api/v1/resource/Temp_and_Humidity_sensor_cluster_01/temperature'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;edgexip&lt;/span&gt;
    &lt;span class="n"&gt;urlHum&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'http://%s:32536/api/v1/resource/Temp_and_Humidity_sensor_cluster_01/humidity'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;edgexip&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E_Ibzocl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10uqubzzogpzpkqhliwc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E_Ibzocl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10uqubzzogpzpkqhliwc.jpg" alt="DHT sensor connected to Raspberry-Pi" width="800" height="776"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you deploy EdgeX on K3s?
&lt;/h3&gt;

&lt;p&gt;Let us first deploy a K3s cluster, with K3s-server and K3s-agent on two separate VMs as seen in Fig. 3. The EdgeX services on K3s will act more like a Gateway (see Fig. 4 in &lt;a href="https://www.infracloud.io/blogs/edgex-foundry-k3s-part-1/"&gt;part-1&lt;/a&gt;). For the VMs, we will use Ubuntu-20.04 OS. Once the VMs are created, proceed with the following steps to deploy K3s.&lt;br&gt;
Note that, it will be better to configure static IPs on both VMs.&lt;/p&gt;
&lt;h3&gt;
  
  
  K3s server/master
&lt;/h3&gt;

&lt;p&gt;To configure the K3s server, we will use the following steps&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;K3s_NODE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="p"&gt;//_/-&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;K3s_EXTERNAL_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;host-ip&amp;gt;
curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://docs.rancher.cn/k3s/k3s-install.sh |  sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the node token generated&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /var/lib/rancher/k3s/server/node-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check whether the K3s server is up and running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl status k3s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  K3s agent
&lt;/h3&gt;

&lt;p&gt;To configure the K3s agent, we will use the following steps&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export K3S_TOKEN=&amp;lt;node-token of K3s server&amp;gt;
export K3s_URL=https://&amp;lt;ip of k3s server&amp;gt;:6443
export INSTALL_K3S_EXEC="--docker --token $K3S_TOKEN --server $K3S_URL"
export K3S_NODE_NAME=${HOSTNAME//_/-}
curl -sfL https://docs.rancher.cn/k3s/k3s-install.sh | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check whether the K3s server is up and running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl status k3s-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you have installed cli tools like &lt;code&gt;kubectl&lt;/code&gt; and &lt;code&gt;helm&lt;/code&gt;. Also ensure that you have set correct permissions for the same. &lt;code&gt;kubeconfig&lt;/code&gt; file for K3S is stored at &lt;code&gt;/etc/rancher/k3s/k3s.yaml&lt;/code&gt;. Set the KUBECONFIG environment variable before proceeding further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/rancher/k3s/k3s.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to deploy EdgeX Foundry on K3s?
&lt;/h3&gt;

&lt;p&gt;Once K3s is is up and running, clone this &lt;a href="https://github.com/rutu-k/edgex-k3s"&gt;repository&lt;/a&gt; for deploying EdgeX Foundry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rutu-k/edgex-k3s.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that, EdgeX Foundry has a docker-compose manifest to try and test its services. Using &lt;code&gt;kompose&lt;/code&gt; we can convert the docker-compose manifest to Kubernetes manifest.&lt;/p&gt;

&lt;p&gt;Also, after converting to Kubernetes manifest, the applications which were using volumes may not be configured properly and eventually won't work in Kubernetes. For this reason, the respective manifests must be corrected properly. For simplicity, &lt;code&gt;emptyDir&lt;/code&gt; volumes are configured.&lt;/p&gt;

&lt;p&gt;First, we will start with Consul. Consul is used as a registry by EdgeX Foundry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nt"&gt;--kubeconfig&lt;/span&gt; /etc/rancher/k3s/k3s.yaml upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; consul ./consul-helm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Consul is in running state, you can visit the dashboard &lt;code&gt;http://[K3s server ip]:[NodePort of service]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that if you visit the Key-Value store, it will be empty. We need to provide the respective configs for the EdgeX Foundry services. For this, we will import the Key-Values and store it in Consul.&lt;br&gt;
I have exported the Key/Value JSON file from the Consul when I was going through the tutorial's docker-compose deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;consul kv import &lt;span class="nt"&gt;--http-addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://[K3s server ip]@edgex-kv.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you will see the configs in the Key-Value store.&lt;/p&gt;

&lt;p&gt;Deploy the EdgeX Foundry application services&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; /k3s/.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that all the application services are up and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc
NAME                                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                                                                   AGE
kubernetes                             ClusterIP   10.43.0.1       &amp;lt;none&amp;gt;        443/TCP                                                                   4d1h
edgex-redis                            ClusterIP   10.43.56.89     &amp;lt;none&amp;gt;        6379/TCP                                                                  3d23h
edgex-core-consul                      ClusterIP   None            &amp;lt;none&amp;gt;        8500/TCP,8301/TCP,8301/UDP,8302/TCP,8302/UDP,8300/TCP,8600/TCP,8600/UDP   25h
consul                                 NodePort    10.43.193.246   &amp;lt;none&amp;gt;        80:32688/TCP                                                              25h
edgex-app-service-configurable-mqtt    NodePort    10.43.102.126   &amp;lt;none&amp;gt;        48101:32294/TCP                                                           4h26m
edgex-app-service-configurable-rules   NodePort    10.43.138.76    &amp;lt;none&amp;gt;        48100:30136/TCP                                                           4h26m
edgex-core-command                     NodePort    10.43.52.70     &amp;lt;none&amp;gt;        48082:32400/TCP                                                           4h26m
edgex-device-rest                      NodePort    10.43.167.127   &amp;lt;none&amp;gt;        49986:32536/TCP                                                           4h26m
edgex-core-metadata                    NodePort    10.43.132.29    &amp;lt;none&amp;gt;        48081:30220/TCP                                                           4h26m
edgex-support-notifications            NodePort    10.43.39.183    &amp;lt;none&amp;gt;        48060:32680/TCP                                                           4h26m
edgex-kuiper                           NodePort    10.43.231.24    &amp;lt;none&amp;gt;        48075:30082/TCP,20498:31868/TCP                                           4h26m
edgex-support-scheduler                NodePort    10.43.6.49      &amp;lt;none&amp;gt;        48085:31497/TCP                                                           4h26m
edgex-sys-mgmt-agent                   NodePort    10.43.250.114   &amp;lt;none&amp;gt;        48090:31736/TCP                                                           4h25m
edgex-core-data                        NodePort    10.43.251.191   &amp;lt;none&amp;gt;        5563:32220/TCP,48080:31931/TCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods
NAME                                                    READY   STATUS    RESTARTS   AGE
edgex-redis-54fb576f64-bdv9x                            1/1     Running   1          3d12h
consul-0                                                1/1     Running   0          25h
edgex-core-metadata-5bd45879cf-h9tbs                    1/1     Running   0          4h25m
edgex-kuiper-bbc6cf47-trkdl                             1/1     Running   0          4h25m
edgex-sys-mgmt-agent-7fb78c6fc5-qmqc2                   1/1     Running   0          4h25m
edgex-support-notifications-7b45446cbc-bqhvb            1/1     Running   0          4h25m
edgex-app-service-configurable-mqtt-59b5c7b6c8-8zhfc    1/1     Running   1          4h25m
edgex-app-service-configurable-rules-58c6846d54-s29hp   1/1     Running   1          4h25m
edgex-core-command-78b5ff9864-hb6wr                     1/1     Running   0          4h25m
edgex-core-data-86f5864db6-cvbl7                        1/1     Running   0          4h25m
edgex-support-scheduler-755b5779dc-br2d8                1/1     Running   0          4h25m
edgex-device-rest-599c579bf5-zbrg8                      1/1     Running   0          4h25m

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  EdgeX Foundry workflows
&lt;/h2&gt;

&lt;p&gt;EdgeX workflow can be divided into three main parts namely; Device, Core Data Service, and Application Service. There is another part for actuation where an action can be taken by analyzing the sensor data, but this is out of scope for this post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device workflow: It is the process of adding a particular sensor device, its profile, selecting the proper device protocol, creating an event object, and sending it to Core Data Service. If you want to add any device to the EdgeX Foundry, it needs three configurations as shown in Fig. 3:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QP5umIw5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddbf9nqcj5316ur8e8yx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QP5umIw5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddbf9nqcj5316ur8e8yx.png" alt="Fig. 3 showing device workflow components" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;ValueDescriptor: Next, the device service needs to inform EdgeX about the type of data it will be sent on the behalf of the devices. If you are given the number 5, what does that mean to you? Nothing, without some context and unit of measure. For example, if I was to say 5 feet is the scan depth of the camera right now, you have a much better understanding of what the number 5 represents. In EdgeX, Value Descriptors provide the context and unit of measure for any data (or values) sent to and from a device. As the name implies, a Value Descriptor describes a value - it's unit of measure, its minimum and maximum values (if there are any), the way to display the value when showing it on the screen, and more. Any data obtained from a device (we call this a GET from the device) or any data sent to the device for actuation (we call this SET or PUT to the device) requires a Value Descriptor to be associated with that data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Device profile: The device profile describes a type of device within the EdgeX system. Each device managed by a device service has an association with a device profile, which defines that device type in terms of the operations which it supports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Device definition: Device information like manufacturers, a protocol which it will use, device profile, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CoreData Service Workflow: Data is submitted to core data as an &lt;code&gt;Event&lt;/code&gt; object. An event is a collection of sensor readings from a device (associated with a device by its ID or name) at a particular point in time. A &lt;code&gt;Reading&lt;/code&gt; object in an &lt;code&gt;Event&lt;/code&gt; object is a particular value sensed by the device and associated with a Value Descriptor in order to provide context to the reading.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application Service Workflow: Application Services are a means to get data from EdgeX Foundry to external systems and processes (be it analytics package, enterprise or on-prem application, cloud systems like Azure IoT, AWS IoT, or Google IoT Core, etc.). Application Services provide the means for data to be prepared (transformed, enriched, filtered, etc.) and groomed (formatted, compressed, encrypted, etc.) before being sent to an endpoint of choice. Endpoints supported out of the box today include HTTP and MQTT endpoints, but will include additional offerings in the future and could include custom endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let's see it in action
&lt;/h3&gt;

&lt;p&gt;Trigger the script to activate the DHT sensor and send the temperature values to the EdgeX Foundry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python rpiPutTempHum.py 
Temp: 27.7999992371C, humidity: 77.5%
Temp: 28.2000007629C, humidity: 75.5999984741%
Temp: 28.1000003815C, humidity: 75.5%
Temp: 28.1000003815C, humidity: 75.4000015259%
Temp: 28.2000007629C, humidity: 75.3000030518%
Temp: 28.2000007629C, humidity: 75.3000030518%
Temp: 28.2000007629C, humidity: 75.3000030518%

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

&lt;/div&gt;



&lt;p&gt;As the sensor readings increase, the event count in the EdgeX Foundry also increases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;└─ &lt;span class="nv"&gt;$ &lt;/span&gt;▶ curl http://192.168.1.179:31931/api/v1/event/count
2043
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also get the latest temperature value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;└─ &lt;span class="nv"&gt;$ &lt;/span&gt;▶ curl http://192.168.1.179:31931/api/v1/reading | json_pp &lt;span class="nt"&gt;-json_opt&lt;/span&gt; pretty,canonical | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 10

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  396k    0  396k    0     0  9660k      0 &lt;span class="nt"&gt;--&lt;/span&gt;:--:-- &lt;span class="nt"&gt;--&lt;/span&gt;:--:-- &lt;span class="nt"&gt;--&lt;/span&gt;:--:-- 9660k
   &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"created"&lt;/span&gt; : 1632159295863,
      &lt;span class="s2"&gt;"device"&lt;/span&gt; : &lt;span class="s2"&gt;"Temp_and_Humidity_sensor_cluster_01"&lt;/span&gt;,
      &lt;span class="s2"&gt;"id"&lt;/span&gt; : &lt;span class="s2"&gt;"ffcf2a3b-6ecc-4476-9ab6-e17ae983886f"&lt;/span&gt;,
      &lt;span class="s2"&gt;"name"&lt;/span&gt; : &lt;span class="s2"&gt;"temperature"&lt;/span&gt;,
      &lt;span class="s2"&gt;"origin"&lt;/span&gt; : 1632159295861600937,
      &lt;span class="s2"&gt;"value"&lt;/span&gt; : &lt;span class="s2"&gt;"28"&lt;/span&gt;,
      &lt;span class="s2"&gt;"valueType"&lt;/span&gt; : &lt;span class="s2"&gt;"Int64"&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To have a demo of Application services, we will configure Application-Mqtt-service to send the temperature values to the MQTT broker. The &lt;code&gt;edgex-app-service-configurable-mqtt&lt;/code&gt; service (check the deployed services in section 'EdgeX Foundry on K3s') is a community-provided exporter that sends EdgeX sensor data to the public MQTT broker hosted by HiveMQ at (&lt;a href="http://broker.mqttdashboard.com"&gt;http://broker.mqttdashboard.com&lt;/a&gt;) on port 1883. This sensor data can then be visualized via HiveMQ provided MQTT browser client by publishing and subscribing to a particular &lt;code&gt;topic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The topic name is configured in the env variables of &lt;code&gt;edgex-app-service-configurable-mqtt&lt;/code&gt; deployment (&lt;a href="https://github.com/rutu-k/edgex-k3s/blob/25d9bff61f2dbdd6865586c5ee946b82ce95fb5d/k3s/app-service-mqtt-deployment.yaml#L65"&gt;refer here&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WRITABLE_PIPELINE_FUNCTIONS_MQTTSEND_ADDRESSABLE_TOPIC&lt;/span&gt;
    &lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DHT-SENSOR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to &lt;a href="http://www.hivemq.com/demos/websocket-client/"&gt;HiveMQ MQTT browser client&lt;/a&gt;. Click &lt;code&gt;Connect&lt;/code&gt; with default configuration. Next, click on &lt;code&gt;Add New Topic Subscription&lt;/code&gt;, type the topic name &lt;code&gt;DHT-SENSOR&lt;/code&gt; and click on &lt;code&gt;Subscribe&lt;/code&gt;. You will see the sensor data in Messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FTShEl-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0fi5f00a7st2lefo7nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FTShEl-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0fi5f00a7st2lefo7nt.png" alt="Fig. 4 showing HiveMQ web client" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we have seen the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to deploy K3s?&lt;/li&gt;
&lt;li&gt;How to convert docker-compose manifest to Kubernetes manifest?&lt;/li&gt;
&lt;li&gt;How to deploy EdgeX Foundry on K3s?&lt;/li&gt;
&lt;li&gt;How to send sensor data from Raspberry Pi to EdgeX Foundry?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, we have seen how to process the data that is received from the sensors. We can also take pre-defined actions by further analyzing the data. EdgeX Foundry provides support for Edge analytics by incorporating &lt;code&gt;eKuiper&lt;/code&gt; rules engine. We will try to cover it in the next part.&lt;/p&gt;

&lt;p&gt;I hope you found this post informative and engaging. For more posts like this one, do subscribe to our weekly newsletter. I’d love to hear your thoughts on this post, so do start a conversation on &lt;a href="https://www.twitter.com/rutu_kadikar"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/ruturaj-kadikar/"&gt;LinkedIn&lt;/a&gt; :).&lt;/p&gt;

&lt;h3&gt;
  
  
  References and further reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.edgexfoundry.org/1.2/walk-through/Ch-WalkthroughData/#value-descriptors"&gt;Value Descriptors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.edgexfoundry.org/1.2/microservices/device/profile/Ch-DeviceProfile/"&gt;Device Profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.edgexfoundry.org/1.2/general/Definitions/"&gt;EdgeX Foundry definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://k3s.io/"&gt;K3s&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>edge</category>
      <category>5g</category>
      <category>microservices</category>
    </item>
    <item>
      <title>EdgeX Foundry on K3s - the Inception</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Wed, 24 Nov 2021 18:32:14 +0000</pubDate>
      <link>https://dev.to/infracloud/edgex-foundry-on-k3s-the-inception-3d4n</link>
      <guid>https://dev.to/infracloud/edgex-foundry-on-k3s-the-inception-3d4n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This blog post is part 1 of a series of articles about how to deploy and operate EdgeX Foundry - an open source software framework for IoT Edge on K3s - a lightweight, highly available, and secured orchestrator.&lt;/em&gt;&lt;/p&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why emphasize on the Edge?
&lt;/h2&gt;

&lt;p&gt;As we start using the edge computing in its true sense, I think we are approaching the edge of the technological renaissance. The Edge is becoming an essential element of all the upcoming and futuristic technologies. Some of the popular examples would be as shown in Fig. 1:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edge is a complementary solution to 5G.&lt;/li&gt;
&lt;li&gt;Edge is the backbone for IoT and Fog.&lt;/li&gt;
&lt;li&gt;Edge is required for AI and ML workloads to enable real-time data processing.&lt;/li&gt;
&lt;li&gt;Automated vehicles leverage the Edge for mission-critical latency and high reliability.&lt;/li&gt;
&lt;li&gt;VR applications needs the Edge for stringent requirements of latency, network and reliability.&lt;/li&gt;
&lt;li&gt;Edge will conserve broadband networks while streaming of global events.&lt;/li&gt;
&lt;li&gt;Software upgrades can use the Edge to minimize network pressure on backhaul.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lk29MRhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqukiub0umbmn1y3l5zx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lk29MRhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqukiub0umbmn1y3l5zx.png" width="500" height="339"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;b&gt;Fig. 1 - Showing the 5G stack&lt;/b&gt;



&lt;p&gt;The major issues which are common in all the above areas are minimum latency requirement and high network availability. These two issues are exacerbated in the case of traditional cloud-based architectures as it is a centralized architecture.&lt;br&gt;
Edge plays an important role in alleviating the two pressure points by distributing data processing, thus being an essential part of all the technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look for while exploring Edge?
&lt;/h2&gt;

&lt;p&gt;Edge is primarily an application or use case driven strategy. Thus it's implementation changes according to the use case and the underlying issues (e.g latency, network bandwidth, scalability, security, etc.). This is also true for the adoption of 5G. Industries are formulating new tools and technologies to adopt 5G in various areas such as IoT, IIoT, entertainment, and more. This is the correct stage for choosing the correct path for implementation and formulating the standards that will help to onboard future technologies.&lt;/p&gt;

&lt;p&gt;Linux Foundation initiated two open communities namely, LF Networking and LF Edge. These communities provide an ecosystem for network infrastructure and services as well as an interoperable framework for the Edge computing respectively. Furthermore, LF Networking integrates with LF Edge to provide an open source Edge framework and seamless Edge networking. But out of these one thing that caught my attention and triggered me to explore this further was the 5G Super Blueprint initiative. &lt;/p&gt;

&lt;p&gt;As we have learned so far, all the upcoming technologies desperately need low-latency, high-bandwidth, and scalable networks. To address all these issues, LF Networking announced 5G Super Blueprint (see Fig. 2), a community-driven integration/illustration of multiple open source initiatives coming together to show end-to-end use cases demonstrating implementation architectures for end users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--76hgxkWu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdae3fm7mnku4q9xjjty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--76hgxkWu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdae3fm7mnku4q9xjjty.png" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;b&gt;Fig. 2 - 5G Super Blueprint, Courtesy: &lt;a href="https://www.lfnetworking.org/5g-super-blueprint/"&gt;Linux Foundation&lt;/a&gt;&lt;/b&gt;



&lt;h3&gt;
  
  
  User Edge (UE)
&lt;/h3&gt;

&lt;p&gt;As you can see 5G Super Blueprint is mainly divided into three sections. The first section named User Edge is also considered as the last mile network. It deals with the applications which are closer to end-users. It uses on-prem and distributed compute resources to reduce latency. It also lowers the pressure on the broadband networks by minimizing the unnecessary backhaul communication to the data centers. In addition to it, we also achieve autonomy, increased security and privacy, and a reduction in overall cost. The business model that applications use in UE is generally based on CAPEX as infrastructure and its operation is handled by the user rather than delivered as managed service. &lt;/p&gt;

&lt;h3&gt;
  
  
  Service Provider Edge (SPE)
&lt;/h3&gt;

&lt;p&gt;In contrast to UE, SPE is distributed yet a shared space and is primarily consumed as a service. It is considered to be more secured and private as compared to cloud as it uses private networks (both wired and wireless/cellular) operated by service providers. It is more standardized than UE, but it also has unique requirements according to the use case and location.&lt;/p&gt;

&lt;h3&gt;
  
  
  5G Core
&lt;/h3&gt;

&lt;p&gt;The core of 5G Blueprint consists of tools that provide open cloud native 5G network functions. Cloud infrastructure that adheres to the 5G principles and is able to provision these 5G functions (e.g. network accelerators, vector packet processors, etc.). It also consists of a management plane that offers to orchestrate, automate, and manage the lifecycle of network functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Edge native similar to cloud native?
&lt;/h3&gt;

&lt;p&gt;No, there is a slight difference. Edge native applications leverage cloud native principles while taking into account the unique characteristics of the Edge in areas such as resource constraints, security, latency, and autonomy. Edge native applications are developed in ways that leverage the cloud and work in concert with upstream resources. Edge applications that don’t comprehend centralized cloud compute resources, remote management, and orchestration or leverage CI/CD aren’t truly “edge native”, rather they more closely resemble traditional on-premises applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why EdgeX Foundry?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Covers both UE and SPE in 5G Super Blueprint
&lt;/h3&gt;

&lt;p&gt;The first reason why I started my exploration in the Edge with EdgeX Foundry is that it was an overlapping project in UE and SPE space. It means that you can use it in UE or in SPE or a combination of both. To understand how it is possible, let's dive into its architecture. &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kw2NDnH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipuwkvvpjwx731yxed6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kw2NDnH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipuwkvvpjwx731yxed6y.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;b&gt;Fig. 3 - EdgeX architecture, Courtesy: &lt;a href="https://docs.edgexfoundry.org/2.0/#edgex-foundry-service-layers"&gt;EdgeX Foundry&lt;/a&gt;&lt;/b&gt;&lt;br&gt;



&lt;p&gt;As you can see in Fig. 3, EdgeX Foundry is primarily divided into 4 layers which are briefly described as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Device Services&lt;/strong&gt;: Responsible for interacting with the Edge devices and connecting with the other services.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Core Services:&lt;/strong&gt; It is mainly responsible for handling the device information and data processing. It consists of following services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Core data:&lt;/em&gt;&lt;/strong&gt; a persistence repository and associated management service for data collected from south side objects.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;em&gt;Command:&lt;/em&gt;&lt;/strong&gt; a service that facilitates and controls actuation requests from the north side to the south side.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;em&gt;Metadata:&lt;/em&gt;&lt;/strong&gt; a repository and associated management service of metadata about the objects that are connected to EdgeX Foundry. Metadata provides the capability to provision new devices and pair them with their owning device services.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;Registry and Configuration:&lt;/em&gt;&lt;/strong&gt; provides other EdgeX Foundry micro services with information about associated services within EdgeX Foundry and micro services configuration properties (i.e. - a repository of initialization values).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Supporting services (Optional):&lt;/strong&gt; The supporting services encompass a wide range of micro services to include the Edge analytics (also known as local analytics). They are mainly responsible for logging, scheduling, and data clean up (also known as scrubbing in EdgeX).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Rules Engine:&lt;/em&gt;&lt;/strong&gt; the reference implementation of Edge analytics service that performs if-then conditional actuation at the Edge, based on sensor data collected by the EdgeX instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Scheduling:&lt;/em&gt;&lt;/strong&gt; an internal EdgeX “clock” that can kick off operations in any EdgeX service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Logging:&lt;/em&gt;&lt;/strong&gt; provides a central logging facility for all of EdgeX services. Services send log entries into the logging facility via a REST API where log entries can be persisted in a database or log file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Alerts and Notifications:&lt;/em&gt;&lt;/strong&gt; provides EdgeX services with a central facility to send out an alert or notification.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application services:&lt;/strong&gt; Application services are the means to extract, process/transform and send sensed data from EdgeX to an endpoint or process of your choice. They also send data to many of the major cloud providers (Amazon IoT Hub, Google IoT Core, Azure IoT Hub, IBM Watson IoT…), to MQTT(s) topics, and HTTP(s) REST endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The placement of these services defines whether the EdgeX Foundry implementation is either on UE or SPE. The following diagram (see Fig.4) describes this placement in detail.&lt;/p&gt;

&lt;p&gt;The loosely coupled architecture and the microservices design enable the deployment of its services in various combinations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--msI110E_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nk0papmxm8l3dm0tg42y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--msI110E_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nk0papmxm8l3dm0tg42y.png" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;b&gt;Fig. 4 - EdgeX implementation strategies, Courtesy: &lt;a href="https://docs.edgexfoundry.org/2.0/#deployments"&gt;EdgeX Foundry&lt;/a&gt;&lt;/b&gt;



&lt;h3&gt;
  
  
  Graduated to Impact Stage in LF Edge projects
&lt;/h3&gt;

&lt;p&gt;Coming back to the reason starting with EdgeX Foundry, it is currently in Stage 3 of the LF Edge's Project Lifecycle Document (PLD) process. All new projects enter as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage 1 “At Large” are the projects which the TAC believes are, or have the potential to be, important to the ecosystem of Top-Level Projects, or the Edge ecosystem as a whole. &lt;/li&gt;
&lt;li&gt;The second “Growth Stage” is for projects that are interested in reaching the Impact Stage, and have identified a growth plan for doing so. &lt;/li&gt;
&lt;li&gt;Finally, the third “Impact Stage” is for projects that have reached their growth goals and are now on a self-sustaining cycle of development, maintenance, and long-term support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VSoQjv21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzuxfu7gjs1h2ixbrkei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VSoQjv21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzuxfu7gjs1h2ixbrkei.png" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;b&gt;Fig. 5 - LF Edge Project Lifecycle Document, Courtesy: &lt;a href="https://www.lfedge.org/projects/"&gt;LF Edge&lt;/a&gt;&lt;/b&gt;



&lt;h3&gt;
  
  
  Why K3s?
&lt;/h3&gt;

&lt;p&gt;While working in Edge, you require a lightweight, resource-constraint, and highly available orchestrator to manage Edge native applications. There are many options available like &lt;a href="https://github.com/kubernetes/minikube"&gt;minikube&lt;/a&gt;, &lt;a href="https://github.com/kubernetes-sigs/kind"&gt;kind&lt;/a&gt;, &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;, &lt;a href="https://k3s.io/"&gt;K3s&lt;/a&gt;, and &lt;a href="https://microk8s.io/"&gt;MicroK8s&lt;/a&gt;. Although minikube and kind are popular tools for hands-on or demo purposes, they are not production-compliant. Kubernetes is a good option for the orchestration of the Edge native microservices. K3s and MicroK8s are lightweight variants of Kubernetes which are more suitable for the Edge scenarios. Both of them can be deployed on small devices like Raspberry-Pis and also on AWS instances. K3s is Linux distribution independent and follows the multi-node architecture. Due to these reasons, we are focusing on K3s for deploying EdgeX Foundry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we have seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the Edge is necessary for upcoming technologies?&lt;/li&gt;
&lt;li&gt;How Linux Foundation is contributing to Open Source Edge and Networking?&lt;/li&gt;
&lt;li&gt;What is EdgeX Foundry?&lt;/li&gt;
&lt;li&gt;How K3s is complementary for the Edge?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you found this post informative and engaging. Stay tuned for the part 2 of this post where we explore how to deploy EdgeX Foundry on K3s and how to send sensor data from Raspberry Pi to EdgeX Foundry.&lt;/p&gt;

&lt;p&gt;For more posts like this one, do subscribe to our weekly newsletter. I’d love to hear your thoughts on this post, so do start a conversation on &lt;a href="https://www.twitter.com/infracloudio"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/company/infracloudio"&gt;LinkedIn&lt;/a&gt; :).&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://enterprisersproject.com/article/2021/6/edge-computing-and-5g-reality-check"&gt;Edge computing and 5G: A reality check&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.akamai.com/2021/03/the-edge-is-becoming-more-critical-in-a-world-of-5g-and-iot.html"&gt;The Edge is Becoming More Critical in a World of 5G and IoT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stlpartners.com/edge_computing/5g-edge-computing/"&gt;Where does Edge computing work with 5G?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/solutions/enterprise-networks/edge-computing-architecture-5g.html"&gt;5G technology needs Edge computing architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ciena.com/insights/articles/the-ying-and-yang-of-5g-and-edge-cloud.html"&gt;The Yin and Yang of 5G and Edge Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.lfnetworking.org/display/LN/LFN+Demo:+5G+Super+Blueprint"&gt;LF 5G Super Blueprint&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>edge</category>
      <category>5g</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Avoiding Kubernetes Cluster Outages with Synthetic Monitoring</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Tue, 22 Jun 2021 10:15:48 +0000</pubDate>
      <link>https://dev.to/infracloud/avoiding-kubernetes-cluster-outages-with-synthetic-monitoring-4o90</link>
      <guid>https://dev.to/infracloud/avoiding-kubernetes-cluster-outages-with-synthetic-monitoring-4o90</guid>
      <description>&lt;h2&gt;
  
  
  What is synthetic monitoring?
&lt;/h2&gt;

&lt;p&gt;Synthetic monitoring consists of pre-defined checks to proactively monitor the critical elements in your infrastructure. These checks simulate the functionality of the elements. We can also simulate the communication between the elements to ensure end-to-end connectivity. Continuous monitoring of these checks also helps to measure overall performance in terms of availability and response times.&lt;/p&gt;

&lt;p&gt;We will narrow down the scope of synthetic checks for Kubernetes clusters and the rest of the post will be based on the same.&lt;/p&gt;

&lt;p&gt;Synthetic checks can help SREs identify issues, and determine the slow responses and downtime before it affects the actual business. It may help to proactively detect network failures, misconfigurations, loss of end-to-end connectivity, etc., during upgrades, major architectural changes, or any feature releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why synthetic checks are important in Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Kubernetes is a collection of distributed processes running simultaneously. Thus, identifying the failure domains in a Kubernetes cluster can be a troublesome task. A well-described synthetic check can reduce/avoid the possible downtime due to these failure domains by replicating the intended workflow and measuring its performance. Some failure domains can be described as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node issues (Docker daemon/Kubelet in a failed state, unallocated IP address due to CNI failures, etc.).&lt;/li&gt;
&lt;li&gt;Pod issues (failed health checks, pods not in running state, etc.)&lt;/li&gt;
&lt;li&gt;Namespace issues (pods not able to schedule in a Namespace)&lt;/li&gt;
&lt;li&gt;DNS resolution issues (CoreDNS lookup failures)&lt;/li&gt;
&lt;li&gt;Network issues (changes in Network policies, etc.)&lt;/li&gt;
&lt;li&gt;And many more ...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools available for Kubernetes synthetic checks/monitoring
&lt;/h2&gt;

&lt;p&gt;There are &lt;a href="https://geekflare.com/synthetic-monitoring-tools/"&gt;multiple tools available for synthetic monitoring,&lt;/a&gt; such as AppDynamics, New Relic, Dynatrace, etc.. For this post, let's focus on the Kubernetes native synthetic checks.&lt;/p&gt;

&lt;p&gt;At the time of writing this post, two tools have Kubernetes native synthetic checks namely &lt;strong&gt;Kuberhealthy&lt;/strong&gt; and &lt;strong&gt;Grafana Cloud&lt;/strong&gt;. &lt;a href="https://github.com/kuberhealthy/kuberhealthy"&gt;Kuberhealthy&lt;/a&gt; is an operator-based synthetic monitoring tool that uses custom resources called Kuberhealthy checks (khchecks), while Grafana cloud uses agents to gather data from the probes that periodically check the pre-defined endpoints. Kuberhealthy provides a lot more synthetic checks in comparison to Grafana Cloud and also it is an open-source option too. Thus, we will explore synthetic monitoring in the Kubernetes clusters with the help of Kuberhealthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kuberhealthy?
&lt;/h2&gt;

&lt;p&gt;Kuberhealthy is an operator for running synthetic checks. Each synthetic check is a test container (a checker pod) created by a custom resource called khcheck/khjob (Kuberhealthy check/Kuberhealthy job). Once the checks are created, Kuberhealthy schedules all the checks at a given interval and within a given timeout. Synthetic checks are defined in the form of khcheck or khjob. Both custom resources are almost same in functionality except that khjob runs one time whereas khcheck runs at regular intervals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6r8L2rmT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxpsh6celg5al5ws7u94.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6r8L2rmT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxpsh6celg5al5ws7u94.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
Deployment check [Courtesy: Kuberhealthy]
&lt;/p&gt;

&lt;p&gt;Kuberhealthy provisions checker pods corresponding to a particular khcheck. The checker pod is destroyed once the purpose is served. The creation/deletion cycle repeats at regular intervals depending upon the duration of &lt;code&gt;runInterval&lt;/code&gt;/&lt;code&gt;timeout&lt;/code&gt; respectively in a khcheck configuration. The result is then sent to the Kuberhealthy, that in turn sends it to the metrics and status endpoints. For monitoring, we can integrate it with Prometheus, or view it on JSON based status page. This page gives a consolidated status of all the khchecks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checks available with Kuberhealthy
&lt;/h3&gt;

&lt;p&gt;There are pre-defined checks available which check for core Kubernetes functions. We can use the checks provided directly by Kuberhealthy or we can also write our own custom checks according to the use case.&lt;/p&gt;

&lt;p&gt;Here is one example of a khcheck. Any application performing CRUD operations on a database/storage needs to have a constant connection with it. Kuberhealthy HTTP check helps to check the connectivity of HTTP/HTTPS endpoints. For example, the following khcheck checks for reachability of MinIO cluster. For simulating the realistic scenario, MinIO is exposed via ngrok. If the connection is successful, it will show &lt;code&gt;OK: true&lt;/code&gt; else if the connection breaks, it will show &lt;code&gt;OK: false&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;comcast.github.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;KuberhealthyCheck&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a-minio-reachable&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kuberhealthy&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;runInterval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2m&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2m&lt;/span&gt;
  &lt;span class="na"&gt;podSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a-minio-reachable&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kuberhealthy/http-check:v1.5.0&lt;/span&gt;
        &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;IfNotPresent&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CHECK_URL&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://ff333084d5a0.ngrok.io/login"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;COUNT&lt;/span&gt; &lt;span class="c1"&gt;#### default: "0"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SECONDS&lt;/span&gt; &lt;span class="c1"&gt;#### default: "0"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PASSING_PERCENT&lt;/span&gt; &lt;span class="c1"&gt;#### default: "100"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;REQUEST_TYPE&lt;/span&gt; &lt;span class="c1"&gt;#### default: "GET"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EXPECTED_STATUS_CODE&lt;/span&gt; &lt;span class="c1"&gt;#### default: "200"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;200"&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15m&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15Mi&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;25m&lt;/span&gt;
    &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
    &lt;span class="na"&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OoEp88LQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2356ehpi7htbxlwjv1v5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OoEp88LQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2356ehpi7htbxlwjv1v5.png" alt="Kuberhealthy Status Page" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of the important uses are mentioned in the following section.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we avoided a major outage in a Kubernetes cluster?
&lt;/h2&gt;

&lt;p&gt;We started facing IP address shortages as the Kubernetes cluster deployed in AWS began to grow with a large number of micro-services being onboarded on it. The issue would become more serious during burst scaling or upgrades. The feasible solution was to incorporate the secondary CIDR solution provided by AWS. However, this required a lot of network changes. A small mistake could result in a major outage.&lt;/p&gt;

&lt;p&gt;We wanted a solution, that will buy us some time to identify misconfigurations (if any) during the rollout of the solution. We identified all the endpoints of the dependent services for all the micro-services. We created respective TCP and HTTP khchecks and installed Kuberhealthy along with the khcheck manifest. The following image shows the setup before rolling out secondary CIDR. All the pods can connect to the dependent services. &lt;br&gt;
(Note that the diagram is a minimalistic version of the scenario.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7-XqRNx6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/su1hcd7633ksrw075uij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7-XqRNx6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/su1hcd7633ksrw075uij.png" alt="Secondary CIDR rollout step 1" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now during the rollout, we wanted to ensure that everything will work fine with the new Pod IP address (100.64.x.x). Thus, we manually added one new node in the cluster which uses the secondary CIDR. khcheck placed a Daemonset on the new node and checked the connectivity with all the endpoints. We realized that some of the endpoints were unable to connect. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QwcEdQgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l3bcivq26ef4t50v5nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QwcEdQgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l3bcivq26ef4t50v5nn.png" alt="Secondary CIDR rollout step 2" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We checked the required whitelisting in Security Groups, NACLs, and WAFs, and found out that the new CIDR is not whitelisted in some of the WAFs. We corrected the WAF configuration accordingly and the khchecks showed status OK. Then we proceed with the actual secondary CIDR rollout and everything worked fine as shown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PinSdHIg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24plu1x38dm2f3t07jmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PinSdHIg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24plu1x38dm2f3t07jmt.png" alt="Secondary CIDR rollout step 3" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, we safeguarded our Kubernetes cluster from a major outage with the help of Kuberhealthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases for Kuberhealthy synthetic checks
&lt;/h2&gt;

&lt;p&gt;We explored and found out that Kuberhealthy can help in the following use cases to make a Kubernetes cluster more reliable:&lt;/p&gt;

&lt;h3&gt;
  
  
  Network changes
&lt;/h3&gt;

&lt;p&gt;If there are major network changes you have to carry out, then having some checks on important endpoints using HTTP or TCP khchecks might help to find any misconfigurations and avoid major downtime proactively.&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM changes
&lt;/h3&gt;

&lt;p&gt;Kuberhealthy has KIAM checks in order to verify proper KIAM functionality. This concept can further be extended to any production-grade cluster that has to be stringent on the workloads' IAM access. While hardening the access, the security team might block the required access, which may lead to downtime. Having appropriate IAM checks helps minimize downtime (KIAM checks, in case you use KIAM in your cluster). &lt;/p&gt;

&lt;p&gt;Additionally, we can also check unnecessary access. We can modify the khchecks to always check for the full access or power user access and alert if anybody provides this access to any workload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Endpoint connectivity
&lt;/h3&gt;

&lt;p&gt;We can always check whether the important elements outside the cluster such as databases, Key-Value stores are up and running with khchecks monitoring the connectivity with their respective endpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  AMI verification
&lt;/h3&gt;

&lt;p&gt;There is a predefined AMI check that verifies the AMI used in the cluster exists in the Amazon marketplace. We can modify the AMI check to verify the important features in a custom-baked AMI like NTP synchronization, directory structures, user access, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  CoreDNS checks
&lt;/h3&gt;

&lt;p&gt;An improper CoreDNS configuration may hamper the DNS resolution at heavy loads. Hence, a DNS check can provide the status of DNS resolution both internal and external in such scenarios. To know more on this, follow this guide on &lt;a href="https://dev.to/blogs/using-coredns-effectively-kubernetes/"&gt;how to effectively use CoreDNS with Kubernetes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Quotas checks
&lt;/h3&gt;

&lt;p&gt;Resource Quotas check is another helpful check which should be running in a production-grade cluster enabled with resource quotas. Suppose the resource quota of a particular namespace is exhausted due to scaling at peak loads. New pods required to serve the additional load won’t be able to be placed in the namespace, which in turn will affect the business in that duration.&lt;/p&gt;

&lt;p&gt;These use cases are a few of many that are observed generally. You can have your use cases according to your infrastructure and write your checks for the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article covered the following points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is synthetic monitoring and its importance in production-grade clusters?&lt;/li&gt;
&lt;li&gt;Why synthetic checks are important for Kubernetes cluster?&lt;/li&gt;
&lt;li&gt;What is Kuberhealthy?&lt;/li&gt;
&lt;li&gt;How we safeguarded the Kubernetes cluster from a major outage?&lt;/li&gt;
&lt;li&gt;What are some of the important use cases of synthetic checks with Kuberhealthy?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To sum it up, this post introduced you to Kuberhealthy tool for synthetic monitoring of a Kubernetes cluster in order to avoid outages and increase infrastructure reliability.&lt;/p&gt;

&lt;p&gt;Hope this article was helpful to you and in case you have any further queries, please feel free to start a conversation with me on &lt;a href="https://twitter.com/rutu_kadikar"&gt;Twitter&lt;/a&gt;. Happy Coding :)&lt;/p&gt;

&lt;h3&gt;
  
  
  References and further reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2020/05/29/k8s-kpis-with-kuberhealthy/"&gt;https://kubernetes.io/blog/2020/05/29/k8s-kpis-with-kuberhealthy/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/news/2019/05/kuberhealthy-synthetic-testing/"&gt;https://www.infoq.com/news/2019/05/kuberhealthy-synthetic-testing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opensource.com/article/19/4/kuberhealthy"&gt;https://opensource.com/article/19/4/kuberhealthy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grepmymind.com/kuberhealthy-the-writing-the-ami-exists-check-c9e986298e4"&gt;https://grepmymind.com/kuberhealthy-the-writing-the-ami-exists-check-c9e986298e4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/box-tech-blog/a-trip-down-the-dns-rabbit-hole-understanding-the-role-of-kubernetes-golang-libc-systemd-41fd80ffd679"&gt;https://medium.com/box-tech-blog/a-trip-down-the-dns-rabbit-hole-understanding-the-role-of-kubernetes-golang-libc-systemd-41fd80ffd679&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://geekflare.com/synthetic-monitoring-tools/"&gt;https://geekflare.com/synthetic-monitoring-tools/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>syntheticmonitoring</category>
      <category>kuberhealthy</category>
      <category>devops</category>
    </item>
    <item>
      <title>Tracing in Grafana with Tempo and Jaeger</title>
      <dc:creator>Ruturaj Kadikar</dc:creator>
      <pubDate>Fri, 23 Apr 2021 18:02:15 +0000</pubDate>
      <link>https://dev.to/infracloud/tracing-in-grafana-with-tempo-and-jaeger-ec</link>
      <guid>https://dev.to/infracloud/tracing-in-grafana-with-tempo-and-jaeger-ec</guid>
      <description>&lt;h2&gt;
  
  
  Why do I need tracing if I have a good logging and monitoring framework?
&lt;/h2&gt;

&lt;p&gt;Application logs are beneficial for displaying important events if something is not working as expected (failure, error, incorrect config, etc.). Although it is a very crucial element in application design, one should log thriftily. This is because log collection, transformation, and storage are costly. &lt;/p&gt;

&lt;p&gt;Unlike logging, which is event triggered and discrete, tracing provides a broader and continuous application view. Tracing helps us understand the path of a process/transaction/entity while traversing the application stack and identifying the bottlenecks at various stages. This helps to optimize the application and increase performance. &lt;/p&gt;

&lt;p&gt;In this post, we will see how to introduce tracing in logs and visualize it easily. In this example, we will use Prometheus, Grafana Loki, Jaeger, and Grafana Tempo as datasources for monitoring metrics, logs, and traces respectively in Grafana. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Distributed-tracing?
&lt;/h2&gt;

&lt;p&gt;In a microservices architecture, understanding an application behavior can be an intriguing task. This is because the incoming requests may span over multiple services, and each intermittent service may have one or more operations on that request. It thus increases complexity and takes more time while troubleshooting problems. &lt;/p&gt;

&lt;p&gt;Distributed tracing helps to get insight into the individual operation and pinpoint the areas of failure caused by poor performance. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is OpenTracing?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://opentracing.io/" rel="noopener noreferrer"&gt;OpenTracing&lt;/a&gt; comprises an API specification, frameworks, and libraries to enable distributed tracing in any application. OpenTracing APIs are very generic and prevents vendor/product lock-in. Recently, OpenTracing and OpenCensus merged to form &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt; (acronym OTel). It targets the creation and management of telemetry data such as traces, metrics, and logs through a set of APIs, SDKs, tooling, and integrations.&lt;br&gt;
Note: &lt;a href="https://opencensus.io/" rel="noopener noreferrer"&gt;OpenCensus&lt;/a&gt; consists of a set of libs for various languages to collect metrics and traces from Applications, visualize them locally and send them remotely for storage and analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the fundamental elements of OpenTracing?
&lt;/h2&gt;

&lt;p&gt;Span: It is a primary building block of a distributed trace. It comprises a name, start time, and duration. &lt;/p&gt;

&lt;p&gt;Trace: It is a visualization of a request/transaction as it traverses through a distributed system. &lt;/p&gt;

&lt;p&gt;Tags: It is key-value information for identifying a span. It helps to query, filter and analyze trace data. &lt;/p&gt;

&lt;p&gt;Logs: Logs are key-value pairs that are useful for capturing span-specific logging messages and other debugging or informational output from the application itself. &lt;/p&gt;

&lt;p&gt;Span-context: It is a process of association of certain data with the incoming request. This context is accessible in all other layers of the application within the same process. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are available tools compatible with OpenTracing?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://zipkin.io/" rel="noopener noreferrer"&gt;Zipkin&lt;/a&gt;&lt;/strong&gt;: It was one of the first distributed-tracing tools developed by Twitter, inspired by Google Dapper paper. Zipkin is coded in Java and supports Cassandra and ElasticSearch for backend scalability. &lt;/p&gt;

&lt;p&gt;It comprises clients or reporters to gather trace data, collectors to index and store the data, a query service to extract and retrieve the trace data, and UI to visualize the traces. Zipkin is compatible with the OpenTracing standard, so these implementations should also work with other distributed tracing systems. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/strong&gt;: Jaeger is another OpenTracing compatible project from Uber Technologies written in Go. Jaeger also supports Cassandra and ElasticSearch as scalable backend solutions. Although its architecture is like Zipkin, it comprises an additional agent on each host to aggregate data in batches before sending it to the collector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/sourcegraph/appdash" rel="noopener noreferrer"&gt;Appdash&lt;/a&gt;&lt;/strong&gt;: Appdash, created by Sourcegraph, is another distributed tracing system written in Go. It also supports the OpenTracing standard. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://grafana.com/oss/tempo/" rel="noopener noreferrer"&gt;Grafana Tempo&lt;/a&gt;&lt;/strong&gt;: Tempo is an open source, highly scalable distributed tracing backend option. We can easily integrate it with Grafana, Loki, and Prometheus. It only requires object storage and is compatible with other open tracing protocols like Jaeger, Zipkin, and OpenTelemetry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling and Visualizing Traces
&lt;/h2&gt;

&lt;p&gt;There are many hands-on tutorials/demos available, but they exist for the docker-compose environment. We will run a tracing example in a Kubernetes environment. We will take the classic example provided by Jaeger, i.e., HOTROD. Although Jaeger has its own UI to visualize traces, we will visualize it in Grafana with Jaeger as a data source. Similarly, we will also see how Grafana Tempo is useful for visualizing the traces.&lt;/p&gt;

&lt;p&gt;For getting started we will clone the Jaeger GitHub repo.&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/jaegertracing/jaeger.git


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Enable distributed tracing in Microservice application
&lt;/h3&gt;

&lt;p&gt;You can check how to enable OpenTracing by navigating through the repo as shown below.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cd jaeger/examples/hotrod
cat pkg/log/factory.go


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;opentracing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SpanFromContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;spanLogger&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;jaegerCtx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaeger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SpanContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spanFields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;zapcore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;zap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"trace_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jaegerCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TraceID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
                &lt;span class="n"&gt;zap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"span_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jaegerCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SpanID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Convert docker-compose manifest to Kubernetes manifest
&lt;/h3&gt;

&lt;p&gt;In the hotrod directory, check the existing Docker manifests.&lt;/p&gt;

&lt;p&gt;You will see the docker-compose.yml file deploying services like Jaeger and HOTROD. We will use &lt;a href="https://kompose.io/" rel="noopener noreferrer"&gt;kompose&lt;/a&gt; to convert docker-compose manifest to Kubernetes manifest.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

kompose convert


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

&lt;/div&gt;

&lt;p&gt;You will see some files being created. We are specifically interested in &lt;code&gt;hotrod-deployment.yaml&lt;/code&gt;, &lt;code&gt;hotrod-service.yaml&lt;/code&gt;, &lt;code&gt;jaeger-deployment.yaml&lt;/code&gt;, and &lt;code&gt;jaeger-service.yaml&lt;/code&gt;. For simplicity, we will add the following label in the hotrod-deployment manifest.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kompose.cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kompose convert&lt;/span&gt;
    &lt;span class="na"&gt;kompose.version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.21.0 (992df58d8)&lt;/span&gt;
  &lt;span class="na"&gt;creationTimestamp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hotrod&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hotrod&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hotrod&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Enable Jaeger tracing in deployment manifest
&lt;/h3&gt;

&lt;p&gt;Now we need to add the following environment variables in &lt;code&gt;hotrod-deployment.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JAEGER_AGENT_HOST&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tempo&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JAEGER_AGENT_PORT&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;6831"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JAEGER_SAMPLER_TYPE&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;const&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JAEGER_SAMPLER_PARAM&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JAEGER_TAGS&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app=hotrod&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jaegertracing/example-hotrod:latest&lt;/span&gt;
    &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hotrod&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;JAEGER_AGENT_HOST&lt;/code&gt;: It is a hostname to communicate with an agent (defaults to localhost).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JAEGER_AGENT_PORT&lt;/code&gt;: It is a port to communicate with an agent (defaults to 6831).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JAEGER_SAMPLER_TYPE&lt;/code&gt;: Four types are available remote, const, probabilistic, ratelimiting (defaults to remote). For example, const type refers to sampling decision for every trace.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JAEGER_SAMPLER_PARAM&lt;/code&gt;: It is a value between 0 to 1 (1 for sampling every trace and 0 for sampling none of them).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JAEGER_TAGS&lt;/code&gt;: It is a comma-separated list of name=value tracer-level tags, which get added to all reported spans.&lt;/p&gt;

&lt;p&gt;Now we will apply these manifests. Note that this will require a running Kubernetes cluster as a pre-requisite.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Prometheus and Loki
&lt;/h3&gt;

&lt;p&gt;Next, we install Prometheus, Loki, and Grafana. The Prometheus Operator Helm chart (&lt;a href="https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack" rel="noopener noreferrer"&gt;&lt;code&gt;kube-prometheus-stack&lt;/code&gt;&lt;/a&gt;) will install Prometheus and Grafana. Loki Helm chart (&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/loki-stack" rel="noopener noreferrer"&gt;&lt;code&gt;loki-stack&lt;/code&gt;&lt;/a&gt;) will install Loki and Promtail. This &lt;a href="https://www.infracloud.io/blogs/grafana-loki-log-monitoring-alerting/" rel="noopener noreferrer"&gt;post&lt;/a&gt; provides more details about log monitoring with Loki.&lt;/p&gt;

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

helm upgrade --install prometheus prometheus-community/kube-prometheus-stack
helm upgrade --install loki grafana/loki-stack


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

&lt;/div&gt;

&lt;p&gt;We need to add Jaeger and Loki data-sources in Grafana. You can achieve this by either manually adding it or having it in the code. We will have the latter one by creating a custom values file &lt;code&gt;prom-oper-values.yaml&lt;/code&gt; as shown below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;additionalDataSources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
      &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-loki&lt;/span&gt;
      &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;proxy&lt;/span&gt;
      &lt;span class="na"&gt;orgId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://loki:3100&lt;/span&gt;
      &lt;span class="na"&gt;basicAuth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;isDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jaeger&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jaeger&lt;/span&gt;
      &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-jaeger&lt;/span&gt;
      &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;browser&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://jaeger:16686&lt;/span&gt;
      &lt;span class="na"&gt;isDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;basicAuth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;uid&lt;/code&gt;: It is a unique user-defined id.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;access&lt;/code&gt;: It states whether the access is proxy or direct (server or browser).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isDefault&lt;/code&gt;: It sets a data-source to default.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;version&lt;/code&gt;: It helps in the versioning of the config file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;editable&lt;/code&gt;: It allows to update datasource from UI.&lt;/p&gt;

&lt;p&gt;We will now upgrade the kube-prometheus-stack Helm chart with the custom values.&lt;/p&gt;

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

helm upgrade --install prometheus prometheus-community/kube-prometheus-stack --values=prom-oper-values.yaml


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

&lt;/div&gt;

&lt;p&gt;If you go to the data-sources, you can see jaeger and loki added here. It's time to see how traces are being logged in the log message. For this, we will go to the HOTROD UI and trigger the request from there.&lt;/p&gt;

&lt;p&gt;Note: In our configuration, we have given the name &lt;code&gt;loki&lt;/code&gt; and &lt;code&gt;jaeger&lt;/code&gt; for the Loki and Jaeger data-sources respectively.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wqg66hvlorjkm36wror.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wqg66hvlorjkm36wror.png" alt="hotrod_query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Grafana and HOTROD services are using ClusterIP we will use port-forwarding to access the UI.&lt;/p&gt;

&lt;p&gt;Go to explore, select loki as a data-source, and select Log labels as &lt;code&gt;{app="hotrod"}&lt;/code&gt; to visualize the logs. You can see the span context containing info like trace and span id in JSON. Copy the trace id. Duplicate the window and go to explore, and select Jaeger as a data-source. Paste the trace id and run the query for visualizing all the traces of the request.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl60467uhl4q43ffslepz.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl60467uhl4q43ffslepz.png" alt="visualize_trace_initial"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Loki Derived Fields
&lt;/h3&gt;

&lt;p&gt;This technique won’t be effective while analyzing burst requests. We need something that will be more efficient and easy to operate. For this, we will use the concept of Loki derived fields. Derived fields allow us to add a parsed field from the log message. We can add a URL comprising the value of the parsed field. Let’s see how this does the trick, but first, add the following config in the &lt;code&gt;prom-oper-values.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loki&lt;/span&gt;
  &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;proxy&lt;/span&gt;
  &lt;span class="na"&gt;orgId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://loki:3100&lt;/span&gt;
  &lt;span class="na"&gt;basicAuth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;isDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;jsonData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;derivedFields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;datasourceUid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-jaeger&lt;/span&gt;
      &lt;span class="na"&gt;matcherRegex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;((\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+)(\d+|[a-z]+))&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$${__value.raw}'&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TraceID&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Note that &lt;code&gt;datasourceUid&lt;/code&gt; has the value of Jaeger’s &lt;code&gt;uid&lt;/code&gt;. This will help identify the data-source while creating the internal link. &lt;code&gt;matcherRegex&lt;/code&gt; has the regex pattern for parsing the trace id from the log message. &lt;code&gt;URL&lt;/code&gt; comprises a full link if it points to an external source. If it’s an internal link, this value serves as a query for the target data source. &lt;code&gt;$${__value.raw}&lt;/code&gt; macro interpolates the field's value into the internal link.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add new log labels using Promtail pipelines
&lt;/h3&gt;

&lt;p&gt;We will add one more change for ease of operation. As you have seen earlier, there was no trace id label on the Loki log. To add a particular label, we will use &lt;code&gt;pipelineStages&lt;/code&gt; to form a label out of log messages. Create a &lt;code&gt;loki-stack-values.yaml&lt;/code&gt; file and add the following code to it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;promtail&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;serviceMonitor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;additionalLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus-operator&lt;/span&gt;
        &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;

    &lt;span class="na"&gt;pipelineStages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{app="hotrod"}'&lt;/span&gt;
        &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;expression&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.*(?P&amp;lt;trace&amp;gt;trace_id&lt;/span&gt;&lt;span class="se"&gt;\"\\&lt;/span&gt;&lt;span class="s"&gt;S)&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;(?P&amp;lt;traceID&amp;gt;[a-zA-Z&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;d]+).*"&lt;/span&gt;
            &lt;span class="na"&gt;traceID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traceID&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;traceID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here &lt;code&gt;pipelineStages&lt;/code&gt; is used to declare a pipeline to add trace id label. You can find more details of the pipeline parameters &lt;a href="https://grafana.com/docs/loki/latest/clients/promtail/pipelines/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Now we will upgrade both kube-prometheus-stack and loki-stack Helm charts with updated values.&lt;/p&gt;

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

helm upgrade --install prometheus prometheus-community/kube-prometheus-stack --values=prom-oper-values.yaml
helm upgrade --install loki grafana/loki-stack --values=loki-stack-values.yaml


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Visualize distributed tracing in Grafana using Jaeger and Tempo
&lt;/h3&gt;

&lt;p&gt;We will again visit HOTROD UI and trigger the request from there. In the Grafana dashboard, click explore and select loki as a data-source. Add &lt;code&gt;{app="hotrod"}&lt;/code&gt; in Log labels. Now you will see a derived field with the name TraceID with an automatically generated internal link to Jaeger. You will also see an extra label with the name traceID. Click the derived field TraceID, and it will directly take you to Jaeger data-source and show all the traces of the particular trace id. This makes switching between logs and traces much easier. Also, this makes clear how to parse the log message according to the requirement.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k70c6u5rqja9oa7s2oa.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k70c6u5rqja9oa7s2oa.png" alt="derived_fields"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we will add Grafana Tempo as a data-source and visualize traces with minimal changes with the same setup. To enable this add the following lines in &lt;code&gt;prom-oper-values.yaml&lt;/code&gt; and upgrade the Helm chart:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tempo&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tempo&lt;/span&gt;
  &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-tempo&lt;/span&gt;
  &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;browser&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://tempo:16686&lt;/span&gt;
  &lt;span class="na"&gt;isDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;basicAuth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Change the data-source &lt;code&gt;uid&lt;/code&gt; in loki's configuration to tempo's &lt;code&gt;uid&lt;/code&gt; (e.g. &lt;code&gt;datasourceUid: my-tempo&lt;/code&gt;) in &lt;code&gt;prom-oper-values.yaml&lt;/code&gt;. Tempo uses Jaeger client libraries to receive all the trace related information. So, we will delete the Jaeger deployment and its service. To install Tempo in a single binary mode, we will use the standard Helm &lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/tempo" rel="noopener noreferrer"&gt;chart&lt;/a&gt; provided by Grafana.&lt;/p&gt;

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

helm upgrade --install tempo grafana/tempo


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

&lt;/div&gt;

&lt;p&gt;We also need to change the &lt;code&gt;JAEGER_AGENT_HOST&lt;/code&gt; variable in HOTROD (&lt;code&gt;hotrod-deployment.yaml&lt;/code&gt;) to &lt;code&gt;tempo&lt;/code&gt; for the correct identification of traces. Incorrect value or missing value may lead to the following error:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1tz02vlmlc6g5ibgoju.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1tz02vlmlc6g5ibgoju.png" alt="tempo_error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Re-apply the hotrod-deployment manifest to incorporate the changes made. Once again, visit the HOTROD UI and trigger the request from there. Now check for HOTROD logs in loki. You notice that the link in the derived field changes to Tempo. Click it and you can visualize all the trace information like before.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdsa8pxfdtg7slov5uxn.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdsa8pxfdtg7slov5uxn.png" alt="tempo_derived_fields"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To summarize the post, we touched upon the following points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to enable distributed tracing in a microservice application.&lt;/li&gt;
&lt;li&gt;How to convert a docker-compose manifest into Kubernetes manifest.&lt;/li&gt;
&lt;li&gt;How to enable Jaeger tracing in the deployment manifest of an application.&lt;/li&gt;
&lt;li&gt;How to configure Loki derived fields.&lt;/li&gt;
&lt;li&gt;How to parse log messages to add new labels using the Promtail pipeline concept.&lt;/li&gt;
&lt;li&gt;How to visualize distributed tracing in Grafana using Jaeger and Tempo data-sources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We hope you found this blog informative and engaging. If you have questions, feel free to reach out to me on &lt;a href="https://www.twitter.com/rutu_kadikar" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/ruturaj-kadikar/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and start a conversation :)&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentracing.io/docs/overview/what-is-tracing/" rel="noopener noreferrer"&gt;What is Distributed Tracing?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/joe-elliott/tracing-example" rel="noopener noreferrer"&gt;tempo-otel-example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/velotio-perspectives/a-comprehensive-tutorial-to-implementing-opentracing-with-jaeger-a01752e1a8ce" rel="noopener noreferrer"&gt;A Comprehensive Tutorial to Implementing OpenTracing With Jaeger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/grafana/latest/datasources/loki/" rel="noopener noreferrer"&gt;Using Loki in Grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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