<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Helm Charts on Digi Hunch</title><link>https://static.digihunch.com/tag/helm-charts/</link><description>Recent content in Helm Charts on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Wed, 02 Apr 2025 13:47:46 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/helm-charts/index.xml" rel="self" type="application/rss+xml"/><item><title>FluxCD: Continuous Deployment with GitOps</title><link>https://static.digihunch.com/2022/01/fluxcd-continuous-deployment-with-gitops/</link><pubDate>Sat, 15 Jan 2022 18:49:00 -0400</pubDate><guid>https://static.digihunch.com/2022/01/fluxcd-continuous-deployment-with-gitops/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-flux-pipeline.webp" alt="Featured image of post FluxCD: Continuous Deployment with GitOps" /&gt;&lt;p class="wp-block-paragraph"&gt;This post explains why I land on FluxCD GitOps for my project. Let&amp;#8217;s star&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-background"&gt;Background&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the &lt;a href="https://github.com/digihunch/korthweb"&gt;Korthweb&lt;/a&gt; project, I landed on Istio for the &lt;a href="https://static.digihunch.com/2021/12/from-ingress-to-gateway-why-you-need-istio-gateways-on-kubernetes-platforms/"&gt;Ingress Gateway&lt;/a&gt; technology. I first attempted to expand the &lt;a href="https://github.com/digihunch/korthweb/tree/main/helm"&gt;orthanc&lt;/a&gt; Helm Chart to bring Istio as dependency (sub-chart). One of the external chart for Istio gateway needs to be referenced multiple times (for ingress and egress). However, it cannot even be used as dependency (sub-chart) because of &lt;a href="https://github.com/istio/istio/issues/35495#issuecomment-1007197188"&gt;this&lt;/a&gt; issue. Istio didn&amp;#8217;t re-introduce Helm Chart as a supported deployment until September 2021. So I&amp;#8217;m not too confident about it.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This leads to a second thought of the &amp;#8220;Big Helm Chart&amp;#8221; approach to deploy all tiers in Korthweb. Helm is based on templating, and having two layers of charts brings complexity. I do need to bring a number of Helm charts together, but not necessarily by another Helm Chart. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The Kubernetes documentation also mentions &lt;a href="https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/"&gt;Kustomize&lt;/a&gt; as an alternative to Helm. Below is a quick exploration of it.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-kustomize"&gt;Kustomize&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A challenge with managing declarative object is to organize numerous manifest files to maintain consistency and readability. &lt;a href="https://github.com/kubernetes-sigs/kustomize"&gt;Kustomize&lt;/a&gt; is a standalone tool to customize Kubernetes objects through a &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#kustomization"&gt;Kustomization&lt;/a&gt; file. This &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/"&gt;page&lt;/a&gt; provides a good list of fields that can be used:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;vars and replacements: copy fields from one source into any number of specified targets.&lt;/li&gt;&#10;&lt;li&gt;namePrefix, namespace, nameSuffix: customize namespace and names.&lt;/li&gt;&#10;&lt;li&gt;configMapGenerator, secretGenerator, and generatorOptions: create configuration entries from literal, files, or environment variables.&lt;/li&gt;&#10;&lt;li&gt;resources: indicates another kustomization directory (e.g. as base)&lt;/li&gt;&#10;&lt;li&gt;patches (also called overlays) add or override fields on resources.&lt;/li&gt;&#10;&lt;li&gt;patchesStrategicMerge: modifies values in known (loaded) resources&lt;/li&gt;&#10;&lt;li&gt;images: modifies the name, tags and/or digest for images, without creating patches.&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/openapi/"&gt;openapi&lt;/a&gt;: use Kubernetes OpenAPI data to get merge key and patch strategy information about resource types.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The base -&amp;gt; overlay pattern ensures readability as well as portability. Typical use pattern is create one base kustomization, and several overlay kustomizations each representing an environment, such as dev, qa and production. &lt;a href="https://www.youtube.com/watch?v=btqZkVQIdd8"&gt;Here&lt;/a&gt; is a good tutorial. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Helm and Kustomize are two approaches to deploy Kubernetes workload. Both tackle the challenge of managing many YAML declarations. &lt;span style="text-decoration: underline;"&gt;Helm is template driven, and is commonly used by application developers as a means of packaging application releases while orchestrating the dependencies. Kustomize follows a base-overlay pattern, and is more commonly used by cluster operators for re-using manifests across multiple environments (e.g. dev, staging and prod)&lt;/span&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In my use case, my deployment needs both. I need third party Helm chart to configure components such as PostgreSQL for HA. I also need Kustomize for the orthanc workload. With the need for both, there should be a higher level deployment technology that ingrate with both mechanisms.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-gitops"&gt;GitOps&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;GitOps is originally brought up by Weaveworks in 2017. It is a methodology to deploy workload continuously, using a Git repository as source of truth. The point of GitOps is not about tooling, or specific platform, but rather to ensure the workload state matches the declaration in repository. For example, you can implement &lt;a href="https://www.redhat.com/sysadmin/ansible-webhooks-gitops"&gt;GitOps with Ansible&lt;/a&gt; for VM environment.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When it comes to managing Kubernetes workload, a GitOps tool must handle the challenge with managing many YAML declarations. Therefore most GitOps tools seek to support many well-adopted mechanisms such as Helm and Kustomize as discussed above, instead of simply taking an enormous amount of raw YAML declarations. The amount of deployment mechanisms supported, is a key indicator of how powerful a GitOps tool is. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The most notable tools are ArgoCD and FluxCD. Both are currently CNCF incubating projects. ArgoCD is powerful with many &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/application_sources/"&gt;tools&lt;/a&gt; supported, such as Kustomize, Helm, Ksonnet, Jsonnet, etc. It also contains a user interface and aims to manage an entire deployment workflow. On the other hand, FluxCD has controllers mainly for &lt;a href="https://fluxcd.io/docs/components/kustomize/"&gt;Kustomize&lt;/a&gt; and &lt;a href="https://fluxcd.io/docs/components/helm/"&gt;Helm&lt;/a&gt;, with a jsonnet &lt;a href="https://fluxcd.io/integrations/#flux-extensions"&gt;extension&lt;/a&gt; from third party. This &lt;a href="https://blog.container-solutions.com/fluxcd-argocd-jenkins-x-gitops-tools"&gt;post&lt;/a&gt; draws a comparison of them (along with JenkinsX) based on earlier versions (from mid 2020). There is even a standard (&lt;a href="https://opengitops.dev/"&gt;OpenGitOps&lt;/a&gt;) in &lt;a href="https://www.cncf.io/projects/opengitops/"&gt;CNCF&lt;/a&gt; landscape but still at Sandbox level.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For Korthweb project, I chose FluxCD. It is simple, and provides just enough types of controller for what I do.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-fluxcd"&gt;FluxCD&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The diagram below illustrates the components:&lt;/p&gt;&#10;&lt;p class="has-white-background-color has-background wp-block-paragraph"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="501px" viewBox="-0.5 -0.5 501 321" style="max-width:100%;max-height:321px;"&gt;&lt;defs&gt;&lt;/defs&gt;&lt;g&gt;&lt;rect x="0" y="0" width="240" height="320" fill="#fff2cc" stroke="#d6b656" pointer-events="all"&gt;&lt;/rect&gt;&lt;image x="9.5" y="9.5" width="40" height="40" xlink:href="https://cdn4.iconfinder.com/data/icons/socialcones/508/Github-128.png" preserveAspectRatio="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 30px; margin-left: 52px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;Git Repository&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="52" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;Git Rep&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="280" y="0" width="220" height="320" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;image x="449.5" y="9.5" width="41.67" height="40" xlink:href="https://app.diagrams.net/img/lib/mscae/Kubernetes.svg"&gt;&lt;/image&gt;&lt;rect x="61" y="50" width="144" height="42" rx="6.3" ry="6.3" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;image x="69.5" y="53.5" width="34" height="34" xlink:href="https://cdn0.iconfinder.com/data/icons/octicons/1024/file-directory-128.png" preserveAspectRatio="none" pointer-events="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 71px; margin-left: 106px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;flux-system&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="106" y="75" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;flux-s&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="60" y="160" width="140" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;image x="69.5" y="165.5" width="34" height="34" xlink:href="https://cdn0.iconfinder.com/data/icons/octicons/1024/file-directory-128.png" preserveAspectRatio="none" pointer-events="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 183px; margin-left: 106px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;Kustomize:&lt;br&gt;infrastructure&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="106" y="187" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;Kustom&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 133 92 L 133 103.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 133 108.88 L 129.5 101.88 L 133 103.63 L 136.5 101.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 60 130 L 40 130 L 40 180 L 53.63 180" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 58.88 180 L 51.88 183.5 L 53.63 180 L 51.88 176.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 60 130 L 40 130 L 40 280 L 53.63 280" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 58.88 280 L 51.88 283.5 L 53.63 280 L 51.88 276.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;rect x="60" y="210" width="140" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;image x="69.5" y="215.5" width="34" height="34" xlink:href="https://cdn0.iconfinder.com/data/icons/octicons/1024/file-directory-128.png" preserveAspectRatio="none" pointer-events="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 233px; margin-left: 106px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;Kustomize:&lt;br&gt;dependency&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="106" y="237" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;Kustom&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="60" y="260" width="140" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;image x="69.5" y="265.5" width="34" height="34" xlink:href="https://cdn0.iconfinder.com/data/icons/octicons/1024/file-directory-128.png" preserveAspectRatio="none" pointer-events="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 283px; margin-left: 106px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;Kustomize:&lt;br&gt;application&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="106" y="287" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;Kustom&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="63" y="110" width="140" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;path d="M 63 130 L 40 130 L 40 230 L 53.63 230" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 58.88 230 L 51.88 233.5 L 53.63 230 L 51.88 226.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;image x="72.5" y="115.5" width="34" height="34" xlink:href="https://cdn0.iconfinder.com/data/icons/octicons/1024/file-directory-128.png" preserveAspectRatio="none" pointer-events="none"&gt;&lt;/image&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 133px; margin-left: 109px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;Kustomize:&lt;br&gt;dev&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="109" y="137" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;Kustom&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="300" y="55" width="167.5" height="120" rx="18" ry="18" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;path d="M 337.35 65.02 C 336.99 65.05 336.62 65.14 336.3 65.3 L 321.98 72.13 C 321.22 72.49 320.68 73.18 320.49 73.98 L 316.95 89.35 C 316.79 90.06 316.93 90.81 317.32 91.43 C 317.39 91.5 317.43 91.57 317.48 91.66 L 327.39 103.97 C 327.92 104.61 328.72 105 329.54 105 L 345.44 105 C 346.26 105 347.06 104.61 347.59 103.97 L 357.5 91.64 C 358 91 358.21 90.15 358.03 89.35 L 354.48 73.98 C 354.3 73.18 353.75 72.49 353 72.13 L 338.68 65.3 C 338.27 65.09 337.81 65 337.35 65.02 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 337.36 66.22 C 337.02 66.24 336.67 66.33 336.37 66.48 L 322.91 72.9 C 322.2 73.24 321.68 73.89 321.51 74.64 L 318.18 89.09 C 318.03 89.76 318.16 90.46 318.53 91.04 C 318.59 91.11 318.64 91.17 318.68 91.26 L 328 102.83 C 328.49 103.43 329.24 103.8 330.02 103.8 L 344.96 103.8 C 345.74 103.8 346.49 103.43 346.98 102.83 L 356.3 91.24 C 356.77 90.64 356.97 89.84 356.79 89.09 L 353.47 74.64 C 353.29 73.89 352.78 73.24 352.07 72.9 L 338.61 66.48 C 338.22 66.29 337.79 66.2 337.36 66.22 Z" fill="#2875e2" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 325.2 74.38 L 324 74.38 L 324 77.05 L 325.34 77.05 L 325.34 74.48 L 327.88 74.48 L 327.88 73.14 L 325.2 73.14 Z M 329.22 74.48 L 331.9 74.48 L 331.9 73.14 L 329.22 73.14 Z M 333.23 74.48 L 335.91 74.48 L 335.91 73.14 L 333.23 73.14 Z M 337.25 74.48 L 339.93 74.48 L 339.93 73.14 L 337.25 73.14 Z M 341.26 74.48 L 343.94 74.48 L 343.94 73.14 L 341.26 73.14 Z M 345.28 74.48 L 347.96 74.48 L 347.96 73.14 L 345.28 73.14 Z M 349.29 74.48 L 349.66 74.48 L 349.66 75.45 L 351 75.45 L 351 73.81 C 351 73.31 350.77 73.14 350.33 73.14 L 349.29 73.14 Z M 349.66 79.46 L 351 79.46 L 351 76.79 L 349.66 76.79 Z M 324 81.07 L 325.34 81.07 L 325.34 78.39 L 324 78.39 Z M 349.66 83.48 L 351 83.48 L 351 80.8 L 349.66 80.8 Z M 324 85.08 L 325.34 85.08 L 325.34 82.41 L 324 82.41 Z M 349.66 87.49 L 351 87.49 L 351 84.82 L 349.66 84.82 Z M 324 89.1 L 325.34 89.1 L 325.34 86.42 L 324 86.42 Z M 349.66 91.51 L 351 91.51 L 351 88.83 L 349.66 88.83 Z M 324 93.11 L 325.34 93.11 L 325.34 90.44 L 324 90.44 Z M 349.66 95.52 L 351 95.52 L 351 92.85 L 349.66 92.85 Z M 324 96.19 C 324 96.66 324.2 96.86 324.67 96.86 L 325.61 96.86 L 325.61 95.52 L 325.34 95.52 L 325.34 94.45 L 324 94.45 Z M 326.94 96.86 L 329.62 96.86 L 329.62 95.52 L 326.94 95.52 Z M 330.96 96.86 L 333.64 96.86 L 333.64 95.52 L 330.96 95.52 Z M 334.97 96.86 L 337.65 96.86 L 337.65 95.52 L 334.97 95.52 Z M 338.99 96.86 L 341.67 96.86 L 341.67 95.52 L 338.99 95.52 Z M 343 96.86 L 345.68 96.86 L 345.68 95.52 L 343 95.52 Z M 347.02 96.86 L 349.7 96.86 L 349.7 95.52 L 347.02 95.52 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 85px; margin-left: 362px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"&gt;flux-system&lt;br&gt;namespace&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="362" y="89" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;flux-sys&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="300" y="225" width="167.5" height="70" rx="10.5" ry="10.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"&gt;&lt;/rect&gt;&lt;path d="M 337.35 235.02 C 336.99 235.05 336.62 235.14 336.3 235.3 L 321.98 242.13 C 321.22 242.49 320.68 243.18 320.49 243.98 L 316.95 259.35 C 316.79 260.06 316.93 260.81 317.32 261.43 C 317.39 261.5 317.43 261.57 317.48 261.66 L 327.39 273.97 C 327.92 274.61 328.72 275 329.54 275 L 345.44 275 C 346.26 275 347.06 274.61 347.59 273.97 L 357.5 261.64 C 358 261 358.21 260.15 358.03 259.35 L 354.48 243.98 C 354.3 243.18 353.75 242.49 353 242.13 L 338.68 235.3 C 338.27 235.09 337.81 235 337.35 235.02 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 337.36 236.22 C 337.02 236.24 336.67 236.33 336.37 236.48 L 322.91 242.9 C 322.2 243.24 321.68 243.89 321.51 244.64 L 318.18 259.09 C 318.03 259.76 318.16 260.46 318.53 261.04 C 318.59 261.11 318.64 261.17 318.68 261.26 L 328 272.83 C 328.49 273.43 329.24 273.8 330.02 273.8 L 344.96 273.8 C 345.74 273.8 346.49 273.43 346.98 272.83 L 356.3 261.24 C 356.77 260.64 356.97 259.84 356.79 259.09 L 353.47 244.64 C 353.29 243.89 352.78 243.24 352.07 242.9 L 338.61 236.48 C 338.22 236.29 337.79 236.2 337.36 236.22 Z" fill="#2875e2" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 325.2 244.38 L 324 244.38 L 324 247.05 L 325.34 247.05 L 325.34 244.48 L 327.88 244.48 L 327.88 243.14 L 325.2 243.14 Z M 329.22 244.48 L 331.9 244.48 L 331.9 243.14 L 329.22 243.14 Z M 333.23 244.48 L 335.91 244.48 L 335.91 243.14 L 333.23 243.14 Z M 337.25 244.48 L 339.93 244.48 L 339.93 243.14 L 337.25 243.14 Z M 341.26 244.48 L 343.94 244.48 L 343.94 243.14 L 341.26 243.14 Z M 345.28 244.48 L 347.96 244.48 L 347.96 243.14 L 345.28 243.14 Z M 349.29 244.48 L 349.66 244.48 L 349.66 245.45 L 351 245.45 L 351 243.81 C 351 243.31 350.77 243.14 350.33 243.14 L 349.29 243.14 Z M 349.66 249.46 L 351 249.46 L 351 246.79 L 349.66 246.79 Z M 324 251.07 L 325.34 251.07 L 325.34 248.39 L 324 248.39 Z M 349.66 253.48 L 351 253.48 L 351 250.8 L 349.66 250.8 Z M 324 255.08 L 325.34 255.08 L 325.34 252.41 L 324 252.41 Z M 349.66 257.49 L 351 257.49 L 351 254.82 L 349.66 254.82 Z M 324 259.1 L 325.34 259.1 L 325.34 256.42 L 324 256.42 Z M 349.66 261.51 L 351 261.51 L 351 258.83 L 349.66 258.83 Z M 324 263.11 L 325.34 263.11 L 325.34 260.44 L 324 260.44 Z M 349.66 265.52 L 351 265.52 L 351 262.85 L 349.66 262.85 Z M 324 266.19 C 324 266.66 324.2 266.86 324.67 266.86 L 325.61 266.86 L 325.61 265.52 L 325.34 265.52 L 325.34 264.45 L 324 264.45 Z M 326.94 266.86 L 329.62 266.86 L 329.62 265.52 L 326.94 265.52 Z M 330.96 266.86 L 333.64 266.86 L 333.64 265.52 L 330.96 265.52 Z M 334.97 266.86 L 337.65 266.86 L 337.65 265.52 L 334.97 265.52 Z M 338.99 266.86 L 341.67 266.86 L 341.67 265.52 L 338.99 265.52 Z M 343 266.86 L 345.68 266.86 L 345.68 265.52 L 343 265.52 Z M 347.02 266.86 L 349.7 266.86 L 349.7 265.52 L 347.02 265.52 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 255px; margin-left: 362px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"&gt;application&lt;br&gt;namespace&lt;br&gt;dev&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="362" y="259" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;applicat&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 337.35 115.02 C 336.99 115.05 336.62 115.14 336.3 115.3 L 321.98 122.13 C 321.22 122.49 320.68 123.18 320.49 123.98 L 316.95 139.35 C 316.79 140.06 316.93 140.81 317.32 141.43 C 317.39 141.5 317.43 141.57 317.48 141.66 L 327.39 153.97 C 327.92 154.61 328.72 155 329.54 155 L 345.44 155 C 346.26 155 347.06 154.61 347.59 153.97 L 357.5 141.64 C 358 141 358.21 140.15 358.03 139.35 L 354.48 123.98 C 354.3 123.18 353.75 122.49 353 122.13 L 338.68 115.3 C 338.27 115.09 337.81 115 337.35 115.02 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 337.36 116.22 C 337.02 116.24 336.67 116.33 336.37 116.48 L 322.91 122.9 C 322.2 123.24 321.68 123.89 321.51 124.64 L 318.18 139.09 C 318.03 139.76 318.16 140.46 318.53 141.04 C 318.59 141.11 318.64 141.17 318.68 141.26 L 328 152.83 C 328.49 153.43 329.24 153.8 330.02 153.8 L 344.96 153.8 C 345.74 153.8 346.49 153.43 346.98 152.83 L 356.3 141.24 C 356.77 140.64 356.97 139.84 356.79 139.09 L 353.47 124.64 C 353.29 123.89 352.78 123.24 352.07 122.9 L 338.61 116.48 C 338.22 116.29 337.79 116.2 337.36 116.22 Z" fill="#2875e2" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 346.63 134.43 L 344.92 134.43 L 344.92 129.85 C 344.92 128.59 343.91 127.58 342.65 127.58 L 338.07 127.58 L 338.07 125.85 C 338.07 124.29 336.78 123 335.22 123 C 333.64 123 332.35 124.29 332.35 125.85 L 332.35 127.58 L 327.78 127.58 C 326.54 127.58 325.5 128.59 325.5 129.85 L 325.5 134.21 L 327.21 134.21 C 328.91 134.21 330.3 135.59 330.3 137.28 C 330.3 138.98 328.91 140.37 327.21 140.37 L 325.5 140.37 L 325.5 144.72 C 325.5 145.96 326.54 147 327.78 147 L 332.13 147 L 332.13 145.29 C 332.13 143.59 333.52 142.2 335.22 142.2 C 336.91 142.2 338.29 143.59 338.29 145.29 L 338.29 147 L 342.65 147 C 343.91 147 344.92 145.96 344.92 144.72 L 344.92 140.15 L 346.63 140.15 C 348.21 140.15 349.5 138.86 349.5 137.28 C 349.5 135.72 348.21 134.43 346.63 134.43 Z" fill="#ffffff" stroke="none" pointer-events="none"&gt;&lt;/path&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 135px; margin-left: 365px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"&gt;flux-system&lt;br&gt;custom resource&lt;br&gt;controllers&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="365" y="139" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px"&gt;flux-syst&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 220.59 83.73 L 216.18 93.26 L 205.45 71.21 L 229.21 65.13 L 224.8 74.66 L 284.41 102.27 L 288.82 92.74 L 299.55 114.79 L 275.79 120.87 L 280.2 111.34 Z" fill="#f8cecc" stroke="#b85450" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 378.75 194.5 L 368.25 194.5 L 383.75 175.5 L 399.25 194.5 L 388.75 194.5 L 388.75 205.5 L 399.25 205.5 L 383.75 224.5 L 368.25 205.5 L 378.75 205.5 Z" fill="#f8cecc" stroke="#b85450" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 201px; margin-left: 420px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"&gt;reconcile&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="420" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle"&gt;reconcile&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 205.4 183.38 L 294.6 239.12" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 200.95 180.59 L 208.74 181.33 L 205.4 183.38 L 205.03 187.27 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 299.05 241.91 L 291.26 241.17 L 294.6 239.12 L 294.97 235.23 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 206.1 231.83 L 293.9 258.17" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 201.07 230.32 L 208.78 228.98 L 206.1 231.83 L 206.77 235.69 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 298.93 259.68 L 291.22 261.02 L 293.9 258.17 L 293.23 254.31 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 206.37 279.84 L 293.63 277.66" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 201.12 279.97 L 208.03 276.3 L 206.37 279.84 L 208.2 283.3 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;path d="M 298.88 277.53 L 291.97 281.2 L 293.63 277.66 L 291.8 274.2 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"&gt;&lt;/path&gt;&lt;/g&gt;&lt;switch&gt;&lt;g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;/g&gt;&lt;a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank" rel="noopener"&gt;&lt;text text-anchor="middle" font-size="10px" x="50%" y="100%"&gt;Text is not SVG &amp;#8211; cannot display&lt;/text&gt;&lt;/a&gt;&lt;/switch&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The configurations starts with a bootstrapping process, which creates directory in Git repository (if not exist), and installs flux-system components in the target Kubernetes cluster. The sync process starts as soon as bootstrapping is completed. The process in charge of syncing declarations to target cluster, confusingly, is also called Kustomization. Therefore there are two Kustomizations. According to the FAQ on FluxCD website:&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are two Kustomization types. the &lt;em&gt;kustomization.kustomize.toolkit.fluxcd.io&lt;/em&gt; is a Kubernetes custom resource while &lt;em&gt;kustomization.kustomize.config.k8s.io&lt;/em&gt; is the type used to configure a Kustomize overlay. The &lt;em&gt;kustomization.kustomize.toolkit.fluxcd.io&lt;/em&gt; object refers to a kustomization.yaml file path inside a Git repository or Bucket source.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Inside of the Git repository, with a &lt;meta charset="utf-8"&gt;&lt;em&gt;kustomization.kustomize.toolkit.fluxcd.io&lt;/em&gt; obejct, the flux-system points to Kustomization file (representing &lt;meta charset="utf-8"&gt;&lt;em&gt;kustomization.kustomize.config.k8s.io&lt;/em&gt; object) at root level. The kustomization.yaml file organizes resources in the same directory. A kustomize directory may also reference other kustomize directory, forming a hierarchy. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-implementation"&gt;Implementation&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;FluxCD has a command &amp;#8220;flux check &amp;#8211;pre&amp;#8221; to check the prerequisite, such as kubectl. The code is stored in the &lt;a href="https://github.com/digihunch/korthweb/tree/main/gitops"&gt;GitOps&lt;/a&gt; directory of &lt;a href="https://github.com/digihunch/korthweb"&gt;Korthweb&lt;/a&gt; repository.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To configure deployment, we need to first create a &lt;a href="https://fluxcd.io/docs/installation/#github-and-github-enterprise"&gt;personal access token&lt;/a&gt;. For GitHub, &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token"&gt;here&lt;/a&gt; is the instruction. Export the token to environment variable, and launch bootstrapping:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ export GITHUB_TOKEN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;xxx_yyy55555XXXodr7ABBBB234CCccw&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ flux bootstrap github &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --owner&lt;span style="color:#f92672"&gt;=&lt;/span&gt;digihunch &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --repository&lt;span style="color:#f92672"&gt;=&lt;/span&gt;korthweb &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --branch&lt;span style="color:#f92672"&gt;=&lt;/span&gt;main &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --personal &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --path&lt;span style="color:#f92672"&gt;=&lt;/span&gt;gitops/environment/dev&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;A deploy key is configured during the bootstrapping process. As soon as bootstrapping is completed, the sync (aka kustomization, or reconciliation) has started, which can be monitored using:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flux get kustomizations --watch&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Running this command without &amp;#8211;watch switch returns the overview of all kustomizations. Once reconciliation is completed, it should display something like:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NAME &#9;READY&#9;MESSAGE &#9;REVISION &#9;SUSPENDED&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;application &#9;True &#9;Applied revision: main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;False&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dependency &#9;True &#9;Applied revision: main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;False&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flux-system &#9;True &#9;Applied revision: main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;False&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;infrastructure&#9;True &#9;Applied revision: main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;main/98f3c771d4ab23f5cb5fd8c7aee325f6490000c7&#9;False&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;FluxCD introduced a number of CRDS. For example, to check configured source repository, check gitrepositories CRD:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl get gitrepositories -n flux-system&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;To check the detail of one kustomization (e.g. infrastructure), check kusomization CRD in flux-system namespace:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl -n flux-system get kustomizations flux-system -o yaml | less&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Other commonly used custom resources include:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;helmcharts&lt;/li&gt;&#10;&lt;li&gt;helmreleases&lt;/li&gt;&#10;&lt;li&gt;helmrepositories&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A Helm release can be created imperatively, for example:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ flux create source helm istio &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --interval&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1h &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --url&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https://istio-release.storage.googleapis.com/charts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ flux create helmrelease istio-base &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --interval&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1h &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --release-name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istio-base &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --target-namespace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istio-system &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --create-target-namespace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;true &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --source&lt;span style="color:#f92672"&gt;=&lt;/span&gt;HelmRepository/istio &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --chart&lt;span style="color:#f92672"&gt;=&lt;/span&gt;base &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --chart-version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1.12.0&amp;#34;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ flux create helmrelease istiod &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --interval&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1h &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --release-name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istiod &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --target-namespace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istio-system &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --source&lt;span style="color:#f92672"&gt;=&lt;/span&gt;HelmRepository/istio &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --chart&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istiod &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --chart-version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1.12.0&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --values&lt;span style="color:#f92672"&gt;=&lt;/span&gt;istiod-values.yaml &#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;However, in a GitOps approach, they should be stored as code (use &amp;#8211;export to export declaration). For example, the &lt;a href="https://github.com/digihunch/korthweb/tree/main/gitops/infrastructure"&gt;infrastructure kustomization&lt;/a&gt; keeps HelmReleases for installing Istio and PostgreSQL. This kustomization is referenced by a Flux &lt;a href="https://github.com/digihunch/korthweb/blob/main/gitops/infrastructure/kustomization.yaml"&gt;Kustomization&lt;/a&gt; from higher level.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;You can also manually &lt;a href="https://fluxcd.io/docs/cmd/flux_reconcile/"&gt;reconcile&lt;/a&gt; one of the kustomizations (or other CRDs) with flux reconcile command, for example:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flux reconcile kustomization dependency&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Since Nov 2021, FluxCD (&lt;a href="https://fluxcd.io/blog/2021/11/november-2021-update/#server-side-apply-has-landed"&gt;0.20&lt;/a&gt;) supports reconciliation based on &lt;a href="https://kubernetes.io/docs/reference/using-api/server-side-apply/"&gt;server-side&lt;/a&gt; apply. This increases performance and help address issues such as &lt;a href="https://www.reddit.com/r/kubernetes/comments/sbw7lo/the_configmap_is_invalid_metadataannotations_too/"&gt;applying large config map&lt;/a&gt;, which is the equivalent of adding &amp;#8211;server-side flag to the kubectl apply command.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-limitation"&gt;Limitation&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Troubleshooting the FluxCD repo can be involving and counter-intuitive. I had to commit a lot of changes to the repo because it serves as source of truth. Even though the commits can be made to a branch, it still involves a lot of code pushes. Traditionally I commit a change after testing. In the GitOps workflow, I commit a change then to test.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;More flexible troubleshooting options are still to be desired. For example, there is no way to run one (FluxCD&amp;#8217;s) Kustomization object at a time (and disable the rest), unless you remove their YAML files from the repo.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The next limitation is the ordering of resources in Kustomization. Arguably this is a limitation from Kustomize, instead of FluxCD&amp;#8217;s. For example, I need the following manifest to be executed:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;apiVersion&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;cert-manager.io/v1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ClusterIssuer&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;metadata&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;selfsigned-issuer&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;spec&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;selfSigned&lt;/span&gt;: {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The resource is a CRD that needs to be first installed using Helm chart (cert-manager). However there&amp;#8217;s no way to control the sequence (Helm release executed first before declaration using CRD). Although there&amp;#8217;s some &lt;a href="https://github.com/kingdonb/bootstrap-repo/tree/staging/apps/cert-manager"&gt;workaround&lt;/a&gt;, it is not convenient. Alternatively, we can separate the resource creation and CRD creation into separate kustomization objects with dependency relationship, as suggested in &lt;a href="https://fluxcd.io/docs/components/kustomize/kustomization/#kustomization-dependencies"&gt;this&lt;/a&gt; example.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Deployment in Kubernetes can get complicated with a lot of manifests. Helm, Kustomize and the like are means to handle the complexity due to numerous manifests. GitOps tools such as FlexCD brings these tools under a single framework, and more importantly, implements the idea of using Git repository as source of truth for continuous deployment.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2022/01/kubernetes-admission-control/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes Admission Control&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2022/01/traffic-segmentation-on-kubernetes-platform/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Traffic Segmentation on Kubernetes Platform&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Intro to PLG stack -Prometheus, Loki and Grafana</title><link>https://static.digihunch.com/2021/10/intro-to-plg-stack-prometheus-loki-and-grafana/</link><pubDate>Sun, 03 Oct 2021 12:59:00 -0400</pubDate><guid>https://static.digihunch.com/2021/10/intro-to-plg-stack-prometheus-loki-and-grafana/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-plg-intro.webp" alt="Featured image of post Intro to PLG stack -Prometheus, Loki and Grafana" /&gt;&lt;p class="wp-block-paragraph"&gt;Last month we discussed &lt;a href="https://static.digihunch.com/2021/09/log-shipping-in-kubernetes-with-efk/"&gt;log shipping with EFK&lt;/a&gt;. This week I spent sometime checking out its alternative Loki. Having been exposed to the &lt;a href="https://static.digihunch.com/2018/09/log-shipping-through-elk/"&gt;ELK stack&lt;/a&gt; extensively, I am also interested in exploring the counterparts in this new stack, such as Prometheus, Loki and Grafana. So I need to address the issues of shipping both metrics and logs.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Let&amp;#8217;s start by clarifying the terms:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Grafana&lt;/strong&gt; is a visualizer. It supports many backends such as Prometheus, Loki, Elasticsearch, CloudWatch and Azure Monitor. It is the flagship product of Grafana Labs.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; is a time-series database and alerting platform. To push metrics to Premethus, you can either integrate your application with client library (in their term, &lt;em&gt;instrumenting&lt;/em&gt;), or configure an existing &lt;a href="https://prometheus.io/docs/instrumenting/exporters/"&gt;exporters&lt;/a&gt; for a third party application such as PostgreSQL. Prometheus &lt;em&gt;collects&lt;/em&gt; and &lt;em&gt;stores&lt;/em&gt; its metrics as time series data ( i.e. metrics information is stored with the timestamp at which it was recorded, alongside optional key-value pairs called labels) and it comes with basic visualization capability. Premetheus is a CNCF project since 2016 and is maintained by Grafana Labs.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Loki&lt;/strong&gt; is a log aggregation system, also developed by Grafana Labs. Loki does not index the contents of the logs. Instead it groups entries into streams, and indexes a set of labels for each log stream. You can use grafana or logcli to consume the logs. Loki supports clients such as Fluentd, Fluentbit, Logstash and Promtail.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Promtail&lt;/strong&gt; is a log collection agent built for Loki.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The roles of the components such as Prometheus, Loki, Grafana and Promtail are similar to the ELK stack. Grafana resembles Kibana. Promtail resembles Filebeat. Premethus exporters resemble Metricbeat. Both Premetheus and Loki resemble Elasticsearch in some aspects. Premetheus keeps metrics and Loki persists log streams. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;These tools are heavily used in Kubernetes. For a simple start, I&amp;#8217;d like to just configure two minimally working pipelines on my MacBook without any containerization. My example setup is to achieve the followings:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Fake up some log lines and ship them to Loki&lt;/li&gt;&#10;&lt;li&gt;Ship OS metrics to Prometheus&lt;/li&gt;&#10;&lt;li&gt;Display the metrics and logs with Grafana&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Here&amp;#8217;s the diagram of what we want to implement:&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="491px" viewBox="-0.5 -0.5 491 106" style="max-width:100%;max-height:106px;"&gt;&lt;defs&gt;&lt;/defs&gt;&lt;g&gt;&lt;rect x="0" y="0" width="490" height="105" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;path d="M 206.37 30 L 220 30 L 210 30 L 223.63 30" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 201.12 30 L 208.12 26.5 L 206.37 30 L 208.12 33.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;path d="M 228.88 30 L 221.88 33.5 L 223.63 30 L 221.88 26.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="110" y="15" width="90" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 30px; margin-left: 111px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Promtail&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="155" y="34" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Promtail&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 206.37 70 L 220 70 L 210 70 L 223.63 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 201.12 70 L 208.12 66.5 L 206.37 70 L 208.12 73.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;path d="M 228.88 70 L 221.88 73.5 L 223.63 70 L 221.88 66.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="110" y="55" width="90" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 70px; margin-left: 111px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Node Exporter&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="155" y="74" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Node Exporter&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 326.37 30 L 340 30 L 340 50 L 353.63 50" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 321.12 30 L 328.12 26.5 L 326.37 30 L 328.12 33.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;path d="M 358.88 50 L 351.88 53.5 L 353.63 50 L 351.88 46.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="230" y="15" width="90" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 30px; margin-left: 231px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Loki&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="275" y="34" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Loki&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 326.37 70 L 340 70 L 340 50 L 353.63 50" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 321.12 70 L 328.12 66.5 L 326.37 70 L 328.12 73.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;path d="M 358.88 50 L 351.88 53.5 L 353.63 50 L 351.88 46.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="230" y="55" width="90" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 70px; margin-left: 231px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Prometheus&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="275" y="74" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Prometheus&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="35" width="90" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 50px; margin-left: 361px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Grafana&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="405" y="54" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Grafana&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 80 30 L 100 30 L 90 30 L 103.63 30" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 108.88 30 L 101.88 33.5 L 103.63 30 L 101.88 26.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="10" y="15" width="70" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 30px; margin-left: 11px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Log File&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="45" y="34" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Log File&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 80 70 L 100 70 L 90 70 L 103.63 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 108.88 70 L 101.88 73.5 L 103.63 70 L 101.88 66.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="10" y="55" width="70" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 70px; margin-left: 11px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Collectors&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="45" y="74" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Collectors&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;/g&gt;&lt;switch&gt;&lt;g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;/g&gt;&lt;a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank" rel="noopener"&gt;&lt;text text-anchor="middle" font-size="10px" x="50%" y="100%"&gt;Viewer does not support full SVG 1.1&lt;/text&gt;&lt;/a&gt;&lt;/switch&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This is simple enough to build a quick and dirty setup&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-configure-node-exporter"&gt;Configure Node Exporter&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We can use home brew to install node_exporter on MacOS. For Linux, use the equivalent package management tool:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install node_exporter&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew services start node_exporter&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl http://localhost:9100/metrics | grep &lt;span style="color:#e6db74"&gt;&amp;#34;node_&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The node_exporter collect metrics and make it available for scrape using port 9100 as shown above. &lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-configure-prometheus"&gt;Configure Prometheus&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Install Prometheus with homebrew and start the service:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install prometheus&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew services start prometheus&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;&lt;meta charset="utf-8"&gt;If curl to port 9090 with GET returns &amp;#8220;Found&amp;#8221;, then Prometheus is successfully installed. We also want to configure it so it scrapes node exporter for metrics. Edit the configuration file, in my case, /usr/local/etc/prometheus.yml, by adding the followings:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;job_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;node&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;static_configs&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;targets&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#39;localhost:9100&amp;#39;&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;This tells Prometheus to scrape metrics at specified interval. Restart Prometheus and browse to http://localhost:9090/ for Prometheus UI. Click on Status -&amp;gt; Targets and you can see the node as an export. Click on Graph and Execute a query for example &amp;#8220;node_memory_free_bytes&amp;#8221; and click on Graph. You should see a plot of the metric value.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="1057" height="801" src="https://static.digihunch.com/wp-content/uploads/2021/10/image-1.png" alt="" class="wp-image-2759"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We can later configure to display the chart in Grafana.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-generate-log-lines"&gt;Generate log lines &lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We use a tool called &lt;a href="https://hub.docker.com/r/mingrammer/flog"&gt;flog&lt;/a&gt; to generate fake logs:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew tap mingrammer/flog&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install flog&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flog -f rfc3164 -l -d 300ms -t log -o /tmp/test.log -w&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The command above produces log in RFC3164 format to /tmp/test.log, one line every 300ms. The log does not rotate.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-configure-loki"&gt;Configure Loki&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Install Loki with homebrew and start the service. We want to configure Loki before Promtail so it is ready to receive logs. You might as well install LogCLI to interact with Loki.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install loki&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install logcli&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew services start loki&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;If nc to port 3100 returns success, then Loki is successfully installed. &lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-configure-promtail"&gt;Configure Promtail&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Install promtail using homebrew:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install promtail&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Note that Promtail is not installed as a &lt;a href="https://github.com/Homebrew/homebrew-services"&gt;homebrew&lt;/a&gt; service. Although it can be manually configured as a service, I&amp;#8217;d rather stay focused and use command line just for the time being. A copy of configuration file is located in /usr/local/etc/promtail-local-config.yaml but it needs to be modified first with a job to tell it where to scrap the log lines. The configuration looks like this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; http_listen_port: &lt;span style="color:#ae81ff"&gt;9080&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grpc_listen_port: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;positions:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; filename: /tmp/positions.yaml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;clients:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - url: http://localhost:3100/loki/api/v1/push&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scrape_configs:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- job_name: app&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; static_configs:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - targets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - localhost&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; labels:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; job: applogs&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; __path__: /tmp/test.log&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then, use the command as in the &lt;a href="https://grafana.com/docs/loki/latest/getting-started/get-logs-into-loki/"&gt;documentation&lt;/a&gt; to start promtail:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;promtail -config.file /usr/local/etc/promtail-local-config.yaml&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Port 9080 will be open when Promtail is running. Promtail will push logs to Loki. You can use &lt;a href="https://grafana.com/docs/loki/latest/getting-started/logcli/"&gt;LogCLI&lt;/a&gt; to interact with Loki and see the latest log lines pushed to Loki. &lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;logcli labels job&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;logcli query &lt;span style="color:#e6db74"&gt;&amp;#39;{job=&amp;#34;applogs&amp;#34;}&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;However, unlike Prometheus, Loki itself does not have any visualization capabilities. We will need Grafana to display the log nicely on the web.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-configure-grafana"&gt;Configure Grafana&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We use Grafana to visualize both the logs and metrics. To install Grafana on Mac:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install grafana&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew services start grafana&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;If curl to port 3000 with GET returns &amp;#8220;Found&amp;#8221;, then Grafana is successfully installed. Browse to localhost:3000, with default credential admin and admin. From the UI, add two data sources. For the first data source, specify Prometheus as type and localhost:9000 as destination. For the second, specify Loki as the destination http://localhost:3100&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The steps to see logs in Loki is pretty much the same as on &lt;a href="https://grafana.com/docs/loki/latest/getting-started/grafana/"&gt;this&lt;/a&gt; page of its documentation.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-large"&gt;&lt;img loading="lazy" decoding="async" width="1394" height="1055" src="https://static.digihunch.com/wp-content/uploads/2021/10/image-3.png" alt="" class="wp-image-2766"/&gt;&lt;figcaption class="wp-element-caption"&gt;Exploring logs&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Exploring metrics data is similar. Click on Explore on the side bar, then select Prometheus from the dropdown as data source. Then execute a query such as &amp;#8220;&lt;meta charset="utf-8"&gt;node_memory_free_bytes&amp;#8221;.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-large is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2021/10/image-2.png" alt="" class="wp-image-2764" width="840" height="513"/&gt;&lt;figcaption class="wp-element-caption"&gt;Explore Metrics&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With this quick and dirty configuration, we established a good understanding of what Prometheus, Loki and Grafana do. Next, we will move all these configurations to K8s cluster and understand some specific points of configurations.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2021/09/file-storage-vs-object-storage/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;File storage vs object storage in the cloud&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/10/logging-and-monitoring-in-kubernetes-with-plg-stack/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Logging and Monitoring in Kubernetes with PLG stack&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>