<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Adrian Todorov</title>
    
    
    
    <link>/</link>
    <description>Recent content on Adrian Todorov</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>adrian.todorov@atodorov.ninja (Adrian Todorov)</managingEditor>
    <webMaster>adrian.todorov@atodorov.ninja (Adrian Todorov)</webMaster>
    <copyright>Adrian Todorov &lt;a href=&#34;https://creativecommons.org/licenses/by-nc/4.0/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt; CC BY-NC 4.0&lt;/a&gt;</copyright>
    <lastBuildDate>Sun, 15 Mar 2026 13:21:59 +0200</lastBuildDate>
    
	<atom:link href="/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>GPU Sharing Done Right: Secrets, Security, and Scaling</title>
      <link>/talks/scale-baedge/</link>
      <pubDate>Sun, 15 Mar 2026 13:21:59 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/talks/scale-baedge/</guid>
      <description>
        
          
          
          
        
        
        &lt;p&gt;Presentation delivered at the &lt;a href=&#34;https://www.socallinuxexpo.org/scale/23x/presentations/gpu-sharing-done-right-secrets-security-and-scaling&#34;&gt;Southern California Linux Expo (SCALE), 23rd Edition&lt;/a&gt; in March 2026.&lt;/p&gt;
&lt;p&gt;Multi-tenant Kubernetes with GPU sharing is a compelling model for AI infrastructure, but it requires careful design to balance performance with security. This session shows how to build a secure and scalable environment where multiple teams can run GPU workloads without compromising isolation or access control. We’ll cover open source options like KAI Scheduler and vCluster and demonstrate how to integrate external tools for secret management and dynamic access policies, all within an architecture that lets teams feel like they have their own cluster—while behind the scenes, resources are efficiently pooled and shared.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;/talks/Scale23X_ScottMcAllister_AdrianTodorov.pdf&#34;&gt;Slide Deck&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Dynamic Identities and Secrets for your applications on Nomad</title>
      <link>/talks/scale-gpu-sharing-done-right/</link>
      <pubDate>Thu, 05 Mar 2026 15:16:05 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/talks/scale-gpu-sharing-done-right/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;description&#34;&gt;Description&lt;/h2&gt;
&lt;p&gt;A presentation delivered at the &lt;a href=&#34;https://www.meetup.com/hashicorp-user-group-paris/events/304454307/?eventOrigin=group_upcoming_events&#34;&gt;December 2024 Paris HashiCorp User Group&lt;/a&gt;, covering Nomad Workload Identity and how it can be used to securely introduce identities (for auth to third parties) and secrets to applications running in Nomad. Using GCP &lt;a href=&#34;https://cloud.google.com/iam/docs/workload-identity-federation&#34;&gt;Workload Identity Federation&lt;/a&gt; and offline trust between GCP IAM and Nomad&amp;rsquo;s Workload Identity, all based on OIDC/JWT.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/sofixa/nomad-dynamic-identities-and-secrets&#34;&gt;GitHub repository with demo code&lt;/a&gt; | &lt;a href=&#34;/talks/HUG%20Paris%20Dynamic%20Identities%20and%20Secrets%20for%20your%20applications%20on%20Nomad.pdf&#34;&gt;Slide Deck&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Orchestrating Edge AI workloads on a Jetson Orin Nano with Nomad</title>
      <link>/2025/06/27/orchestrating-edge-ai-workloads-on-a-jetson-orin-nano-with-nomad/</link>
      <pubDate>Fri, 27 Jun 2025 16:49:06 +0100</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2025/06/27/orchestrating-edge-ai-workloads-on-a-jetson-orin-nano-with-nomad/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently I&amp;rsquo;ve been tinkering around with my Home Assistant setup, more specifically adding voice control. I wanted to enhance it with a local LLM (large language model) to be able to do more advanced natural language processing (I&amp;rsquo;m in a multilingual household, and Home Assistant&amp;rsquo;s voice control is pretty static - you have to predefine phrases and actions, you can&amp;rsquo;t just improvise). I could have used a cloud service, but not only is that not fun, but it also has privacy implications. So I wanted to run it all locally, and preferably on a small, power-efficient device that can handle the workload.&lt;/p&gt;
&lt;p&gt;Enter the Jetson Orin Nano from NVIDIA.&lt;/p&gt;
&lt;h2 id=&#34;jetson-orin-nano&#34;&gt;Jetson Orin Nano&lt;/h2&gt;
&lt;p&gt;The Jetson Orin Nano is a powerful, compact AI development board from NVIDIA. It has a 6 core ARM CPU, a Tensor GPU with 1024 CUDA/32 tensor cores, and 8GB of 102 GB/s (relatively slow, but usable) RAM. It&amp;rsquo;s a great platform for running small AI workloads locally, and is very power efficient. Recently NVIDIA released a software update (confusingly called Jetson Orin Nano Super) that added a significant performance improvement (mostly in terms of TOPS and memory bandwidth).&lt;/p&gt;
&lt;p&gt;It runs &amp;ldquo;Jetpack&amp;rdquo;, a NVIDIA customised (with all the NVIDIA drivers and libraries) version of Ubuntu, and there is a pretty good community, ecosystem and documentation around it. In particular, &lt;a href=&#34;https://github.com/dusty-nv/jetson-containers&#34;&gt;Jetson Containers&lt;/a&gt; is a very good collection of ready-to-use containers (with correct versions of CUDA and all necessary configs, etc.) for popular AI / ML / robotics-related software.&lt;/p&gt;
&lt;p&gt;As the underlying OS is based on Ubuntu, the software catalogue is vast, including HashiCorp Nomad, to plug into a larger homelab setup and orchestrate everything from a common control plane.&lt;/p&gt;
&lt;p&gt;In my case, I&amp;rsquo;d like to run &lt;a href=&#34;https://ollama.com/&#34;&gt;Ollama&lt;/a&gt;, a local LLM hosting server, to integrate it with &lt;a href=&#34;https://www.home-assistant.io/integrations/ollama/&#34;&gt;Home Assistant&lt;/a&gt;, and maybe some other AI workloads. They need to run on the Jetson, but consumers don&amp;rsquo;t (such as &lt;a href=&#34;https://openwebui.com/&#34;&gt;Open WebUI&lt;/a&gt;, a frontend for Ollama, or Home Assistant). They can run elsewhere in my lab to avoid wasting precious memory that could be used as VRAM for the Large Language Models. For instance, OpenWebUI takes a good 800+ MB of RAM, and the Jetson has only 8GB, so it would be a waste to run it there.&lt;/p&gt;
&lt;h2 id=&#34;nomad&#34;&gt;Nomad&lt;/h2&gt;
&lt;p&gt;Nomad is a powerful, flexible, and easy to use orchestrator that can run on a wide range of platforms, including edge devices like the Jetson Orin Nano. It supports a variety of workloads, including containers and raw executables, and crucially for Edge scenarios, supports various distributed clusters topologies and tolerates unreliable networks.&lt;/p&gt;
&lt;p&gt;Nomad supports &lt;code&gt;linux/arm64&lt;/code&gt;, so everything should work out of the box. Furthermore, Nomad has an &lt;a href=&#34;https://developer.hashicorp.com/nomad/plugins/devices/nvidia&#34;&gt;NVIDIA Device Driver&lt;/a&gt; so there should be direct support to fingerprint (discover and make targetable via attributes) the GPU and attach it to jobs.&lt;/p&gt;
&lt;p&gt;This doesn’t sound too complex, right? While building it, I was pleasantly surprised with how simple the whole process was. Let&amp;rsquo;s dive in.&lt;/p&gt;
&lt;h2 id=&#34;jetson-setup&#34;&gt;Jetson setup&lt;/h2&gt;
&lt;p&gt;NVIDIA have a detailed &lt;a href=&#34;https://www.jetson-ai-lab.com/initial_setup_jon.html&#34;&gt;getting started tutorial&lt;/a&gt; on how to set up the Jetson Orin Nano, so I won&amp;rsquo;t go into too much detail about it here. The only tricky part was that the one I got was running a very old firmware version, so I had to jump through multiple steps to update it to a recent one that allows running the latest Jetpack 6.x (the version that delivers the drastically improved performance that led to NVIDIA calling it &amp;ldquo;Jetson Orin Nano Super&amp;rdquo;). Other than that, it was basically flashing a micro SD card, inserting it into the Jetson, and booting it up. Rinse, repeat this step several times until you get to the desired version.&lt;/p&gt;
&lt;p&gt;An NVME drive is &lt;em&gt;strongly&lt;/em&gt; recommended to store the heavy stuff (container images, models, etc.) - microSD cards are more expensive per GB at the higher end, aren&amp;rsquo;t made for such heavy random write I/O, and probably won&amp;rsquo;t survive that long. The Jetson Orin Nano has two available M.2 slots (a third one is used for the WiFi card), a PCIe 3.0 x4 in the 2280 format, and a PCIe 3.0 x2 in the 2230 format.&lt;/p&gt;
&lt;p&gt;To allow for remote headless control, enable SSH from the Ubuntu GUI setup, and configure SSH keys.&lt;/p&gt;
&lt;h3 id=&#34;performance-tuning&#34;&gt;Performance tuning&lt;/h3&gt;
&lt;p&gt;To get the most out of the Jetson, you need to disable the Desktop GUI (which just wastes resources), and set the power mode to &amp;ldquo;Max Performance&amp;rdquo;, which came with Jetpack 6.x. By default there&amp;rsquo;s a cap of 15W power consumption, which can be increased to 25W or &amp;ldquo;unlimited&amp;rdquo; - the setting I went for. This can be done using the &lt;code&gt;nvpmodel&lt;/code&gt; command, which is part of the Jetpack installation. The command to set the power mode to unlimited is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# set the power mode to unlimited&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo /usr/sbin/nvpmodel -m &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# disable desktop GUI to free up resources&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl set-default multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# reboot for the changes to take effect and everything to be cleaned&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;installing-nomad&#34;&gt;Installing Nomad&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re new to Nomad, consider taking a look at the &lt;a href=&#34;https://developer.hashicorp.com/nomad/tutorials/get-started/gs-overview&#34;&gt;Introduction to Nomad&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nomad has releases for &lt;code&gt;arm64&lt;/code&gt; (the CPU architecture of the Jetson family) available via an APT repository which works for Jetpack.&lt;/p&gt;
&lt;p&gt;Connect to the Jetson via SSH, and run the following commands to install Nomad:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get update &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install wget gpg coreutils
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;lsb_release -cs&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; main&amp;#34;&lt;/span&gt;  | sudo tee /etc/apt/sources.list.d/hashicorp.list
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get update &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install nomad
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install CNI plugins which are used to configure networking for Nomad allocations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export ARCH_CNI&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; aarch64 &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; echo arm64 &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; echo amd64&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export CNI_PLUGIN_VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;v1.7.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -L -o cni-plugins.tgz &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://github.com/containernetworking/plugins/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;CNI_PLUGIN_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/cni-plugins-linux-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ARCH_CNI&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;CNI_PLUGIN_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;.tgz &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also need a configuration file for the Nomad agent to know which addresses to listen on, which folder to use for the Nomad and allocation data (on the NVME to avoid overtaxing the SD card), etc. In my case I&amp;rsquo;m connecting to an existing Nomad cluster, but it can also be a standalone single machine cluster with only the Jetson. The configuration file is in HCL format, and should be placed in &lt;code&gt;/etc/nomad.d/&lt;/code&gt;.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;963278154&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;963278154&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;/etc/nomad/client.hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
name = &amp;#34;jetson-nano-01&amp;#34;
region = &amp;#34;global&amp;#34;
datacenter = &amp;#34;home&amp;#34;

# the address the Nomad client will be available on, important to adjust especially on public networks where 
# it shouldn&amp;#39;t be 0.0.0.0
bind_addr = &amp;#34;0.0.0.0&amp;#34;

# the folder where Nomad stores its data, which we want on the NVME drive
data_dir = &amp;#34;/ssd/nomad&amp;#34;

log_level = &amp;#34;INFO&amp;#34;
enable_syslog = true

client {
    enabled = true

    # the address of the Nomad servers/control plane; 
    # if there are none and this will be a single node cluster, add a server block 
    # with enabled = true and bootstrap_expect = 1 in a separate configuration file
    # in the same folder (e.g. /etc/nomad/server.hcl), and use 172.0.0.1 for the server address
    servers = [&amp;#34;nomad-servers.home&amp;#34;]
    # Node Pool, used to group nodes with similar capabilities (in this case, Jetsons)
    node_pool = &amp;#34;jetsons&amp;#34;
}

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



&lt;h3 id=&#34;setting-up-the-nvidia-jetson-gpuapu-for-use-with-nomad&#34;&gt;Setting up the NVIDIA Jetson GPU/APU for use with Nomad&lt;/h3&gt;
&lt;p&gt;Nomad has a concept called &lt;a href=&#34;https://developer.hashicorp.com/nomad/plugins/devices&#34;&gt;device drivers&lt;/a&gt;, which enable Nomad to fingerprint (discover) devices, collect information about them, and make them available for scheduling and targeting. They are with an open spec, anyone can write their own, and there are community ones for USB and Xlinix FPGAs, as well as an official NVIDIA driver. It discovers NVIDIA GPUs, collects their info (type, wattage, memory use, etc.) and allows you to deploy workloads specifically targeting them, like so:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;279436185&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;279436185&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Example job using an NVIDIA GPU&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
job &amp;#34;gpu-test&amp;#34; {
  datacenters = [&amp;#34;dc1&amp;#34;]
  type = &amp;#34;batch&amp;#34;

  group &amp;#34;smi&amp;#34; {
    task &amp;#34;smi&amp;#34; {
      driver = &amp;#34;docker&amp;#34;

      config {
        image = &amp;#34;nvidia/cuda:12.8.1-base-ubuntu22.04&amp;#34;
        command = &amp;#34;nvidia-smi&amp;#34;
      }

      resources {
        device &amp;#34;nvidia/gpu&amp;#34; {
          count = 1

          # Add an affinity for a particular model
          affinity {
            attribute = &amp;#34;${device.model}&amp;#34;
            value     = &amp;#34;Tesla H100&amp;#34;
            weight    = 50
          }
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;I thought I&amp;rsquo;d need to use it, so compiled my own (currently there are no &lt;code&gt;arm64&lt;/code&gt; releases), tried running it&amp;hellip; and got a bunch of errors from NVML, the underlying NVIDIA library for GPU management and monitoring. After some research, I discovered that contrary to my expectations, Jetsons aren&amp;rsquo;t supported by NVML, at all. It goes as far as detecting there&amp;rsquo;s an NVIDIA device of type &amp;ldquo;Orin&amp;rdquo;, and that&amp;rsquo;s it, none of the other methods such as getting the name, wattage, memory, etc. work.&lt;/p&gt;
&lt;p&gt;Therefore the NVIDIA device driver, which relies entirely on NVML, is out. But is it actually needed?&lt;/p&gt;
&lt;p&gt;Turns out, no, not really. CUDA workloads detect the integrated GPU on their own and directly use it. The only thing needed for containers is the NVIDIA container toolkit (which installs a special &lt;code&gt;nvidia&lt;/code&gt; runtime), which comes preinstalled with Jetpack. The last part of the puzzle is a way to target the correct client, the one with the GPU, but this is easily solved by the fact that I put the Jetson in its own node pool, and use that to target it.&lt;/p&gt;
&lt;p&gt;Note: Nomad can run applications with &lt;a href=&#34;https://developer.hashicorp.com/nomad/docs/drivers/raw_exec&#34;&gt;&lt;code&gt;raw_exec&lt;/code&gt;&lt;/a&gt; where binaries/scripts are executed directly on the host OS, with no isolation. This could be marginally faster than with containers, but comes at the expense of increased difficulty  when managing dependencies such as CUDA and various other libraries&amp;rsquo; versions. There is already some complexity due to the dependency on the host NVIDIA driver and kernel, which is enough of a potential minefield, so I decided to stick to Docker containers for now.&lt;/p&gt;
&lt;p&gt;Speaking of Docker containers, this brings me back to the &lt;a href=&#34;https://github.com/dusty-nv/jetson-containers&#34;&gt;jetson-containers&lt;/a&gt; repository by &lt;a href=&#34;https://github.com/dusty-nv&#34;&gt;Dustin Franklin&lt;/a&gt;. It contains ready to use (with all necessary libraries and dependencies) containers for popular robotics, IoT, AI, ML, etc. frameworks/tools/platforms, as well as wrapper tools to start them with the appropriate settings. That&amp;rsquo;s a great starting point for running workloads on the Jetson, and what I&amp;rsquo;ll use to make my life easier.
The containers are available on &lt;a href=&#34;https://hub.docker.com/u/dustynv&#34;&gt;Docker Hub&lt;/a&gt;, and can be pulled and run like any other container.&lt;/p&gt;
&lt;h2 id=&#34;deploying-ollama-and-open-webui-on-nomad&#34;&gt;Deploying Ollama and Open WebUI on Nomad&lt;/h2&gt;
&lt;p&gt;With all this set up, we can now deploy Ollama and Open WebUI on Nomad. The process is pretty straightforward, and is similar to deploying any other container on Nomad. The only difference is that Docker needs to use the &lt;code&gt;nvidia&lt;/code&gt; runtime - NVIDIA&amp;rsquo;s Jetson guides recommend setting it as the default for the docker daemon (in &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;), but it can also be specified in Nomad with &lt;a href=&#34;https://developer.hashicorp.com/nomad/docs/drivers/docker#runtime&#34;&gt;&lt;code&gt;runtime&lt;/code&gt;&lt;/a&gt; in the job spec.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;647529813&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;647529813&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Ollama job spec&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
job &amp;#34;ollama&amp;#34; {
  # targeting the &amp;#34;jetsons&amp;#34; node pool which contains the Jetson Orin Nano
  datacenters = [&amp;#34;*&amp;#34;]
  node_pool = &amp;#34;jetsons&amp;#34;
  namespace = &amp;#34;llm&amp;#34; # namespace for all LLM-related jobs, needs to be created first
  type      = &amp;#34;service&amp;#34;

  group &amp;#34;ollama&amp;#34; {
    # persistent volume to store Ollama&amp;#39;s models, data, cache, etc.
    volume &amp;#34;ollama&amp;#34; {
      type            = &amp;#34;host&amp;#34;
      source          = &amp;#34;ollama&amp;#34;
      access_mode     = &amp;#34;single-node-single-writer&amp;#34;
      attachment_mode = &amp;#34;file-system&amp;#34;
    }

    # service and network to make Ollama&amp;#39;s API discoverable to other jobs, like Open WebUI
    # and Home Assistant
    service {
      name     = &amp;#34;ollama&amp;#34;
      port     = &amp;#34;ollama&amp;#34;
      provider = &amp;#34;nomad&amp;#34;
    }
    network {
      port &amp;#34;ollama&amp;#34; {
        static = 11434
      }
    }
    # Ollama Docker container (from jetson-containers), using the NVIDIA runtime
    task &amp;#34;ollama&amp;#34; {
      driver = &amp;#34;docker&amp;#34;
      config {
        image = &amp;#34;dustynv/ollama:r36.4.0&amp;#34;
        command = &amp;#34;ollama&amp;#34;
        args    = [&amp;#34;serve&amp;#34;]
        runtime = &amp;#34;nvidia&amp;#34;
        shm_size = 8192
        ports = [&amp;#34;ollama&amp;#34;]
      }
      # env vars to configure Ollama
      env {
        OLLAMA_HOST = &amp;#34;0.0.0.0&amp;#34;
        OLLAMA_MODELS = &amp;#34;/ollama/models&amp;#34;
        OLLAMA_LOGS = &amp;#34;/ollama/logs&amp;#34;
      }
      volume_mount {
        volume      = &amp;#34;ollama&amp;#34;
        destination = &amp;#34;/ollama&amp;#34;
      }
      resources {
        cpu    = 9000
        memory = 7168 # leave a GB for the OS, Nomad and other processes
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;Next, a Nomad job spec for Open WebUI:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;689517243&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;689517243&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;OpenWebUI job spec&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
job &amp;#34;openwebui&amp;#34; {
  datacenters = [&amp;#34;*&amp;#34;]
  namespace = &amp;#34;llm&amp;#34;
  node_pool = &amp;#34;default&amp;#34; # default node pool, so that it doesn&amp;#39;t run on the Jetson
  type       = &amp;#34;service&amp;#34;

  group &amp;#34;openwebui&amp;#34; {
    volume &amp;#34;openwebui&amp;#34; {
      type            = &amp;#34;host&amp;#34;
      source          = &amp;#34;openwebui&amp;#34;
      access_mode     = &amp;#34;single-node-single-writer&amp;#34;
      attachment_mode = &amp;#34;file-system&amp;#34;
    }

   service {
      name = &amp;#34;open-webui&amp;#34;
      port = &amp;#34;http&amp;#34;
      provider = &amp;#34;nomad&amp;#34;
    }

    network {
        port &amp;#34;http&amp;#34; {
            static = 8080
            to = 8080
        }
    }

  task &amp;#34;open-webui&amp;#34; {
    driver = &amp;#34;docker&amp;#34;
    config {
        image   = &amp;#34;ghcr.io/open-webui/open-webui:0.6&amp;#34;
        ports   = [&amp;#34;http&amp;#34;]
    }
    resources {
        cpu    = 600
        memory = 1024
    }

  # dynamic template to inject the Ollama server address into the OpenWebUI container,
  # with automatic restart on changes
  template {
    data = &amp;lt;&amp;lt;EOH
    # any extra environment variables needed by OpenWebUI can be added here
    # such as ENABLE_WEB_SEARCH=true and WEB_SEARCH_ENGINE=duckduckgo
OLLAMA_BASE_URL=http://{{range nomadService &amp;#34;ollama&amp;#34;}}{{ .Address}}:{{ .Port }}{{end}}
EOH

    destination = &amp;#34;secrets/file.env&amp;#34;
    env         = true
    change_mode = &amp;#34;restart&amp;#34;
    }
   volume_mount {
        volume      = &amp;#34;openwebui&amp;#34;
        destination = &amp;#34;/app/backend/data&amp;#34;
      }
  
  }
 }

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



&lt;p&gt;For both jobs, I used Nomad volumes to create a persistent storage for the data (for models, cache, configuration). Volumes can be managed by CSI plugins, but I used the newly released builtin dynamic host volumes, which are much simpler to set up and use. They are created on the host, and mounted into the container. Example volume definition that will create a volume called &lt;code&gt;ollama&lt;/code&gt; in the the Nomad data_dir (&lt;code&gt;/ssd/nomad/host_volumes&lt;/code&gt;) folder on the host:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name            &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ollama&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;namespace       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;llm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;type            &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;plugin_id       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mkdir&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;node_pool       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jetsons&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;capacity_min &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10G&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;capacity_max &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;100G&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;capability&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  access_mode     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;single-node-single-writer&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  attachment_mode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file-system&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Deploying all of those is a matter of running &lt;code&gt;nomad volume run&lt;/code&gt; and &lt;code&gt;nomad job run&lt;/code&gt; with the job spec files. The jobs will be scheduled on the Jetson Orin Nano, the Ollama server will be available on port 11434, and OpenWebUI on port 8080.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad volume create jobs/llm/ollama.volume.hcl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad volume create jobs/llm/openwebui.volume.hcl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad job run jobs/llm/ollama.hcl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad job run jobs/llm/openwebui.hcl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After a few minutes, the Ollama server should be up and running, and you can access it via the OpenWebUI at &lt;code&gt;http://jetson|other-machine-IP:8080&lt;/code&gt;. Clients such as Home Assistant can connect to Ollama at &lt;code&gt;http://jetson-IP:11434&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The NVIDIA Jetson Orin Nano is a decently powerful (for limited home use) AI development board, and with Nomad it&amp;rsquo;s very easy to orchestrate AI workloads on it and integrate it into a larger homelab setup.&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Dynamic Identities and Secrets for your applications on Nomad</title>
      <link>/talks/nomad-workload-identity/</link>
      <pubDate>Thu, 05 Dec 2024 15:16:05 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/talks/nomad-workload-identity/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;description&#34;&gt;Description&lt;/h2&gt;
&lt;p&gt;A presentation delivered at the &lt;a href=&#34;https://www.meetup.com/hashicorp-user-group-paris/events/304454307/?eventOrigin=group_upcoming_events&#34;&gt;December 2024 Paris HashiCorp User Group&lt;/a&gt;, covering Nomad Workload Identity and how it can be used to securely introduce identities (for auth to third parties) and secrets to applications running in Nomad. Using GCP &lt;a href=&#34;https://cloud.google.com/iam/docs/workload-identity-federation&#34;&gt;Workload Identity Federation&lt;/a&gt; and offline trust between GCP IAM and Nomad&amp;rsquo;s Workload Identity, all based on OIDC/JWT.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/sofixa/nomad-dynamic-identities-and-secrets&#34;&gt;GitHub repository with demo code&lt;/a&gt; | &lt;a href=&#34;/talks/HUG%20Paris%20Dynamic%20Identities%20and%20Secrets%20for%20your%20applications%20on%20Nomad.pdf&#34;&gt;Slide Deck&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Running a multi-gig Home Network in 2024</title>
      <link>/2024/07/03/running-a-multi-gig-home-network-in-2024/</link>
      <pubDate>Wed, 03 Jul 2024 19:01:40 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2024/07/03/running-a-multi-gig-home-network-in-2024/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Why a multi-gig home network? What is a multi-gig network anyway? The second question is easy, it&amp;rsquo;s a network that runs at a speed higher than 1Gbps (usually one of or a combination of 2.5/5/10Gbps), which until a few years ago was almost exclusively reserved for the enterprise space due to hardware costs. But it isn&amp;rsquo;t anymore, there are quite a few &lt;em&gt;relatively&lt;/em&gt; affordable options nowadays. The first question is a bit more complex, but the short answer is: because I can. The long answer is: because I enjoy tinkering with networking (to some extent), and because I want to have a fast network at home. My Internet Service Provider (ISP), Free (yes, &lt;a href=&#34;https://www.free.fr/&#34;&gt;really&lt;/a&gt;) already gives me lots of bandwith - 5Gbps down and 700Mbps up, so why not have a network that can handle as much as possible from that? I have a few bandwith intensive workloads at home - streaming from my NAS, video game streaming from the cloud / my gaming PC to my TV, remote storage for my Nomad cluster from my NAS, game downloads, backups, etc.&lt;/p&gt;
&lt;p&gt;I embarked on this journey in 2022, but it took me some time to finish implementing everything and find the time to write about it, so I&amp;rsquo;m documenting it from here in 2024 (it didn&amp;rsquo;t actually take me 2 years to set up everything, I just did things sequentially with massive gaps in between). I&amp;rsquo;ll try to remember as much as possible, but I&amp;rsquo;ll also try to keep it up to date with the latest information I have.&lt;/p&gt;
&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;
&lt;h3 id=&#34;router&#34;&gt;Router&lt;/h3&gt;
&lt;p&gt;One of the most important parts, the centerpriece of the network. I wanted to use a router with some very specific advanced features, which my ISP provided box doesn&amp;rsquo;t have (even if it has &lt;em&gt;a lot&lt;/em&gt; of features for an ISP-provided one, such as WireGuard and OpenVPN, ad-blocking DNS, etc.), hence the need for a separate, proper one. Unfortunately there&amp;rsquo;s no way to entirely remove my ISP&amp;rsquo;s router (because it has an integrated 10G-EPON module to be able to actually use the fibre link to my home), but I can put it in bridge mode and use my own router behind it for all the logic and network management.&lt;/p&gt;
&lt;h4 id=&#34;requirements&#34;&gt;Requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Multiple (at least 3) multi-gig &lt;em&gt;Ethernet&lt;/em&gt; ports (ideally 10Gbps) - due to the physical constraints in my network cupboard, and the need for the ISP&amp;rsquo;s router in bridge mode, there simply isn&amp;rsquo;t the space for a switch there too, hence the need for a router with multiple multi-gig ports (at least one for the &amp;ldquo;WAN&amp;rdquo; link to the ISP router, and two others for the two rooms with lots of equipment). As for why Ethernet, the place I live in is wired for Ethernet in every room, following a standard that should give me up to 10Gbps, so I want to take advantage of that, even if I know that it&amp;rsquo;s not perfect and consumes lots of power/heat compare to SFP+.&lt;/li&gt;
&lt;li&gt;VLAN support (basic stuff)&lt;/li&gt;
&lt;li&gt;VPN support, both as a server but also, and more importantly, as a client with something like &lt;code&gt;ipsets&lt;/code&gt; to direct only certain traffic through VPNs (to avoid a few specific geoblocks)&lt;/li&gt;
&lt;li&gt;(relatively) affordable&lt;/li&gt;
&lt;li&gt;(relatively) low power consumption and (relatively) low noise and (relatively) small size - it&amp;rsquo;s going to live in a fully closed network cupboard, so it can&amp;rsquo;t be too loud or too hot, and there isn&amp;rsquo;t a ton of space either&lt;/li&gt;
&lt;li&gt;Wi-Fi optional to not needed, because I have a separate Unifi WiFi access point that I&amp;rsquo;m happy with, and in any case the network cupboard being weirdly located would result in poor coverage&lt;/li&gt;
&lt;li&gt;software support - I don&amp;rsquo;t want a router from a vendor that will stop updating it within a year or two, and then being stuck with outdated/insecure device at the core of my network. I was looking for something that has a good community around it, and/or a vendor that has a good track record of updating their devices for a long time&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;options&#34;&gt;Options&lt;/h4&gt;
&lt;p&gt;It took quite some digging to find a router that fits all these requirements - most that did from the hardware side (multiple multi-gig ports) are &amp;ldquo;gamer routers&amp;rdquo; from the likes of Asus, Netgear and TP-Link (such as the Asus GT-AXE16000 or Netgear Nighthawk RS700S). Not only do they have Wi-Fi onboard which I don&amp;rsquo;t need, Netgear and TP-Link have&amp;hellip; let&amp;rsquo;s say far from steallar reputation in terms of their software&amp;rsquo;s security and quickness/length of updates. Asus is a bit better because they use ASUSWRT (based on the Tomato network firmware), which is open source, and there&amp;rsquo;s a third party/community Asuswrt-Merlin project which builds on top of that, but it&amp;rsquo;s still not ideal. Their router that seemed to most closely match my requirements, the Asus GT-AXE16000, wasn&amp;rsquo;t supported by Asuswrt-Merlin and it was unclear when that support would land (and although I love contributing to open source, networking firmwares are way above my capabilities).&lt;/p&gt;
&lt;p&gt;On the other side were the &amp;ldquo;prosumer&amp;rdquo; routers, such as those from Ubuquiti and Mikrotik. My previous network used to run on an Edgerouter-X, which was a great little router, so I was familiar with Ubiquiti&amp;rsquo;s software and hardware. However their product strategy (deprecating the Edge* line and focusing on the Unifi line, which is UI-managed and has less flexibility and features), as well as the overall quality of their software, and importantly in this case, the size of their routers (the Unifi Dream Machines are huge) made me look elsewhere. Which is a shame, because I plan on using their Access Points for WiFi, and it would have been great to be able to manage the whole network from a single central point. Mikrotik was a bit of a wildcard, I had never used their products, but they seemed to have a good reputation in the networking community, and their routers were relatively affordable. However, none had more than one multi-gig (and it was only 2.5Gbps) Ethernet port (like most vendors, and for very good reasons, they prioritise SFP+ ports for 1Gbps+).&lt;/p&gt;
&lt;p&gt;By chance, I stumbled upon an article by &lt;a href=&#34;https://www.servethehome.com/inexpensive-4x-2-5gbe-fanless-router-firewall-box-review-intel-j4125-i225-pfsense/&#34;&gt;ServeTheHome&lt;/a&gt; about an inexpensive 2.5Gbps mini PC that can serve as a router from Topton/Qotom (apparently appears under different brand names around the internet), based on a decent Intel CPU and with 4x Intel 2.5Gbps Ethernet ports. After some digging around I found a 6x 2.5Gbps port version, still using Intel NICs (Intel i226-V), which is important for compatibility with various OSes (the seller proposed shipping it with pfSense or OPNsense, but I guessed any *nix OS would be fine based on the specs and hardware involved). A big added benefit is the fanless design. The description of the device was exactly what I was looking for, and the price was very reasonable (~300 euros with shipping), so I decided to give it a try. I ordered it from AliExpress, and it arrived in a few weeks, much faster than planned.&lt;/p&gt;
&lt;p&gt;Hardware specs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Intel Celeron N5105 (4 cores, 4 threads, 2.0GHz base, 2.9GHz turbo) - decent low-powered CPU, more than enough for a home router, even with multiple 2.5Gbps ports, VPNs, etc.&lt;/li&gt;
&lt;li&gt;8GB DDR4 RAM - more than enough, in normal use it uses less than 1.5GB&lt;/li&gt;
&lt;li&gt;128GB SSD - more than enough, the whole OS + config + everything takes around 5GB&lt;/li&gt;
&lt;li&gt;6x Intel i225-V 2.5Gbps Ethernet ports - currently I only use 4 of them, but it provides some flexibility for the future (like connecting a backup 4G modem, or after I upgrade my ISP&amp;rsquo;s router to one that has more than one 2.5Gbps port, make an aggregate of two ports and load balance between the two for 2x2.5Gbps Internet)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The exact model I got doesn&amp;rsquo;t seem to be in stock anymore, but there are all sorts of similar ones with newer processors and various combinations of ports available on Amazon, Ebay, AliExpress.&lt;/p&gt;
&lt;h4 id=&#34;operating-system&#34;&gt;Operating System&lt;/h4&gt;
&lt;p&gt;Since I went with custom hardware, I had to also pick an appropraite OS. I initially tried OPNSense, but the configuration by ClickOps wasn&amp;rsquo;t my thing, especially for my scenario where I have 3 ports that need to be bridged and configured the same; it was &lt;em&gt;a lot&lt;/em&gt; of clicking around. I hesitated rolling a regular Linux distro such as Debian, but in the end decided to go for a more specialized one, &lt;a href=&#34;https://vyos.net/&#34;&gt;VyOS&lt;/a&gt;. It is based on Vyatta, same as EdgeOS from Ubiquiti which I already knew from my previous router, the venerable ER-X. It&amp;rsquo;s entirely CLI-based - even better, a declarative CLI, like real networking software, and has a good community and documentation. All the configuration is in a single file (effectively) with some Git-like commit/compare/rollback/etc. features, including an extremely powerful &lt;code&gt;commit-confirm&lt;/code&gt; which will commit configuration changes, and reboot if you don&amp;rsquo;t explicitly confirm them; this is brilliant for network equipment where a misconfiguration can easily cut off your own admin access. The biggest downside is that Long Term Support Releases are for paying customers/contributors only; for everyone else, you either have to compile your own, or use the rolling release, which is what I went with. I&amp;rsquo;m not too worried about it, because VyOS makes it very easy to backup the configuration (it&amp;rsquo;s just a text file &lt;a href=&#34;https://docs.vyos.io/en/latest/cli.html#remote-archive&#34;&gt;automatically backed up&lt;/a&gt; to my NAS on each configuration commit), so if anything goes wrong I can just reflash the device and restore the configuration.&lt;/p&gt;
&lt;p&gt;VyOS&amp;rsquo; documentation is pretty good on all the &lt;a href=&#34;https://docs.vyos.io/en/latest/quick-start.html#&#34;&gt;basics&lt;/a&gt;, all options and features, and importantly for people getting started, there are &lt;a href=&#34;https://docs.vyos.io/en/latest/configexamples/index.html&#34;&gt;configuration blueprints&lt;/a&gt; which show you how to achieve complete things (like a site to site VPN). There&amp;rsquo;s also a good community of people writing about it, like this &lt;a href=&#34;https://lev-0.com/2024/06/17/vyos-for-home-use-part-1-initial-setup/&#34;&gt;blog series&lt;/a&gt; by &lt;a href=&#34;https://lev-0.com/&#34;&gt;Level Zero Networking&lt;/a&gt;, and many EdgeOS-related blog posts, docs, forum posts, etc. also apply or are easy to translate.&lt;/p&gt;
&lt;h3 id=&#34;switches&#34;&gt;Switches&lt;/h3&gt;
&lt;p&gt;I needed 3 switches - one for the living room (for the TV, console, media box, etc.), and two chained ones for the office - one covering my homelab, (3 Nomad mini PCs + another mini PC), and the other for the rest of the office (NAS, work and personal laptops, Raspberry Pis running Home Assistant, assorted projects, another 3 Nomad nodes, etc.) in two different corners of the room.&lt;/p&gt;
&lt;h4 id=&#34;requirements-1&#34;&gt;Requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;A few multi-gig Ethernet ports (at least 2.5Gbps, but also at least one 10Gbps port for my NAS so that both my Nomad cluster and other uses can saturage their links) for the uplink and a few devices that can take advantage of it, but mostly 1Gbps ports; PoE isn&amp;rsquo;t needed because I have exactly one device that can use it, an Access Point, and it&amp;rsquo;s powered by a PoE injector&lt;/li&gt;
&lt;li&gt;&amp;ldquo;managed&amp;rdquo; (mostly VLAN support)&lt;/li&gt;
&lt;li&gt;(relatively) affordable&lt;/li&gt;
&lt;li&gt;(relatively) small and (relatively) low noise - 1 of them would be in the living room, and slightly visible, so a full rackmount switch would be out of place&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;options-1&#34;&gt;Options&lt;/h4&gt;
&lt;p&gt;For switches, there were much more options available on the market, with quite a lot of flexibility in terms of port combinations. After going over:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mikrotik - &lt;a href=&#34;https://mikrotik.com/product/crs312_4c_8xg_rm&#34;&gt;CRS312-4C+8XG-RM&lt;/a&gt; with 4x combo 10G Ethernet/SFP+ ports, 8 1/2.5/5/10G Ethernet ports&lt;/li&gt;
&lt;li&gt;Netgear:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.netgear.com/business/wired/switches/plus/gs110emx/&#34;&gt;GS110EMX&lt;/a&gt; with 2x 1/2.5/5/10G Ethernet ports, 8x 1G Ethernet ports&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.netgear.com/business/wired/switches/smart/ms510tx/#tab-techspecs&#34;&gt;MS510TX&lt;/a&gt; with 1x SFP+, 1x1/2.5/5/10G, 2x 1/2.5/5G, 2x1/2.5G, 4x1G Ethernet ports&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.netgear.com/business/wired/switches/smart/ms510txm/&#34;&gt;MS510TXM&lt;/a&gt; with 2x SFP+, 4x1x1/2.5/5/10G, 4x1/2.5G&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Zyxel &lt;a href=&#34;https://www.zyxel.com/global/en/products/switch/12-port-web-managed-multi-gigabit-switch-includes-3-port-10g-and-1-port-10g-sfp-xgs1250-12&#34;&gt;XGS1250-12&lt;/a&gt; with 1xSFP+, 3x1/2.5/5/10G, 8x 1G Ethernet ports.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I settled on the Zyxel, it was by far the cheapest option (~190 euros vs ~270 for the Netgear GS110EMX), and it provides a very good combination of ports for my needs.&lt;/p&gt;
&lt;p&gt;I use the SFP+ port on one of them for 10Gbps to my NAS, a 10Gbps Ethernet cable to chain two of the switches (thus getting 10Gbps between my Nomad homelab and the NAS serving its persistent volumes), and 2.5Gbps uplinks to the router. The web UI they come with is a bit weird and it took me reading the docs twice to understand how to properly configure the VLANs, especially trunks (having a port that allows multiple vlans), but it does the trick. Also, there&amp;rsquo;s an &lt;a href=&#34;https://www.reddit.com/r/homelab/comments/16q095r/making_managed_switch_out_of_unmanaged_zyxel/&#34;&gt;OpenWRT firmware&lt;/a&gt; for those switches with a lot of extra functionality if someone needs more than the stock firmware provides, or if they want to convert the non-managed switches (which are cheaper) to a managed version.&lt;/p&gt;
&lt;p&gt;I use VLANs extensively to separate the IoT devices from the rest of the network, and to have a separate LAB network for my Nomad homelab Nomad.&lt;/p&gt;
&lt;h3 id=&#34;wireless-access-point&#34;&gt;Wireless Access Point&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m currently using an older Unifi Access Point (AC-PRO) that only does WiFi 5 (formerly known as ac), doesn&amp;rsquo;t support WiFi6 nor WiFi 6E, and only has an 1Gbps uplink (technically two of them, but the second one can only serve as a backup) so it can&amp;rsquo;t fully benefit from my fast wired network. I plan on upgrading to a new model that can make use of a multi-gig uplink, and to prepare for the future WiFi 6, 6E and 7 devices on my network. WiFi frequencies are quite congested where I live (and I don&amp;rsquo;t help with 3 2.4GHz networks, 2 Zigbee networks and a ton of Bluetooth devices over the same 2.4Ghz band), so moving to WiFi 6/6E/7 should have a noticeable impact. Hopefully.&lt;/p&gt;
&lt;p&gt;Overall I&amp;rsquo;m happy with Ubiquiti&amp;rsquo;s Unifi line &lt;em&gt;for Access Points&lt;/em&gt; - they work pretty well and the UI is perfectly fine for configuring them (unlike for a router), so I&amp;rsquo;ll probably get a Unifi U7 Pro or a U7 Pro Max that has a 2.5Gbps uplink, which is perfect for my setup.&lt;/p&gt;
&lt;p&gt;In terms of networks, I have 3 separate SSIDs (WiFi networks, mapped to VLANs) - one for Internet of Things devices to keep them separate and only give them internet access, one for guests, and one for everything else.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Overal, I&amp;rsquo;m very happy with the current setup. It works very well, is super reliable, allows me to do everything I want to do (including, importantly, conditional VPN for certain traffic), and is relatively easy to manage (no ongoing maintenance other than a VyOS update very few weeks).&lt;/p&gt;
&lt;h3 id=&#34;hardware-1&#34;&gt;Hardware&lt;/h3&gt;
&lt;p&gt;Outside of the upgrade of the WiFi Access Point, one day I might upgrade the router to one with a better uplink (or figure out a way to add one to the current router, e.g. with a USB3 adaptor) to make use of more of my ISP&amp;rsquo;s bandwith, but that&amp;rsquo;s not a priority right now.&lt;/p&gt;
&lt;h3 id=&#34;observability&#34;&gt;Observability&lt;/h3&gt;
&lt;p&gt;An important part of any network is observability - knowing what happens in it, bandwith actually used (to see if there are any bottlenecks that merit an upgrade), what devices are connected, how much they use (e.g. my washing machine downloading gigabytes from the Internet would not be normal), etc. I&amp;rsquo;ll use Grafana Alloy with Grafana Cloud-hosted Prometheus, monitoring the various devices with the old and battle tested SNMP.&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Configuring Home Assistant OS with VLANs</title>
      <link>/2024/06/09/configuring-home-assistant-os-with-vlans/</link>
      <pubDate>Sun, 09 Jun 2024 19:10:40 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2024/06/09/configuring-home-assistant-os-with-vlans/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;(if you know why you&amp;rsquo;re here, jump to the next section)&lt;/p&gt;
&lt;p&gt;VLANs (virtual local area networks) are virtual networks that allow you to segment a single physical network into multiple logical ones. It&amp;rsquo;s a great way to isolate devices from each other and keep your network a bit more secure, especially with IoT/smart devices (as the famous saying goes, the &lt;code&gt;s&lt;/code&gt; in IoT stands for security). In my case, all my &amp;ldquo;smart&amp;rdquo; devices are on a separate VLAN because I don&amp;rsquo;t trust them enough, and Home Assistant, which manages them all, needs to be accessible from both the IoT network and my main network. I use Home Assistant OS, which is a pre-built image for Raspberry Pi and generally pretty great, but hides a lot of things from the user, so the usual Linux configuration options are not available (you can&amp;rsquo;t just SSH in and use &lt;code&gt;nmcli&lt;/code&gt; or &lt;code&gt;/etc/network/interfaces&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&#34;commands&#34;&gt;Commands&lt;/h2&gt;
&lt;p&gt;You need to install the &lt;a href=&#34;https://community.home-assistant.io/t/home-assistant-community-add-on-ssh-web-terminal/33820&#34;&gt;SSH &amp;amp; Web Terminal&lt;/a&gt; add-on to get a terminal to be able to run commands on your Home Assistant OS, configure it with a username and password/authorized key (important even if you want to use it directly in the UI, otherwise it refuses to start), and start it. Afterwards, you can &amp;ldquo;Open Web UI&amp;rdquo; / SSH in, and run the following commands using the &lt;code&gt;ha&lt;/code&gt; cli:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# gets the network configuration, including the name of the network interface (something like end0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha network info
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then, for a static network / if you want your Home Assistant to have a static IP:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ha network vlan $NETWORK_INTERFACE $VLAN_ID --ipv4-method static --ipv6-method disabled
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --ipv4-address 172.16.1.5/24 --ipv4-gateway 172.16.1.1 --ipv4-nameserver 172.16.1.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or for DHCP:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ha network vlan $NETWORK_INTERFACE $VLAN_ID --ipv4-method auto --ipv6-method disabled 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
        
        </description>
    </item>
    
    <item>
      <title>Logging on Nomad and log aggregation with Loki</title>
      <link>/2021/07/09/logging-on-nomad-and-log-aggregation-with-loki/</link>
      <pubDate>Fri, 09 Jul 2021 18:38:43 +0100</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2021/07/09/logging-on-nomad-and-log-aggregation-with-loki/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;When running a task orchestrator like Nomad or Kubernetes, there&amp;rsquo;s usually a bunch of different instances ( containers, micro-VMs, jails, etc. ) running, more or less ephemerally, across a fleet of servers. By default all logs would be local to the nodes actually running the stuff we want to run, making it burdensome to debug, correlate events, alert, etc., especially if the node crashes, hence why it&amp;rsquo;s a well established practice to collect all logs they emit to a central location, where all of those actions happen.&lt;/p&gt;
&lt;p&gt;One of the most popular log management stacks is the so-called ELK ( ElasticSearch for log indexing, Logstash for parsing/transforming them, and Kibana for visualisation, with either Filebeat or Fluentd / Fluent bit for log collection), which has a few drawbacks - most notably heavy resource consumption and licence changes, the latter leading to numerous forks, which will probably result in some chaos/incompatibilities in the future.&lt;/p&gt;
&lt;p&gt;A recent-ish contender in that space is Grafana Labs&amp;rsquo; &lt;a href=&#34;https://grafana.com/oss/loki/&#34;&gt;Loki&lt;/a&gt;. It&amp;rsquo;s a lightweight Prometheus-inspired tool, which can be run as a bunch of microservices for better and easier scale-out, or in &lt;code&gt;monolithic&lt;/code&gt; all-in-one mode. In contrast to ElasticSearch, it only indexes labels ( which are user defined ), the logs themselves ( &lt;code&gt;chunks&lt;/code&gt; ) are stored as-is, separately. That makes it more flexible and much cheaper with regards to storage and compute.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a variety of storage options - Cassandra (index and chunk), GCS/S3 (chunk), BigTable (chunk), DynamoDB(chunk) and the monolithic-only local storage ( which uses BoltDB internally for indexing). The last one is great for getting started/testing/non-huge projects, and the lack of redundancy ( since it writes to the local filesystem) can be offset by the storage provider ( e.g. a CSI plugin, GlusterFS, DRBD, or good old NFS). Visualisation from Loki is done with &lt;a href=&#34;https://grafana.com/oss/grafana/&#34;&gt;Grafana&lt;/a&gt; ( not really surprising since they&amp;rsquo;re both made by the same company), via the &lt;a href=&#34;https://grafana.com/docs/loki/latest/logql/&#34;&gt;LogQL&lt;/a&gt; PromQL-inspired query language.&lt;/p&gt;
&lt;p&gt;Having been using Loki for a few months in production, I&amp;rsquo;m really like it and hence this article on logs and using it on and with Nomad.&lt;/p&gt;
&lt;p&gt;There are two main ways to get logs from Nomad tasks into Loki ( one of which only works for Docker tasks), and I&amp;rsquo;ll discuss the pros and cons of each one later on.&lt;/p&gt;
&lt;h2 id=&#34;how-logs-on-nomad-work&#34;&gt;How logs on Nomad work&lt;/h2&gt;
&lt;p&gt;By default Nomad writes task logs to the &lt;code&gt;alloc/logs&lt;/code&gt; folder shared by all tasks in an allocation, which is stored locally on the client node running it. That makes accessing logs slightly burdensome and look like the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# get all current allocations for the job&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job status random-logger-example 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID            &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; random-logger-example
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Name          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; random-logger-example
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-04-27T23:28:29+02:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Type          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Priority      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Datacenters   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dc1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Namespace     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status        &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; running
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Periodic      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parameterized &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Task Group  Queued  Starting  Running  Failed  Complete  Lost
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;random      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;         &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;         &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latest Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; beffde05
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; running
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Deployment is running
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Deployed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Task Group  Desired  Placed  Healthy  Unhealthy  Progress Deadline
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;random      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;          2021-04-27T23:38:29+02:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Allocations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID        Node ID   Task Group  Version  Desired  Status   Created  Modified
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;529b074e  a394f493  random      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;        run      running  8s ago   3s ago
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# get the logs for an allocation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad alloc logs 529b074e
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As soon as there&amp;rsquo;s more than one allocation, you have to get the logs for each one by one; if you want to see the logs of an old allocation ( assuming it hasn&amp;rsquo;t been garbage collected already ), you have to run &lt;code&gt;nomad job status&lt;/code&gt; with the &lt;code&gt;-all-allocs&lt;/code&gt; flag to include non-current versions.&lt;/p&gt;
&lt;p&gt;Specific log options for the task driver can be configured on multiple levels - per task, per client, or in certain cases, most notably &lt;a href=&#34;https://www.nomadproject.io/docs/drivers/docker#logging-1&#34;&gt;Docker&lt;/a&gt;, per task driver.&lt;/p&gt;
&lt;p&gt;On the task level one can send all logs to a central syslog server (easily adaptable to fluentd, Splunk, etc. ) like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;syslog&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;logging&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;syslog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          config &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            syslog-address         &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;tcp://my-syslog-server:10514&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tag                    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;${NOMAD_TASK_NAME}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is perfectly fine, except that you have to do it on each and every task, which can quickly become burdensome, especially if your logging configuration changes one day, and you need to be on Docker Engine 20.10+, or use a logging driver that supports writing the logs locally as well as to the remote endpoint, otherwise &lt;code&gt;docker logs&lt;/code&gt; and &lt;code&gt;nomad alloc logs&lt;/code&gt; are unusable because the logs get sent directly. To facilitate that, there is use the new Docker driver-wide &lt;a href=&#34;https://www.nomadproject.io/docs/drivers/docker#logging-1&#34;&gt;logging configuration&lt;/a&gt;, but then you&amp;rsquo;re limited only to Docker logging drivers, and, the bigger issue in my opinion, you&amp;rsquo;re lacking context (unless the stuff you run detects and specifically logs that context).&lt;/p&gt;
&lt;p&gt;The, in my humble opinion, better option, is to have something that runs automatically on all client nodes, via a &lt;code&gt;system&lt;/code&gt; job, and collects all logs, like what everyone does with their Kubernetes clusters via Promtail, Fluend/Fluentbit, Datadog agent, Splunk Connect, etc. The biggest challenges with that are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;context - it&amp;rsquo;s good to know everything about where the logs are from - which task, namespace, client node, etc.&lt;/li&gt;
&lt;li&gt;discovery - how to find all new allocations to ship the logs of?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Recently, there have been some great news concerning those two challenges in regards to Docker-based tasks - &lt;a href=&#34;https://github.com/hashicorp/nomad/pull/9885&#34;&gt;this&lt;/a&gt; PR on Nomad that adds extra Docker labels with job, task, task group, node, namespace names, &lt;a href=&#34;https://github.com/hashicorp/nomad/pull/10156&#34;&gt;this&lt;/a&gt; PR that enables default logging options for the Docker driver on the Nomad side.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll describe how to collect and ship logs from Nomad, and then briefly go over how to run Loki, a lightweight log aggregation tool by Grafana Labs, on Nomad.&lt;/p&gt;
&lt;h2 id=&#34;logs-collection&#34;&gt;Logs collection&lt;/h2&gt;
&lt;p&gt;Nomad makes each allocation&amp;rsquo;s logs &lt;a href=&#34;https://www.nomadproject.io/api-docs/client#stream-logs&#34;&gt;available through the API&lt;/a&gt;, so ideally our logging agent should be able to connect to it directly. The only mainstream one that does that at the time of writing is:&lt;/p&gt;
&lt;h3 id=&#34;filebeat&#34;&gt;Filebeat&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.elastic.co/guide/en/beats/filebeat/current/configuration-autodiscover.html#_nomad&#34;&gt;Filebeat&lt;/a&gt;, Elastic&amp;rsquo;s log collection agent, has an auto-discovery module for Nomad, experimentally via &lt;a href=&#34;https://github.com/elastic/beats/pull/14954&#34;&gt;this PR&lt;/a&gt; which hasn&amp;rsquo;t been released in a stable version yet. If one wants to use ElasticSearch, or any of the compatible alternatives or companions ( Logstash, Kafka), that&amp;rsquo;s great. In theory one can configure Filebeat to output to a file, and then parse that file with another logging agent ( like Vector or Promtail) and ship the logs somewhere else, but IMHO that seems too much hassle for little benefit.&lt;/p&gt;
&lt;h3 id=&#34;promtail&#34;&gt;Promtail&lt;/h3&gt;
&lt;p&gt;Grafana provide a log collecting companion to Loki in the form of &lt;a href=&#34;https://grafana.com/docs/loki/latest/clients/promtail/&#34;&gt;Promtail&lt;/a&gt;, which is lightweight and easy to configure, but much more limited compared to filebeat, fluent* or Vector in terms of compatible sources. The biggest downside is that for Docker logs it can&amp;rsquo;t use Docker labels for extra context, and having only the container name and ID is often insufficient.&lt;/p&gt;
&lt;h3 id=&#34;vector&#34;&gt;Vector&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://vector.dev/&#34;&gt;Vector&lt;/a&gt; is a very fast and lightweight observability agent that can collect logs and metrics, transform and ship them to a variety of backends by &lt;a href=&#34;https://timber.io/&#34;&gt;Timber&lt;/a&gt;, a logging SaaS. They were recently &lt;a href=&#34;https://vector.dev/blog/datadog-acquisition/&#34;&gt;acquired&lt;/a&gt; by Datadog, who also have an agent and logging backend, so they obviously saw some value in them. And, very importantly for this story, Vector&amp;rsquo;s &lt;a href=&#34;https://vector.dev/docs/reference/configuration/sources/docker_logs/&#34;&gt;Docker logs source&lt;/a&gt; can use Docker labels to enrich the logs&amp;rsquo; context, and there&amp;rsquo;s a &lt;a href=&#34;https://vector.dev/docs/reference/configuration/sinks/loki/&#34;&gt;Loki &lt;em&gt;sink&lt;/em&gt;&lt;/a&gt; ( backend ). So, let&amp;rsquo;s see about deploying Vector as a &lt;code&gt;system&lt;/code&gt; job to collect logs from Docker.&lt;/p&gt;
&lt;p&gt;First, we need to allow Vector to access the Docker daemon and configure Nomad to add extra metadata; the easiest and cleanest way to do that is to pass the Docker socket as a host volume, which need to be declared at the host (Nomad client) level, and then mounted in the Vector job. We can do that read-only, and we can use ACLs to limit who can mount it to avoid allowing every job to mount it and do whatever.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;973451862&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;973451862&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Nomad client configuration for the Docker sock host volume and extra Docker labels&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
plugin &amp;#34;docker&amp;#34; {
  config {  
    # extra Docker labels to be set by Nomad on each Docker container with the appropriate value
    extra_labels = [&amp;#34;job_name&amp;#34;, &amp;#34;task_group_name&amp;#34;, &amp;#34;task_name&amp;#34;, &amp;#34;namespace&amp;#34;, &amp;#34;node_name&amp;#34;]
  }
}

client {
  host_volume &amp;#34;docker-sock-ro&amp;#34; {
    path = &amp;#34;/var/run/docker.sock&amp;#34;
    read_only = true
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;






  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;792618543&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;792618543&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;An ACL policy allowing the host volume to be mounted as read-only&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
host_volume &amp;#34;docker-sock-ro&amp;#34; {
  policy = &amp;#34;read&amp;#34; # read = read-only, write = read/write, deny to deny
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;Second, actually mount the newly available host volume inside the Vector task:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;894652317&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;894652317&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Declaring and mounting the Docker sock volume&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;

group &amp;#34;vector&amp;#34; {
    ...
    volume &amp;#34;docker-sock&amp;#34; {
      type = &amp;#34;host&amp;#34;
      source = &amp;#34;docker-sock&amp;#34;
      read_only = true
    }
    task &amp;#34;vector&amp;#34; {
      ...
      volume_mount {
        volume = &amp;#34;docker-sock&amp;#34;
        destination = &amp;#34;/var/run/docker.sock&amp;#34;
        read_only = true
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;Third, tell Vector to collect Docker&amp;rsquo;s logs and send them to Loki, enriching them with the metadata extracted from the Docker labels:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;619457328&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;619457328&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;toml&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Vector configuration file&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-toml&#34; &gt;&lt;code&gt;
          data_dir = &amp;#34;alloc/data/vector/&amp;#34;
          [sources.logs]
            type = &amp;#34;docker_logs&amp;#34;
          [sinks.out]
            type = &amp;#34;console&amp;#34;
            inputs = [ &amp;#34;logs&amp;#34; ]
            encoding.codec = &amp;#34;json&amp;#34;
          [sinks.loki]
            type = &amp;#34;loki&amp;#34; 
            inputs = [&amp;#34;logs&amp;#34;] 
            endpoint = &amp;#34;http://loki.example&amp;#34;
            encoding.codec = &amp;#34;json&amp;#34; 
            healthcheck.enabled = true 
            # since . is used by Vector to denote a parent-child relationship, and Nomad&amp;#39;s Docker labels contain &amp;#34;.&amp;#34;,
            # we need to escape them twice, once for TOML, once for Vector
            labels.job = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.job_name }}&amp;#34;
            labels.task = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.task_name }}&amp;#34;
            labels.group = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.task_group_name }}&amp;#34;
            labels.namespace = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.namespace }}&amp;#34;
            labels.node = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.node_name }}&amp;#34;
            # remove fields that have been converted to labels to avoid having them twice
            remove_label_fields = true
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;And that&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;Full example Vector job file with all those components and dynamic sourcing of the Loki address from Consul:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;578364192&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;578364192&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Vector job file&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
job &amp;#34;vector&amp;#34; {
  datacenters = [&amp;#34;dc1&amp;#34;]
  # system job, runs on all nodes
  type = &amp;#34;system&amp;#34; 
  update {
    min_healthy_time = &amp;#34;10s&amp;#34;
    healthy_deadline = &amp;#34;5m&amp;#34;
    progress_deadline = &amp;#34;10m&amp;#34;
    auto_revert = true
  }
  group &amp;#34;vector&amp;#34; {
    count = 1
    restart {
      attempts = 3
      interval = &amp;#34;10m&amp;#34;
      delay = &amp;#34;30s&amp;#34;
      mode = &amp;#34;fail&amp;#34;
    }
    network {
      port &amp;#34;api&amp;#34; {
        to = 8686
      }
    }
    # docker socket volume
    volume &amp;#34;docker-sock&amp;#34; {
      type = &amp;#34;host&amp;#34;
      source = &amp;#34;docker-sock&amp;#34;
      read_only = true
    }
    ephemeral_disk {
      size    = 500
      sticky  = true
    }
    task &amp;#34;vector&amp;#34; {
      driver = &amp;#34;docker&amp;#34;
      config {
        image = &amp;#34;timberio/vector:0.14.X-alpine&amp;#34;
        ports = [&amp;#34;api&amp;#34;]
      }
      # docker socket volume mount
      volume_mount {
        volume = &amp;#34;docker-sock&amp;#34;
        destination = &amp;#34;/var/run/docker.sock&amp;#34;
        read_only = true
      }
      # Vector won&amp;#39;t start unless the sinks(backends) configured are healthy
      env {
        VECTOR_CONFIG = &amp;#34;local/vector.toml&amp;#34;
        VECTOR_REQUIRE_HEALTHY = &amp;#34;true&amp;#34;
      }
      # resource limits are a good idea because you don&amp;#39;t want your log collection to consume all resources available 
      resources {
        cpu    = 500 # 500 MHz
        memory = 256 # 256MB
      }
      # template with Vector&amp;#39;s configuration
      template {
        destination = &amp;#34;local/vector.toml&amp;#34;
        change_mode   = &amp;#34;signal&amp;#34;
        change_signal = &amp;#34;SIGHUP&amp;#34;
        # overriding the delimiters to [[ ]] to avoid conflicts with Vector&amp;#39;s native templating, which also uses {{ }}
        left_delimiter = &amp;#34;[[&amp;#34;
        right_delimiter = &amp;#34;]]&amp;#34;
        data=&amp;lt;&amp;lt;EOH
          data_dir = &amp;#34;alloc/data/vector/&amp;#34;
          [api]
            enabled = true
            address = &amp;#34;0.0.0.0:8686&amp;#34;
            playground = true
          [sources.logs]
            type = &amp;#34;docker_logs&amp;#34;
          [sinks.out]
            type = &amp;#34;console&amp;#34;
            inputs = [ &amp;#34;logs&amp;#34; ]
            encoding.codec = &amp;#34;json&amp;#34;
          [sinks.loki]
            type = &amp;#34;loki&amp;#34; 
            inputs = [&amp;#34;logs&amp;#34;] 
            endpoint = &amp;#34;http://[[ range service &amp;#34;loki&amp;#34; ]][[ .Address ]]:[[ .Port ]][[ end ]]&amp;#34; 
            encoding.codec = &amp;#34;json&amp;#34; 
            healthcheck.enabled = true 
            # since . is used by Vector to denote a parent-child relationship, and Nomad&amp;#39;s Docker labels contain &amp;#34;.&amp;#34;,
            # we need to escape them twice, once for TOML, once for Vector
            labels.job = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.job_name }}&amp;#34;
            labels.task = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.task_name }}&amp;#34;
            labels.group = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.task_group_name }}&amp;#34;
            labels.namespace = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.namespace }}&amp;#34;
            labels.node = &amp;#34;{{ label.com\\.hashicorp\\.nomad\\.node_name }}&amp;#34;
            # remove fields that have been converted to labels to avoid having the field twice
            remove_label_fields = true
        EOH
      }
      service {
        check {
          port     = &amp;#34;api&amp;#34;
          type     = &amp;#34;http&amp;#34;
          path     = &amp;#34;/health&amp;#34;
          interval = &amp;#34;30s&amp;#34;
          timeout  = &amp;#34;5s&amp;#34;
        }
      }
      kill_timeout = &amp;#34;30s&amp;#34;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;Overall, that&amp;rsquo;s pretty a pretty good solution for the problem, with a lightweight and fast logging agent, some context, and everything is configured from within Nomad; however, that only works for Docker tasks and requires some (light) configuration on each client node.&lt;/p&gt;
&lt;h3 id=&#34;nomad_follower-promtail&#34;&gt;nomad_follower (+Promtail)&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s a project called &lt;a href=&#34;https://github.com/sofixa/nomad_follower&#34;&gt;&lt;code&gt;nomad_follower&lt;/code&gt;&lt;/a&gt;, which uses Nomad&amp;rsquo;s API to tail allocation logs. It requires no outside (of the Nomad system job running it) configuration, and compiles all the logs with metadata and context in a file which can then be scraped by a logging agent and sent to whatever logging backend you have. It&amp;rsquo;s a bit more obscure compared to Vector or Filebeat, and debugging it might require diving in the code ( speaking from experience, it didn&amp;rsquo;t accept my &lt;code&gt;logfmt&lt;/code&gt; formatted logs because it was looking at a timestamp starting in the first 4 characters of each line (used to deal with multi-line logs), but mine started after 5.. so i had to fork and patch it). Nonetheless, coupled with a logging agent it&amp;rsquo;s a fairly decent solution that works for all task types.&lt;/p&gt;
&lt;p&gt;Configuration is done via env variables ( like the file where to write all logs, the Nomad/Consul service tag to filter on, etc.), including Nomad API access/credentials. The logs are stored in JSON, with JSON-formatted logs inside the &lt;code&gt;data&lt;/code&gt; field, non-JSON (like &lt;code&gt;logfmt&lt;/code&gt;) logs are in the &lt;code&gt;message&lt;/code&gt; field, and there&amp;rsquo;s a bunch of metadata alongside them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alloc_id&lt;/li&gt;
&lt;li&gt;job_name&lt;/li&gt;
&lt;li&gt;job_meta&lt;/li&gt;
&lt;li&gt;node_name&lt;/li&gt;
&lt;li&gt;service_name&lt;/li&gt;
&lt;li&gt;service_tags&lt;/li&gt;
&lt;li&gt;task_meta&lt;/li&gt;
&lt;li&gt;task_name&lt;/li&gt;
&lt;/ul&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;317962458&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;317962458&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Example nomad_follower job file&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
  group &amp;#34;log-shipping&amp;#34; {
    count = 1
    restart {
      attempts = 2
      interval = &amp;#34;30m&amp;#34;
      delay    = &amp;#34;15s&amp;#34;
      mode     = &amp;#34;fail&amp;#34;
    }
    ephemeral_disk {
      size = 300
    }
    task &amp;#34;nomad-follower&amp;#34; {
      driver = &amp;#34;docker&amp;#34;
      config {
        image = &amp;#34;sofixa/nomad_follower:latest&amp;#34;
      }
      env {
        VERBOSE    = 4
        LOG_TAG    = &amp;#34;logging&amp;#34;
        LOG_FILE   = &amp;#34;${NOMAD_ALLOC_DIR}/nomad-logs.log&amp;#34;
        # this is the IP of the docker0 interface
        # and Nomad has been explicitly told to listen on it so that Docker tasks can communicate with the API
        NOMAD_ADDR = &amp;#34;http://172.17.0.1:4646&amp;#34; 
        # Nomad ACL token, could be sourced via template from Vault
        NOMAD_TOKEN = &amp;#34;xxxx&amp;#34; 
      }
      # resource limits are a good idea because you don&amp;#39;t want your log collection to consume all resources available 
      resources {
        cpu    = 100
        memory = 512
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;That will result in all allocations running on the same node as an allocation from this task with the &lt;code&gt;logging&lt;/code&gt; tag to get their logs collected and stored in &lt;code&gt;${NOMAD_ALLOC_DIR}/nomad-logs.log&lt;/code&gt;. Now all we need is to get something to read, parse and send those logs; considering I&amp;rsquo;d like to use Loki for storage, Promtail seems like the best option, but of course any of the alternatives could do the job just as well.&lt;/p&gt;
&lt;p&gt;Promtail&amp;rsquo;s &lt;a href=&#34;https://grafana.com/docs/loki/latest/clients/promtail/configuration/&#34;&gt;configuration&lt;/a&gt; is split into scrape (collection), pipeline that parses/transforms/extracts labels, and generic ( Loki adress, ports for healthcheck, etc.). It has a few ways to scrape logs, the one we need in this case is the &lt;code&gt;static&lt;/code&gt;, which tails a file; and we also need to parse the various fields ( via a json pipeline stage) and mark some as labels ( so they&amp;rsquo;re indexed and we can search by them).&lt;/p&gt;
&lt;p&gt;To scrape and parse the logs pre-collected by &lt;code&gt;nomad_follower&lt;/code&gt;, we need a configuration similar to this one:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;354261987&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;354261987&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;yaml&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Example Promtail YAML configuration file&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-yaml&#34; &gt;&lt;code&gt;
server:
  # port for the healthcheck
  http_listen_port: 3000
  grpc_listen_port: 0
positions:
  filename: ${NOMAD_ALLOC_DIR}/positions.yaml
client:
  url: http://loki.example/loki/api/v1/push
scrape_configs:
- job_name: local
  static_configs:
  - targets:
      - localhost
    labels:
      job: nomad
      __path__: &amp;#34;${NOMAD_ALLOC_DIR}/nomad-logs.log&amp;#34;
  pipeline_stages:
    # extract the fields from the JSON logs
    - json:
        expressions:
          alloc_id: alloc_id
          job_name: job_name
          job_meta: job_meta
          node_name: node_name
          service_name: service_name
          service_tags: service_tags
          task_meta: task_meta
          task_name: task_name
          message: message
          data: data
    # the following fields are used as labels and are indexed:
    - labels:
        job_name:
        task_name:
        service_name:
        node_name:
        service_tags:
    # an example regex to extract a field called time from within message( which is for non-JSON formatted logs,
    # so the assumption is that they&amp;#39;re in the logfmt format,
    # and a field time= is present with a timestamp in, which is the actual timestamp of the log)
    - regex:
        expression: &amp;#34;.*time=\\\&amp;#34;(?P&amp;lt;timestamp&amp;gt;\\S*)\\\&amp;#34;[ ]&amp;#34;
        source: &amp;#34;message&amp;#34;
    - timestamp:
        source: timestamp
        format: RFC3339
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;A full example system job file, with &lt;code&gt;nomad_follower&lt;/code&gt; and Promtail, with a template to dynamically source Loki&amp;rsquo;s address from within Consul:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;673821954&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;673821954&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Example log_follower job file&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
job &amp;#34;log-shipping&amp;#34; {
  datacenters = [&amp;#34;dc1&amp;#34;]
  type = &amp;#34;system&amp;#34;
  namespace = &amp;#34;logs&amp;#34;
  update {
    max_parallel      = 1
    min_healthy_time  = &amp;#34;10s&amp;#34;
    healthy_deadline  = &amp;#34;3m&amp;#34;
    progress_deadline = &amp;#34;10m&amp;#34;
    auto_revert       = false
  }
  group &amp;#34;log-shipping&amp;#34; {
    count = 1
    network {
      port &amp;#34;promtail-healthcheck&amp;#34; {
        to = 3000
      }
    }
    restart {
      attempts = 2
      interval = &amp;#34;30m&amp;#34;
      delay    = &amp;#34;15s&amp;#34;
      mode     = &amp;#34;fail&amp;#34;
    }
    ephemeral_disk {
      size = 300
    }
    task &amp;#34;nomad-forwarder&amp;#34; {
      driver = &amp;#34;docker&amp;#34;
      env {
        VERBOSE    = 4
        LOG_TAG    = &amp;#34;logging&amp;#34;
        LOG_FILE   = &amp;#34;${NOMAD_ALLOC_DIR}/nomad-logs.log&amp;#34;
        # this is the IP of the docker0 interface
        # and Nomad has been explicitly told to listen on it so that Docker tasks can communicate with the API
        NOMAD_ADDR = &amp;#34;http://172.17.0.1:4646&amp;#34;
        # Nomad ACL token, could be sourced via template from Vault
        NOMAD_TOKEN = &amp;#34;xxxx&amp;#34;
      }
      config {
        image = &amp;#34;sofixa/nomad_follower:latest&amp;#34;
      }
      # resource limits are a good idea because you don&amp;#39;t want your log collection to consume all resources available
      resources {
        cpu    = 100
        memory = 512
      }
    }
    task &amp;#34;promtail&amp;#34; {
      driver = &amp;#34;docker&amp;#34;
      config {
        image = &amp;#34;grafana/promtail:2.2.1&amp;#34;
        args = [
          &amp;#34;-config.file&amp;#34;,
          &amp;#34;local/config.yaml&amp;#34;,
          &amp;#34;-print-config-stderr&amp;#34;,
        ]
        ports = [&amp;#34;promtail-healthcheck&amp;#34;]
      }
      template {
        data = &amp;lt;&amp;lt;EOH
server:
  http_listen_port: 3000
  grpc_listen_port: 0

positions:
  filename: ${NOMAD_ALLOC_DIR}/positions.yaml

client:
  url: http://loki.example/loki/api/v1/push
scrape_configs:
- job_name: local
  static_configs:
  - targets:
      - localhost
    labels:
      job: nomad
      __path__: &amp;#34;${NOMAD_ALLOC_DIR}/nomad-logs.log&amp;#34;
  pipeline_stages:
    # extract the fields from the JSON logs
    - json:
        expressions:
          alloc_id: alloc_id
          job_name: job_name
          job_meta: job_meta
          node_name: node_name
          service_name: service_name
          service_tags: service_tags
          task_meta: task_meta
          task_name: task_name
          message: message
          data: data
    # the following fields are used as labels and are indexed:
    - labels:
        job_name:
        task_name:
        service_name:
        node_name:
        service_tags:
    # use a regex to extract a field called time from within message( which is for non-JSON formatted logs,
    # so the assumption is that they&amp;#39;re in the logfmt format,
    # and a field time= is present with a timestamp in, which is the actual timestamp of the log)
    - regex:
        expression: &amp;#34;.*time=\\\&amp;#34;(?P&amp;lt;timestamp&amp;gt;\\S*)\\\&amp;#34;[ ]&amp;#34;
        source: &amp;#34;message&amp;#34;
    - timestamp:
        source: timestamp
        format: RFC3339
EOH
        destination = &amp;#34;local/config.yaml&amp;#34;
      }
      # resource limits are a good idea because you don&amp;#39;t want your log collection to consume all resources available
      resources {
        cpu    = 500
        memory = 512
      }
      service {
        name = &amp;#34;promtail&amp;#34;
        port = &amp;#34;promtail-healthcheck&amp;#34;
        check {
          type     = &amp;#34;http&amp;#34;
          path     = &amp;#34;/ready&amp;#34;
          interval = &amp;#34;10s&amp;#34;
          timeout  = &amp;#34;2s&amp;#34;
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;h2 id=&#34;running-loki&#34;&gt;Running Loki&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; I personally consider it somewhat of an anti-pattern to run your log aggregation system on the same cluster as the one it&amp;rsquo;s aggregating logs from. If the cluster explodes, you can&amp;rsquo;t really access the logs to debug what happened and why. For smaller use cases, or if critical failure isn&amp;rsquo;t probable, it&amp;rsquo;s perfectly fine and will probably never cause any issues; past a certain point though, I&amp;rsquo;d recommend splitting it ( and other similarly scoped tools like monitoring) into a separate management cluster, or using the &lt;a href=&#34;https://grafana.com/products/cloud/&#34;&gt;hosted version&lt;/a&gt;, which includes a decent free tier (50GB and 14 days retention when it comes to logs).&lt;/p&gt;
&lt;p&gt;Like I mentioned &lt;a href=&#34;https://atodorov.me/2021/03/27/using-traefik-on-nomad/&#34;&gt;last time&lt;/a&gt;, even though one can include YAML configuration from Consul in Nomad jobs via the &lt;code&gt;template&lt;/code&gt; stanza, I prefer to have as much as possible in the Nomad file directly for better versioning and rollbackability ( YAML stored in Consul evolves independently of the Nomad job&amp;rsquo;s lifecycle, so rollbacking the latter won&amp;rsquo;t do anything about the former ).&lt;/p&gt;
&lt;p&gt;To run a basic, monolithic Loki service with local storage and unlimited retention, a host volume for said storage, Traefik as a reverse proxy (with TLS and a basic auth middleware attached, since &lt;a href=&#34;https://grafana.com/docs/loki/latest/operations/authentication/&#34;&gt;Loki doesn&amp;rsquo;t do auth itself&lt;/a&gt;) and Loki&amp;rsquo;s YAML configuration file embedded, you need something along these lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  datacenters &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dc1&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  type        &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    max_parallel      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    health_check      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;checks&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    min_healthy_time  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    healthy_deadline  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3m&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    progress_deadline &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5m&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;restart&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      attempts &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      interval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5m&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      delay    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;25s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      mode     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;delay&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;network&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;port&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        to &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;volume&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      type      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      read_only &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      source    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;grafana/loki:2.2.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-config.file&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/loki/local-config.yaml&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ports &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;volume_mount&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        volume      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        read_only   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;template&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;auth_enabled&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;server&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;http_listen_port&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;ingester&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycler&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;address&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;127&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;ring&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;kvstore&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;store&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;inmemory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;replication_factor&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;final_sleep&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # Any chunk not receiving new logs in this time will be flushed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;chunk_idle_period&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;h&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;       
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # All chunks will be flushed when they hit this age, default is 1h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;max_chunk_age&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;h&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;           
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # Loki will attempt to build chunks up to 1.5MB, flushing if chunk_idle_period or max_chunk_age is reached first
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;chunk_target_size&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1048576&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;chunk_retain_period&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&lt;/span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;max_transfer_retries&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;     # Chunk transfers disabled
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;schema_config&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;configs&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2020&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;store&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;boltdb&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;shipper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;object_store&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;filesystem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;v11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;index&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;prefix&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;index_&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;period&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;h&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;storage_config&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;boltdb_shipper&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;active_index_directory&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;boltdb&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;shipper&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;active&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;cache_location&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;boltdb&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;shipper&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;cache_ttl&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;h&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;         # Can be increased for faster performance over longer query periods, uses more disk space
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;shared_store&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;filesystem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;filesystem&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;directory&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;chunks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;compactor&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;working_directory&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;tmp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;boltdb&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;shipper&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;compactor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;shared_store&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;filesystem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;limits_config&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;reject_old_samples&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;reject_old_samples_max_age&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;168&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;h&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;chunk_store_config&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;max_look_back_period&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;table_manager&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;retention_deletes_enabled&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;retention_period&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/loki/local-config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;resources&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cpu    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        memory &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        port &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;check&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          name     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Loki healthcheck&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          port     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          type     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          path     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/ready&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          interval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;20s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          timeout  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#66d9ef&#34;&gt;check_restart&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            limit           &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            grace           &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;60s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ignore_warnings &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        tags &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;traefik.enable&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;traefik.http.routers.loki.tls&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;          # the middleware has to be declared somewhere else, we only attach it here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;          &amp;#34;traefik.http.routers.loki.middlewares&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;basicauth&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;file&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;So, which logging agent to use with Nomad ? As always, it depends. If you have ElasticSearch or any of the compatible alternatives, Filebeat is probably the best option due to the native support. If you only run Docker-based tasks, Vector collecting Docker Daemon&amp;rsquo;s logs (with Docker labels for context) is a pretty decent option. If neither, or you want more context ( like custom metadata) than what is available with Vector, nomad_follower is for you.&lt;/p&gt;
&lt;h2 id=&#34;discuss&#34;&gt;Discuss&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=27792007&#34;&gt;Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/hashicorp/comments/oh0ypm/logging_on_nomad_and_log_aggregation_with_loki/&#34;&gt;Reddit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/sofixa/status/1413557159841996800&#34;&gt;Twitter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://t.me/devops_lemons&#34;&gt;Telegram&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Using Traefik on Nomad</title>
      <link>/2021/03/27/using-traefik-on-nomad/</link>
      <pubDate>Sat, 27 Mar 2021 23:20:43 +0100</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2021/03/27/using-traefik-on-nomad/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Traefik is a great load balancer, which uses dynamic configuration from a variety of providers, notably in this case &lt;a href=&#34;https://doc.traefik.io/traefik/providers/consul-catalog&#34;&gt;Consul Catalog&lt;/a&gt;, which Nomad jobs can register into, providing a fast and easy way of having automatic virtual hosts and load balancing (ingress) for all of our Nomad jobs. There&amp;rsquo;s already a decent basic &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/load-balancing-traefik&#34;&gt;tutorial&lt;/a&gt; on &lt;a href=&#34;https://learn.hashicorp.com/&#34;&gt;Hashicorp Learn&lt;/a&gt; about doing just that, so I&amp;rsquo;ll focus on more advanced patterns and use cases that I&amp;rsquo;ve had to deal with.&lt;/p&gt;
&lt;p&gt;A full Nomad job file can be found &lt;a href=&#34;https://github.com/sofixa/nomad-examples/blob/main/traefik/traefik.nomad&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;base&#34;&gt;Base&lt;/h2&gt;
&lt;p&gt;Traefik&amp;rsquo; s configuration comes in two parts - static, like on which ports to listen, tracing, logs, etc. and dynamic, which comes from a third-party source(like Consul&amp;rsquo; s service catalogue) and is used to dynamically create routers (aka virtual hosts, which can be HTTP, TCP or UDP) and services(aka backends).&lt;/p&gt;
&lt;p&gt;The static configuration can be provided via CLI flags on start-up, or auto-reloaded YAML / TOML configuration files (which in the case of Traefik running on Nomad can come from Consul or Vault via the &lt;code&gt;template&lt;/code&gt; stanza), and contains the basics - entrypoints(on which ports to listen), access logs, metrics, etc. and middlewares (&lt;em&gt;Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Personally I prefer to have as much as possible in the Nomad file for better version history and rollbackability (if the configuration of a middleware comes from a YAML file stored in Consul, its updates are independent of Nomad, and you if you rollback your Nomad deployment to version X, it won&amp;rsquo; t rollback the value in Consul as well), and specifically in the case of Traefik, I think that CLI flags are a bit leaner and sufficiently readable for the basics.&lt;/p&gt;
&lt;p&gt;A small example, minimal Traefik configuration with the dashboard and API enabled, healthcheck, Prometheus-compatible metrics, access logs :&lt;/p&gt;
&lt;p&gt;


  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;897532614&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;897532614&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;yaml&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;YAML version&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-yaml&#34; &gt;&lt;code&gt;
# to make use of the file, we need to tell Traefik to watch the folder where it is
args = [&amp;#34;--providers.file.directory=local/traefik/&amp;#34;]
template {
  data        = &amp;lt;&amp;lt;EOH
  ping: {}
  accessLog: {}
  api:
    dashboard: true
  metrics:
    entryPoint: metrics
EOH
  destination = &amp;#34;local/traefik/base-config.yaml&amp;#34;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



vs&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;618397245&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;618397245&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;bash&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;CLI flags version&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-bash&#34; &gt;&lt;code&gt;
  args = [
    &amp;#34;--ping=true&amp;#34;,
    &amp;#34;--accesslog=true&amp;#34;,
    &amp;#34;--api=true&amp;#34;,
    &amp;#34;--metrics=true&amp;#34;,
    &amp;#34;--metrics.prometheus=true&amp;#34;,
    &amp;#34;--metrics.prometheus.entryPoint=metrics&amp;#34;,
  ]
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;I&amp;rsquo;ll provide most examples from here on in the CLI format, but converting them to TOML or YAML shouldn&amp;rsquo;t be very complicated in most cases with the help of the &lt;a href=&#34;https://doc.traefik.io/traefik/&#34;&gt;Traefik docs&lt;/a&gt;, which show everything in the different versions.&lt;/p&gt;
&lt;p&gt;The bare minimum to get Traefik running under Nomad looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik:2.4&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--entryPoints.http.address&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--accesslog&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--api&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--metrics&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--metrics.prometheus&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--metrics.prometheus.entryPoint&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--ping&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--ping.entryPoint&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ports &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;static-configuration-from-consul-via-templates&#34;&gt;Static configuration from Consul via templates&lt;/h3&gt;
&lt;p&gt;Traefik has a &lt;code&gt;file&lt;/code&gt; configuration provider (with automatic and hot reloads, hence the &lt;code&gt;noop&lt;/code&gt; change_mode), and with the following argument &lt;code&gt;--providersfile.directory=local/traefik/&lt;/code&gt; we can use Nomad templates to generate extra configuration coming from Consul:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;897642531&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;897642531&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Consul template&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
template {
  data        = &amp;#34;{{ key \&amp;#34;traefik/auth\&amp;#34; }} &amp;#34;
  destination = &amp;#34;local/traefik/auth.yaml&amp;#34;
  change_mode = &amp;#34;noop&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;As I already mentioned though, I prefer to have most of Traefik&amp;rsquo; s configuration in the Nomad job file directly for rollbackability.&lt;/p&gt;
&lt;h3 id=&#34;tls-configuration-from-vault-via-templates&#34;&gt;TLS configuration from Vault via templates&lt;/h3&gt;
&lt;p&gt;Using the same argument &lt;code&gt;--providers.file.directory=local/traefik/&lt;/code&gt; and the following templates, we can have TLS certificates stored in Vault with restarts (due to the fact that Traefik &lt;a href=&#34;https://github.com/traefik/traefik/issues/5495&#34;&gt;doesn&amp;rsquo;t support&lt;/a&gt; hot reload of certificates).&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;758243196&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;758243196&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;manual TLS from Vault&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
template {
  data = &amp;lt;&amp;lt;EOH
    tls:
      certificates:
        - certFile: &amp;#34;local/secret/example.com.crt&amp;#34;
          keyFile: &amp;#34;local/secret/example.com.key&amp;#34;
   EOH
  destination = &amp;#34;local/traefik/cert.yaml&amp;#34;
  change_mode = &amp;#34;noop&amp;#34;
}
template {
  data        = &amp;#34;{{ with secret \&amp;#34;secret/data/example.com\&amp;#34;  }}{{.Data.data.key}}{{end}}&amp;#34;
  destination = &amp;#34;local/secret/example.com.key&amp;#34;
  change_mode = &amp;#34;restart&amp;#34;
  splay       = &amp;#34;1m&amp;#34;
}
template {
  data        = &amp;#34;{{ with secret \&amp;#34;secret/data/example.com\&amp;#34;  }}{{.Data.data.crt}}{{end}}&amp;#34;
  destination = &amp;#34;local/secret/example.com.crt&amp;#34;
  change_mode = &amp;#34;restart&amp;#34;
  splay       = &amp;#34;1m&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;h2 id=&#34;consul-catalog&#34;&gt;Consul Catalog&lt;/h2&gt;
&lt;p&gt;To be able to create dynamic routers based on the services we have in Consul, Traefik needs some configuration (&lt;a href=&#34;https://doc.traefik.io/traefik/providers/consul-catalog/&#34;&gt;full doc here&lt;/a&gt;) on itself, and then tags on those services telling it the specifics:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;635712894&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;635712894&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;bash&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;flags version&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-bash&#34; &gt;&lt;code&gt;
  &amp;#34;--providers.consulcatalog=true&amp;#34;,
  &amp;#34;--providers.consulcatalog.exposedByDefault=false&amp;#34;,
  &amp;#34;--providers.consulcatalog.endpoint.address=http://172.17.0.1:8500&amp;#34;,
  &amp;#34;--providers.consulcatalog.prefix=traefik&amp;#34;,
  &amp;#34;--providers.consulcatalog.defaultrule=Host(`{{ .Name }}.example.com`)&amp;#34;,
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;OR&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;154632897&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;154632897&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;toml&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TOML version&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-toml&#34; &gt;&lt;code&gt;
[providers.consulCatalog]
  prefix           = &amp;#34;traefik&amp;#34;
  exposedByDefault = false
  defaultRule      = &amp;#34;Host(`{{ .Name }}.{{ index .Labels \&amp;#34;customLabel\&amp;#34;}}`)&amp;#34;
  constraints      = &amp;#34;Tag(`a.tag.name`)&amp;#34;
  [providers.consulCatalog.endpoint]
    address = &amp;#34;http://172.17.0.1:8500&amp;#34;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;Basically we enable the Consul Catalog provider and point it to a Consul agent, determine the &amp;ldquo;prefix&amp;rdquo; (tags on Consul services starting with
&lt;code&gt;prefix&lt;/code&gt; will be looked at for extra configuration, so for prefix = &lt;code&gt;traefik&lt;/code&gt;, tags like &lt;code&gt;traefik.http.routers.api.service = api@internal&lt;/code&gt; will be used), define
whether or not services are exposed by default (IMHO they shouldn&amp;rsquo;t be), the default routing rule (&lt;code&gt;Host {{.Name }}.example.com&lt;/code&gt; will use &lt;code&gt;service-name.example.com&lt;/code&gt; by default, over-ridable per-service via tags).&lt;/p&gt;
&lt;p&gt;Optionally we can also add constraints, which allows to do complex matching on tags to determine if a router should be created or not, mostly useful if &lt;code&gt;exposedByDefault&lt;/code&gt; is true.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; on the Consul address - since Traefik runs inside Docker, pointing it to the default &lt;code&gt;localhost:8500&lt;/code&gt; won&amp;rsquo;t work unless we run it in &lt;code&gt;network_mode = host &lt;/code&gt; (sharing the host&amp;rsquo;s networking, more on that below); in my case, I&amp;rsquo;m pointing it to the host&amp;rsquo;s &lt;code&gt;docker0&lt;/code&gt; IP, 172.17.0.1, which is accessible from all Docker containers, and is the same across all my hosts, and making Consul listen on the &lt;code&gt;docker0&lt;/code&gt; on top of usual localhost via the following configuration on the consul agent.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;139568274&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;139568274&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Consul agent configuration to make its API and DNS interfaces available from within docker containers&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
  addresses {
      http = &amp;#34;127.0.0.1 {{ GetInterfaceIP \&amp;#34;docker0\&amp;#34; }}&amp;#34;
  }
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;There&amp;rsquo;s also bunch of more advanced options around Consul auth, API read &lt;a href=&#34;https://www.consul.io/api-docs/featuresconsistetimeout&#34;&gt;consistency requirements&lt;/a&gt; and refreshInterval.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to make use of the provider in the Nomad job file via the &lt;a href=&#34;https://www.nomadproject.io/docs/job-specification/service&#34;&gt;&lt;code&gt;service&lt;/code&gt;&lt;/a&gt; stanza:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;935248716&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;935248716&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Example Traefik configuration via Consul tags&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
service {
  name = &amp;#34;my-service&amp;#34;
  port = &amp;#34;https&amp;#34;
  tags = [
    # HTTPS-only service which will be called when the URL is example.com or example.org/something
    # with my-middleware attached
    &amp;#34;traefik.enable=true&amp;#34;,
    &amp;#34;traefik.http.routers.my-service.rule=Host(`example.com`) || (Host(`example.org`) &amp;amp;&amp;amp; Path(`/something`))&amp;#34;,
    &amp;#34;traefik.http.routers.my-service.tls=true&amp;#34;,
    &amp;#34;traefik.http.routers.my-service.middlewares=my-middleware&amp;#34;,
  ]
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;If &lt;code&gt;exposedByDefault&lt;/code&gt; is true and you have all the configuration you need by default (e.g.http-&amp;gt;https redirect and other middlewares you need on the entrypoint level), you don&amp;rsquo;t even need per-service configuration unless you want to make something specific.&lt;/p&gt;
&lt;h2 id=&#34;networking&#34;&gt;Networking&lt;/h2&gt;
&lt;p&gt;There are two main ways you can configure Nomad in regards to Traefik networking - &lt;code&gt;host&lt;/code&gt; networking or with &lt;code&gt;static&lt;/code&gt; ports. Host networking, which is the same as Docker&amp;rsquo;s &lt;code&gt;--network=&amp;quot;host&amp;quot;&lt;/code&gt;, adds the task to the host&amp;rsquo;s network namespace and shares its network stack, and is generally not recommended.&lt;/p&gt;
&lt;p&gt;Static ports are host-level ports that are declared statically (compared to regular Nomad ports, which are ephemeral and random on the host level, and rather impractical for incoming http / https traffic) and forwarded to the task, like so:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;168973542&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;168973542&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;single network ports example&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
group &amp;#34;traefik&amp;#34; {
  network {
    port &amp;#34;http&amp;#34; {
      static = 80
    }
    port &amp;#34;https&amp;#34; {
      static = 443
    }
  }
  task &amp;#34;traefik&amp;#34; {
    driver = &amp;#34;docker&amp;#34;
    config {
      image = &amp;#34;traefik:2.4&amp;#34;
      args = [
        &amp;#34;--entryPoints.http.address=:80&amp;#34;,
        &amp;#34;--entryPoints.https.address=:443&amp;#34;,
      ]
      ports = [&amp;#34;http&amp;#34;, &amp;#34;https&amp;#34;]
      ...
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;This declares the ports 80 and 443, and attaches them to the Traefik task, which uses them as entrypoints named &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;https&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have multiple networks, you can make use of Nomad&amp;rsquo;s &lt;a href=&#34;https://www.nomadprojecconfigurationclient#host_network-stanza&#34;&gt;&lt;code&gt;host_network&lt;/code&gt;&lt;/a&gt; configuration, where you declare the available networks with aliases on the Nomad client and target them with the &lt;code&gt;host_network&lt;/code&gt; option on ports. ( In reality that&amp;rsquo;s what Nomad does behind the scenes, using the first network it finds for a hidden &lt;code&gt;default&lt;/code&gt; host_network, and attaching ports to it). Do note however, that if you declare &lt;code&gt;host_networks&lt;/code&gt;, ports which don&amp;rsquo;t specify the host_network will use the default value of &lt;code&gt;default&lt;/code&gt;, and if no such network exists, allocations will fail (silently for &lt;code&gt;system&lt;/code&gt; jobs).&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;716845923&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;716845923&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;multiple host_networks example&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
group &amp;#34;traefik&amp;#34; {
  network {
    port &amp;#34;http-priv&amp;#34; {
      static       = 80
      host_network = &amp;#34;private&amp;#34;
    }
    port &amp;#34;https-priv&amp;#34; {
      static       = 443
      host_network = &amp;#34;private&amp;#34;
    }
    port &amp;#34;http-pub&amp;#34; {
      static       = 80
      host_network = &amp;#34;public&amp;#34;
    }
    port &amp;#34;https-pub&amp;#34; {
      static       = 443
      host_network = &amp;#34;public&amp;#34;
    }
  }
  task &amp;#34;traefik&amp;#34; {
    driver = &amp;#34;docker&amp;#34;
    config {
      image = &amp;#34;traefik:2.4&amp;#34;
      args = [
        &amp;#34;--entryPoints.http.address=:80&amp;#34;,
        &amp;#34;--entryPoints.https.address=:443&amp;#34;,
      ]
      ports = [&amp;#34;http-priv&amp;#34;, &amp;#34;https-priv&amp;#34;, &amp;#34;http-pub&amp;#34;, &amp;#34;https-pub&amp;#34;]
      ...
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;This will make available the &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;https&lt;/code&gt; Traefik endpoints on both networks, and can of course be adapted to have specific endpoints only on specific networks.&lt;/p&gt;
&lt;p&gt;If for some reason the above doesn&amp;rsquo;t work for you (like if you use VRRP with a virtual IP floating between multiple machines, &lt;code&gt;host_network&lt;/code&gt; might not work due Nomad fingerprinting the networks on start-up, and since the floating IP won&amp;rsquo;t be available on all machines simultaneously, Nomad won&amp;rsquo;t bind to it), you can resort to host-mode networking (again, it &amp;rsquo; s generally discouraged) where the task shares the host&amp;rsquo;s networking, like so:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;467358219&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;467358219&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;host networking&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
group &amp;#34;traefik&amp;#34; {
  network {
    port &amp;#34;http&amp;#34; {
      static = 80
    }
    port &amp;#34;https&amp;#34; {
      static = 443
    }
  }
  task &amp;#34;traefik&amp;#34; {
    driver = &amp;#34;docker&amp;#34;
    config {
      image = &amp;#34;traefik:2.4&amp;#34;
      args = [
        &amp;#34;--entryPoints.http.address=:80&amp;#34;,
        &amp;#34;--entryPoints.https.address=:443&amp;#34;,
      ]
      ports        = [&amp;#34;http&amp;#34;, &amp;#34;https&amp;#34;]
      network_mode = &amp;#34;host&amp;#34;
      ...
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;p&gt;With this, Traefik will be available on ports 80 and 443 on &lt;em&gt;all&lt;/em&gt; network interfaces on the host.&lt;/p&gt;
&lt;h3 id=&#34;security&#34;&gt;Security&lt;/h3&gt;
&lt;p&gt;Traefik&amp;rsquo;s API, dashboard and metrics endpoints should be protected for security reasons, which can be done by putting them on a separate entrypoint which is firewalled off and/or adding middlewares with auth. The API and dashboard are represented by a special service, &lt;code&gt;api@internal&lt;/code&gt;, and Prometheus-compatible &lt;code&gt;/metrics&lt;/code&gt; can be put on a dedicated service as well (via the&lt;a href=&#34;https://doc.traefik.io/traefik/observability/metrics/prometheus#manualrouting&#34;&gt;&lt;code&gt;manualRouting = true&lt;/code&gt;&lt;/a&gt; option, which will create a &lt;code&gt;prometheus@internal&lt;/code&gt; service ).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a basic example of that, making use of tags on the Consul service of Traefik to dynamically configure the routes and middlewares:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;426758931&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;426758931&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;hcl&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;securing traefik&amp;rsquo;s API, dashboard and metrics&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;△&#34; data-label-collapse=&#34;▽&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-hcl&#34; &gt;&lt;code&gt;
task &amp;#34;traefik&amp;#34; {
  driver = &amp;#34;docker&amp;#34;
  config {
    image = &amp;#34;traefik:2.4&amp;#34;
    args = [
      # defining 3 entrypoints, on ports 80, 443 and 8080 ( for admin stuff)
      # and putting the healthcheck and metrics (with manual routing) on the admin endpoint
      &amp;#34;--entryPoints.http.address=:80&amp;#34;,
      &amp;#34;--entryPoints.https.address=:443&amp;#34;,
      &amp;#34;--entryPoints.admin.address=:8080&amp;#34;,
      &amp;#34;--entrypoints.http.http.redirections.entryPoint.to=https&amp;#34;,
      &amp;#34;--accesslog=true&amp;#34;,
      &amp;#34;--api=true&amp;#34;,
      &amp;#34;--metrics=true&amp;#34;,
      &amp;#34;--metrics.prometheus=true&amp;#34;,
      &amp;#34;--metrics.prometheus.entryPoint=admin&amp;#34;,
      &amp;#34;--metrics.prometheus.manualrouting=true&amp;#34;,
      &amp;#34;--ping=true&amp;#34;,
      &amp;#34;--ping.entryPoint=admin&amp;#34;,
      &amp;#34;--providers.consulcatalog=true&amp;#34;,
      &amp;#34;--providers.consulcatalog.endpoint.address=http://172.17.0.1:8500&amp;#34;,
      &amp;#34;--providers.consulcatalog.prefix=traefik&amp;#34;,
    ]
    ports = [&amp;#34;http&amp;#34;, &amp;#34;https&amp;#34;, &amp;#34;admin&amp;#34;]
  }
  service {
    name = &amp;#34;traefik&amp;#34;
    port = &amp;#34;https&amp;#34;
    tags = [
      # using Consul service tags prefixed by traefik (as defined in `--providers.consulcatalog.prefix`) 
      # to configure api&amp;amp;dashboard routers
      # with a headers check ( spoofable ) and a basic auth middleware attached inline
      &amp;#34;traefik.enable=true&amp;#34;,
      &amp;#34;traefik.http.routers.api.rule=Host(`traefik.example.com`) &amp;amp;&amp;amp; HeadersRegexp(`X-Real-Ip`, `^(10.1.1.1)$`)&amp;#34;,
      &amp;#34;traefik.http.routers.api.service=api@internal&amp;#34;,
      &amp;#34;traefik.http.routers.api.middlewares=basic-auth&amp;#34;,
      &amp;#34;traefik.http.middlewares.basic-auth.basicauth.users=admin:xxx&amp;#34;,
    ]
    # healthcheck using the appropriate port
    check {
      name     = &amp;#34;alive&amp;#34;
      type     = &amp;#34;http&amp;#34;
      port     = &amp;#34;admin&amp;#34;
      path     = &amp;#34;/ping&amp;#34;
      interval = &amp;#34;5s&amp;#34;
      timeout  = &amp;#34;2s&amp;#34;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;



&lt;h2 id=&#34;minimising-downtime-during-updates&#34;&gt;Minimising downtime during updates&lt;/h2&gt;
&lt;p&gt;Traditionally, an ingress/load balancer/reverse proxy such as Traefik would run on all client nodes and route appropriately. In such a scenario, you need some way to distribute the incoming traffic between the client nodes (such as round-robin DNS, L4 load balancing on the router/provider, BGP/Anycast, etc.), and to know their health and stop sending requests their way if they&amp;rsquo;re unavailable. One of the potential scenarios to deal with gracefully are node draining or configuration updates.&lt;/p&gt;
&lt;p&gt;To achieve that on Nomad with minimal downtime, we use &lt;code&gt;system&lt;/code&gt; jobs, staggered updates that don&amp;rsquo;t restart all instances simultaneously with the &lt;code&gt;uppdate&lt;/code&gt; stanza, and a combination of the &lt;code&gt; kill_timeout&lt;/code&gt; task parameter and Traefik&amp;rsquo;s &lt;a href=&#34;https://doc.traefik.io/traefik/routing/entrypoints/#lifecycle&#34;&gt;lifeCycle.requestAcceptGraceTimeout and lifeCycle.graceTimeOut&lt;/a&gt; to allow for requests to finish gracefully:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  region      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;global&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  datacenters &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dc1&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  type        &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # only one Traefik instance will be restarted at a time, with 1 minute delay between each such action
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # and automatic rollback to the previous version if the new one doesn&amp;#39;t pass the health check
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    max_parallel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    stagger      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1m&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    auto_revert  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # Nomad will wait for 30s after sending the kill signal to the task before forcefully shutting it down
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # by default it&amp;#39;s 10s ( not enough to properly drain connections )
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # and the maximum is limited by the max_kill_timeout setting on the Nomad client ( default 30s)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  kill_timeout &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;30s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik:2.4&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;        # Traefik will continue serving new requests for 15s while failing its healthcheck,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;        # giving time to downstream load balancers to take it out of their pool
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;        # and will *then* wait for 10s for existing requests to finish before shutting down,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;        # before Nomad forcefully kills it 30s after initiating
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.http.address&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.http.transport.lifeCycle.requestAcceptGraceTimeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.http.transport.lifeCycle.graceTimeOut&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.https.address&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;443&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.https.transport.lifeCycle.requestAcceptGraceTimeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;#34;--entryPoints.https.transport.lifeCycle.graceTimeOut&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;sidecars&#34;&gt;Sidecars&lt;/h2&gt;
&lt;p&gt;A sidecar is a task that runs alongside the main task doing something auxiliary like collecting logs, metrics, traces. I run two sidecars with my Traefik instances, one for logs and another for traces, due to the heavy load and specific configuration required for it.&lt;/p&gt;
&lt;h3 id=&#34;promtail-for-logs&#34;&gt;Promtail for logs&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/clients/promtail/&#34;&gt;Promtail&lt;/a&gt; is a logging agent from &lt;a href=&#34;https://grafana.com&#34;&gt;Grafana Labs&lt;/a&gt; that can get logs from a variety of sources, and then send them to &lt;a href=&#34;https://grafana.com/oss/loki/&#34;&gt;Loki&lt;/a&gt;, a highly-scalable yet lightweight log aggregation system inspired by Prometheus. It&amp;rsquo;s drastically simpler and lighter than ElasticSearch (sometimes a default choice for centralised log management) to setup, and does a very good job, so that&amp;rsquo;s what I use (there&amp;rsquo;s a blog post in the works on that too).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example &lt;code&gt;task&lt;/code&gt; block for a Promtail sidecar that can collect Traefik&amp;rsquo;s logs, parse them with a regex, and add some labels (index fields for searching), with the associated lifecycle policy(sidecar, poststart), healthcheck, resource limitations:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;promtail&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;grafana/promtail:2.2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-config.file&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/config.yaml&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-print-config-stderr&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # the only port required is for the healthcheck
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    ports &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;promtail_healthcheck&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # the template with Promtail&amp;#39;s YAML configuration file, configuring the files to scrape,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # the Loki server to send the logs to (based on a registered Consul service, but it could be a fixed URL),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # the regex to parse the Common Log Format (https://en.wikipedia.org/wiki/Common_Log_Format) used for access logs,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # and the labels ( HTTP method and status code)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;template&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;server&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;http_listen_port&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;grpc_listen_port&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;positions&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;filename&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;alloc&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;positions&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;url&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34;&lt;/span&gt; }}{{ .&lt;span style=&#34;color:#66d9ef&#34;&gt;Address&lt;/span&gt; }}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;{{ .&lt;span style=&#34;color:#66d9ef&#34;&gt;Port&lt;/span&gt; }}{{ &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt; }}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;loki&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;api&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;push&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;scrape_configs&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;job_name&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static_configs&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;targets&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;localhost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#66d9ef&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;traefik&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;__path__&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/alloc/logs/traefik.std*.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;pipeline_stages&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;regex&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;expression&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;^&lt;/span&gt;(&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;P&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;remote_addr&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;gt;&lt;/span&gt;[&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;.]&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;) &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; (&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;P&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;remote_user&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;gt;&lt;/span&gt;[&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;^&lt;/span&gt; ]&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;*&lt;/span&gt;) &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;[(&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;P&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;time_local&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;gt;&lt;/span&gt;.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;] &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;(?P&amp;lt;method&amp;gt;[^ ]*) (?P&amp;lt;request&amp;gt;[^ ]*) (?P&amp;lt;protocol&amp;gt;[^ ]*)&amp;#34; (P&amp;lt;status&amp;gt;[\d]+) (?        P&amp;lt;body_bytes_sent&amp;gt;[\d]+) &amp;#34;(?P&amp;lt;http_referer&amp;gt;[^&amp;#34;]*)&amp;#34; &amp;#34;(?P&amp;lt;http_user_agent&amp;gt;[^&amp;#34;]*)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;method&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;resources&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      cpu    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      memory &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # poststart, and sidecar=true, so Promtail will start *after* Traefik ( since it has nothing to do before Traefik isup and running),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # and run for as long as it does
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      hook    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;poststart&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      sidecar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # a service for a health check to determine the state of Promtail
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;check&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        type     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        port     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;promtail_healthcheck&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        path     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/ready&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        interval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        timeout  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;opentelemetry-collector-for-traces&#34;&gt;OpenTelemetry collector for traces&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;OpenTelemetry is a collection of tools, APIs, and SDKs. You use it to instrument, generate, collect, and export telemetry data(metrics, logs, and traces) for analysis in order to understand your software&amp;rsquo;s performance and behaviour.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s the future standard for telemetry adopted by just about everyone in the branch (Datadog, AWS, Splunk, Google,Elastic, Honeycomb, Lighstep come to mind), which would allow easily switching backends while keeping the same instrumentation and collector. At the time of writing, only the tracing part is stable, logs and metrics are a work in progress in various stages (Prometheus / OpenMetrics-compatible metrics are in alpha and &lt;a href=&#34;https://medium.com/opentelemetry/opentelemetry-metrics-roadmap-f4276fd070cf&#34;&gt;should be ready by the end of November 2021&lt;/a&gt;, while the logs spec is at the design stage), so personally I&amp;rsquo;d only use it for that part while waiting for the rest to be ready.&lt;/p&gt;
&lt;p&gt;The OpenTelemetry(OTEL) collector is an agent you can run alongside tasks (as a sidecar) or on each Nomad client as a &lt;code&gt;system&lt;/code&gt; job to collect traces (and one day metrics and logs).&lt;/p&gt;
&lt;p&gt;Specifically in regards to Traefik, we can use the latter&amp;rsquo;s &lt;a href=&#34;https://doc.traefik.io/traefik/observability/tracing/jaeger/&#34;&gt;Jaeger tracing compatibility&lt;/a&gt; combined with the Jaeger thrift compact receiver in OTEL. Due to the potentially heavy traffic, I run a collector per Traefik, as a sidecar task, just in case.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example &lt;code&gt;task&lt;/code&gt; block with the OpenTelemetry collector sidecar which sends traces to a Jaeger server (it could be anything else supported by OTEL), with extra tags set via the &lt;code&gt;JAEGER_TAGS&lt;/code&gt; env variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry-agent&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel/opentelemetry-collector-contrib:0.22.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;#34;--config&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;otel&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;yaml&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # pass the healthcheck and Jaeger Thrift compact ( UDP ) ports 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    ports &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel_health&amp;#34;, &amp;#34;jaeger_thrift_compact&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;    # extra JAEGER_TAGS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;env&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      JAEGER_TAGS &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &amp;#34;mytag&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;value,mytag2&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;test&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # it&amp;#39;s a good idea to limit the amount of resources available to the collector
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;resources&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cpu    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;128&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # Mhz
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    memory &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # MB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # prestart, and sidecar=true, so the OTEL collector will start *before* Traefik, and run for as long as it does
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    hook    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prestart&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sidecar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # a service for a health check to determine the state of the OTEL collector
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;check&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      name     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;health&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      type     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      port     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel_health&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      path     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      interval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      timeout  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # the template with OTEL&amp;#39;s YAML configuration file, defining the Jaeger Thrift compact (UDP) receiver,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # Jaeger Thrift ( HTTP ) exporter to a centrally running Jaeger server registered with Consul
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;  # and some boilerplate ( healthcheck, batching, retries)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;template&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#66d9ef&#34;&gt;receivers&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;jaeger&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#66d9ef&#34;&gt;protocols&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#66d9ef&#34;&gt;thrift_compact&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#66d9ef&#34;&gt;exporters&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;jaeger_thrift&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#66d9ef&#34;&gt;url&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;  {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger-api-thrift&amp;#34;&lt;/span&gt; }}{{ .&lt;span style=&#34;color:#66d9ef&#34;&gt;Address&lt;/span&gt; }}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;{{ .&lt;span style=&#34;color:#66d9ef&#34;&gt;Port&lt;/span&gt; }}{{ &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt; }}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;api&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;traces&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#66d9ef&#34;&gt;timeout&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;logging&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#66d9ef&#34;&gt;loglevel&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;debug&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#66d9ef&#34;&gt;processors&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;batch&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;queued_retry&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#66d9ef&#34;&gt;extensions&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;health_check&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;extensions&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;health_check&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#66d9ef&#34;&gt;pipelines&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#66d9ef&#34;&gt;traces&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;receivers&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;jaeger&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;processors&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;batch&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#66d9ef&#34;&gt;exporters&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;jaeger_thrift&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/otel/config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And to make use of it, Traefik needs the following extra arguments:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--tracing.jaeger=true&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--tracing.jaeger.localAgentHostPort=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;NOMAD_ADDR_jaeger_thrift_compact&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To send traces in the Jaeger thrift compact protocol to the IP and port(NOMAD_ADDR) of the jaeger_thrift_compact port.&lt;/p&gt;
&lt;h2 id=&#34;discuss&#34;&gt;Discuss&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=26608919&#34;&gt;Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/sofixa/status/1375937637987549186&#34;&gt;Twitter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://t.me/devops_lemons&#34;&gt;Telegram&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/Traefik/comments/meoib9/using_traefik_on_hashicorp_nomad/&#34;&gt;Reddit&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Please support Web Monetization if you want less ads on the web</title>
      <link>/2021/03/07/please-support-web-monetization-if-you-want-less-ads-on-the-web/</link>
      <pubDate>Sun, 07 Mar 2021 14:50:37 +0100</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2021/03/07/please-support-web-monetization-if-you-want-less-ads-on-the-web/</guid>
      <description>
        
          
          
          
        
        
        &lt;p&gt;&lt;em&gt;Note: Since it came up last time, I&amp;rsquo;m not in any way affiliated with any of the entities discussed in this article&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-is-web-monetization&#34;&gt;What is Web Monetization&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://webmonetization.org/&#34;&gt;Web Monetization&lt;/a&gt; is a browser API that allows content creators to monetize content, and content consumers to pay for it, anonymously, without ads or any friction, like paywalls and subscriptions.&lt;/p&gt;
&lt;p&gt;The basic concept is that a content creator signals they&amp;rsquo;re accepting payments, and the content consumer, via a browser extension, natively in the browser or by account linking, streams micropayments via the &lt;a href=&#34;https://interledger.org/&#34;&gt;Interledger&lt;/a&gt;, which supports a wide variety of providers and currencies ( real and crypto). The point is, as a consumer you pay for what you consume directly ( instead of indirectly via tracking and ads ) and proportionally.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s based on an open &lt;a href=&#34;https://webmonetization.org/specification.html&#34;&gt;specification&lt;/a&gt; which is still a work in progress, but fully functional.&lt;/p&gt;
&lt;h2 id=&#34;why-you-should-participate-in-it&#34;&gt;Why you should participate in it&lt;/h2&gt;
&lt;p&gt;A lot of people don&amp;rsquo;t like ads - be it because they find them wasteful, too obnoxious, too insistent, too intrusive, too dumb, etc. Even more people dislike tracking ( the art of following user actions across the internet to serve them more &amp;ldquo;relevant&amp;rdquo; ads based on their interests ), because that centralises a lot of power and knowledge in a few big companies ( Google, Facebook, etc. ), and allows precise targeting, which has been used for some nasty things. If I may quote the EFF directly:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Over the years, the machinery of targeted advertising has frequently been used for &lt;a href=&#34;https://www.americanbanker.com/news/payday-lenders-are-finding-ways-around-googles-ad-ban&#34;&gt;exploitation&lt;/a&gt;, &lt;a href=&#34;https://www.reuters.com/article/us-facebook-advertisers/u-s-charges-facebook-with-racial-discrimination-in-targeted-housing-ads-idUSKCN1R91E8&#34;&gt;discrimination&lt;/a&gt;, and &lt;a href=&#34;https://stoponlinevaw.com/wp-content/uploads/2018/10/Black-ID-Target-by-Russia-Report-SOVAW.pdf&#34;&gt;harm&lt;/a&gt;. The ability to target people based on ethnicity, religion, gender, age, or ability allows discriminatory ads for jobs, housing, and credit. Targeting based on credit history - or characteristics systematically associated with it - enables predatory ads for high-interest loans. Targeting based on demographics, location, and political affiliation helps purveyors of politically motivated disinformation and voter suppression.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A big part of the aforementioned people, and plenty of others, use ad blockers ( either as browser plugins like AdBlock Plus or Ublock (Origin), or DNS-level like PiHole and AdGuard Home ), which block ads, trackers and various analytics software, which aren&amp;rsquo;t necessarily the same as trackers - their main purpose is to analyse and aggregate users of the website, by country, language, browser, device type (mobile, PC), how they came upon the website, how much time they spent on what page, etc. compared to trackers&amp;rsquo; main purpose, which is to analyse per-user (anonymised, but still) interests and behaviour and recommend related ads.&lt;/p&gt;
&lt;p&gt;There are proposals by Google to supposedly improve upon the experience of tracking ( in part due to major browsers like Firefox blocking some of the technology enabling such tracking ), but there are &lt;a href=&#34;https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea&#34;&gt;major issues with them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nonetheless, for a lot of web content creators, ads remain the main way to make money of the content they produce, which could be just to compensate costs, as a reward for the time spent, or even potentially to allow transferring to full time content producing. And for a lot of content consumers, blocking ads removes the only way to &amp;ldquo;pay&amp;rdquo;, baring some direct donations scheme.&lt;/p&gt;
&lt;p&gt;Ideally, there should be an easy way to directly pay for the content you consume. In some cases you can subscribe and pay a monthly fee, but that could never cover it all - nobody will pay for every small blog, recipe/repair tutorial/gardening tips website/YouTube channel. How much value do they bring to you ? How much would you pay for them? How would you know they&amp;rsquo;re worth it without using them first, and why would they allow you to use them for free, when most users would be one-shot coming from a search engine? And then there&amp;rsquo;s non-profit open/crowdsourced institutions like &lt;a href=&#34;https://www.wikipedia.org/&#34;&gt;Wikipedia&lt;/a&gt; and the &lt;a href=&#34;https://archive.org/&#34;&gt;Internet Archive&lt;/a&gt; ( which is Web Monetized) whose principles make them incompatible with ads and paywalls/subscriptions and force them to rely on donations.&lt;/p&gt;
&lt;p&gt;Enter Web Monetization - with almost no friction, content consumers pay-per-use ( time spent ), automatically, and more or less anonymously. If content creators desire, there can be exclusive features only for &amp;ldquo;paying&amp;rdquo; ( participating in Web Monetization ) users, or no ads for them.&lt;/p&gt;
&lt;p&gt;Funnily enough, the concept is nothing new - the French Minitel ( more info on &lt;a href=&#34;https://en.wikipedia.org/wiki/Minitel&#34;&gt;Wikipedia&lt;/a&gt; and a fascinating read by the &lt;a href=&#34;https://spectrum.ieee.org/tech-history/cyberspace/minitel-the-online-world-france-built-before-the-web&#34;&gt;IEEE&lt;/a&gt;) system, in a sense a predecessor of the Internet, which among other things, contained specifically paying per time spent on pages.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;At the time of writing, there is only one Web Monetization provider - &lt;a href=&#34;https://coil.com&#34;&gt;Coil.com&lt;/a&gt;, but the API is open so in theory anyone can join in and compete with them.&lt;/p&gt;
&lt;p&gt;For content consumers, they provide browser extensions ( which are FOSS under the Apache 2.0 licence and available on &lt;a href=&#34;https://github.com/coilhq/web-monetization-projects&#34;&gt;GitHub&lt;/a&gt;) and subscriptions ($5 USD/month), which are spent at the rate of $0.36 USD an hour, providing for roughly 13 hours of content consumption. After $4.50 is spent, the rate is lowered to last until the end of the month. Said subscription also includes some perks, such as ad-free experiences on &lt;a href=&#34;https://help.coil.com/docs/membership/perks/imgur-emerald&#34;&gt;Imgur&lt;/a&gt; with Emerald and &lt;a href=&#34;https://help.coil.com/docs/membership/perks/cinnamon&#34;&gt;Cinnamon&lt;/a&gt; ( a subscription-based video content platform).&lt;/p&gt;
&lt;p&gt;For content creators, you need an account with a virtual wallet providers that supports ILP ( the Interledger protocol used to make the magic happen, like &lt;a href=&#34;https://www.uphold.com/&#34;&gt;Uphold&lt;/a&gt; and &lt;a href=&#34;https://gatehub.net/&#34;&gt;Gatehub&lt;/a&gt; ) and an HTML meta tag with the address of your wallet ( like so &lt;code&gt;&amp;lt;meta name=&amp;quot;monetization&amp;quot; content=&amp;quot;$ilp.uphold.com/8Q6r7F3XjXEi&amp;quot;&amp;gt;&lt;/code&gt; ) in the code of your website. The latter can be added manually or via any of the existing plugins (there are ones for &lt;a href=&#34;https://github.com/sabinebertram/hugo-webmonetization-component&#34;&gt;Hugo&lt;/a&gt;, &lt;a href=&#34;https://github.com/mrmuhammadali/gatsby-plugin-monetization&#34;&gt;Gatsby&lt;/a&gt;, &lt;a href=&#34;https://github.com/sorxrob/svelte-monetization&#34;&gt;Svelte&lt;/a&gt;, &lt;a href=&#34;https://wordpress.org/plugins/coil-web-monetization/&#34;&gt;Wordpress&lt;/a&gt;). For some cases where that&amp;rsquo;s impossible, Coil allow you to connect with YouTube and Twitch directly.&lt;/p&gt;
&lt;p&gt;Anonymity and privacy are provided by the way things work - that wallets are randomly generated IDs, Coil transfer the money, the wallet provider knows who the recipient is, the content creators knows how much they&amp;rsquo;ve received, but nobody knows everything. &lt;a href=&#34;https://coil.com/p/sharafian/Doubling-Down-on-Privacy/cD_ZiwT2J&#34;&gt;Here&amp;rsquo;s a post&lt;/a&gt; by Coil&amp;rsquo;s co-founder and CTO Ben Sharafian discussing wallet-side and sender-site (based on &lt;a href=&#34;https://privacypass.github.io/&#34;&gt;PrivacyPass&lt;/a&gt;) privacy techniques they and the wallet providers use to ensure everyone&amp;rsquo;s privacy is respected.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;p&gt;Of course, that could never replace premium subscription services like the Financial Times, or even direct ones like Substack due to the limited amounts involved, and it isn&amp;rsquo;t trying to - the point is to help monetise smaller sized websites ( and Youtube/Twitch channels ) &lt;em&gt;or&lt;/em&gt; open/crowdsourced/non-profit institutions by providing a decent alternatives to obnoxious ads (which millions of people block anyway ) and paywalls. For instance the &lt;a href=&#34;https://archive.org/&#34;&gt;Internet Archive&lt;/a&gt; and &lt;a href=&#34;https://hackernoon.com/&#34;&gt;Hacker Noon&lt;/a&gt; are web monetized; and so is this and some other small-scale personal blogs. It&amp;rsquo;s more similar to &lt;a href=&#34;https://www.buymeacoffee.com/&#34;&gt;Buy me a coffee&lt;/a&gt;, &lt;a href=&#34;https://www.patreon.com/&#34;&gt;Patreon&lt;/a&gt; and &lt;a href=&#34;https://github.com/sponsors&#34;&gt;GitHub Sponsors&lt;/a&gt;, only more automated, ubiquitous and with less effort.&lt;/p&gt;
&lt;p&gt;However, it&amp;rsquo;s relatively recent and not very popular yet - according to the &lt;a href=&#34;https://twitter.com/WebMotized&#34;&gt;WebMotized&lt;/a&gt; Twitter bot there&amp;rsquo;s only 1482 web monetized websites so far. Some more participation is needed, on both sides ( content creators and consumers) to make it a viable alternative to ads and some paywalls. I already did my part&lt;/p&gt;
&lt;h2 id=&#34;conclusion--summary&#34;&gt;Conclusion &amp;amp; Summary&lt;/h2&gt;
&lt;p&gt;Are you a content consumer or provider, or both? Don&amp;rsquo;t like ads and privacy invading tracking? Participate in Web Monetization!&lt;/p&gt;
&lt;p&gt;If I&amp;rsquo;ve convinced you, feel free to sign up for &lt;a href=&#34;https://help.coil.com/docs/membership/get-membership&#34;&gt;Coil&amp;rsquo;s membership&lt;/a&gt; to contribute and/or &lt;a href=&#34;https://help.coil.com/docs/account/monetize-content&#34;&gt;set up&lt;/a&gt; web monetization on your website. If not, check out the &lt;a href=&#34;#discuss&#34;&gt;Discuss&lt;/a&gt; section below, I&amp;rsquo;d really like to hear why not and what did I miss.&lt;/p&gt;
&lt;h2 id=&#34;discuss&#34;&gt;Discuss&lt;/h2&gt;
&lt;p&gt;Hacker News: &lt;a href=&#34;https://news.ycombinator.com/item?id=26375857&#34;&gt;https://news.ycombinator.com/item?id=26375857&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Twitter: &lt;a href=&#34;https://twitter.com/sofixa/status/1368561842835099649&#34;&gt;https://twitter.com/sofixa/status/1368561842835099649&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Why you should take a look at Nomad before jumping on Kubernetes</title>
      <link>/2021/02/27/why-you-should-take-a-look-at-nomad-before-jumping-on-kubernetes/</link>
      <pubDate>Sat, 27 Feb 2021 20:05:43 +0100</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2021/02/27/why-you-should-take-a-look-at-nomad-before-jumping-on-kubernetes/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;pre-introduction&#34;&gt;Pre-introduction&lt;/h2&gt;
&lt;p&gt;Recently I stumbled upon and then stumbled upon again on &lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/&#34;&gt;David Anderson&lt;/a&gt;&amp;rsquo;s interesting post about &amp;ldquo;new Kubernetes&amp;rdquo;, based on a discussion he had with &lt;a href=&#34;https://timewitch.net/&#34;&gt;Vallery Lancey&lt;/a&gt; about what they would do differently if they were rewriting Kubernetes from scratch. Interestingly, a decent part of the proposals for a &amp;ldquo;new Kubernetes&amp;rdquo; are design choices made by Hashicorp for &lt;a href=&#34;https://www.nomadproject.io/&#34;&gt;Nomad&lt;/a&gt;, which is a pretty underrated orchestrator, and drastically simpler ( one of the main goals of said &amp;ldquo;new Kubernetes&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Some people are aware that Docker Swarm kinda exists but is abandonware/on life support, and isn&amp;rsquo;t really recommended anymore, but it still comes up in discussions due to how easy it is to use. For most, that leaves Kubernetes as the only &amp;ldquo;serious&amp;rdquo; option, but it is a &lt;em&gt;very&lt;/em&gt; complex piece of software, with a lot of moving parts, which isn&amp;rsquo;t actually required or need in most cases.&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/nomad/kubernetes.jpg#center&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;This inspired me to write a series on Nomad, what it is, why it&amp;rsquo;s great, where it&amp;rsquo;s lacking and how to use it.&lt;/p&gt;
&lt;h2 id=&#34;introduction---what-is-nomad-and-why-its-great&#34;&gt;Introduction - what is Nomad and why it&amp;rsquo;s great&lt;/h2&gt;
&lt;p&gt;Hashicorp&amp;rsquo;s Nomad is a simple to run and maintain, yet very flexible task scheduler/orchestrator. It relies on plugins for execution, autoscaling and other features, and can run pretty much anything via its &lt;code&gt;task drivers&lt;/code&gt; - Docker, contairnerd, LXC, rkt, podman, Java, fork/exec, QEMU, firecracker, FreeBSD jails.&lt;/p&gt;
&lt;p&gt;It comes in the form of a single binary, run in two modes (&lt;code&gt;server&lt;/code&gt;, in groups of 3 or 5, which make scheduling decisions and host the APIs and configuration, and an unlimited number of &lt;code&gt;worker&lt;/code&gt;s which actually run whatever it is you want to run), and can be automatically clustered via &lt;a href=&#34;https://consul.io&#34;&gt;Consul&lt;/a&gt;. The configuration ( both for jobs and of Nomad itself) is in &lt;a href=&#34;https://github.com/hashicorp/hcl&#34;&gt;HCL&lt;/a&gt; (I&amp;rsquo;ll get into more detail about how great that is a bit later) or JSON (mainly for when the jobs are submitted by machines/scripts/tooling and not humans). Multiple clusters can be connected via &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/federation?in=nomad/manage-clusters&#34;&gt;multi-region federation&lt;/a&gt; for sharing ACLs and for API forwarding ( you can submit a job or request logs to any server for any region and it will be forwarded to the appropriate server). Deployments can be complex out of the box ( rolling, canary, blue/green), and everything is version controlled and rollbackable.&lt;/p&gt;
&lt;p&gt;Like most HashiCorp tools, it&amp;rsquo;s &amp;ldquo;open core&amp;rdquo;, meaning that the majority of features are available in an &lt;a href=&#34;https://github.com/hashicorp/nomad&#34;&gt;open source&lt;/a&gt; version, and some more advanced/enterprise-y ones ( in Nomad&amp;rsquo;s case, &lt;a href=&#34;https://www.hashicorp.com/blog/hashicorp-nomad-multi-cluster-deployment&#34;&gt;multi-region/cluster deployments&lt;/a&gt; - deploying something simultaneously to multiple separate clusters, policy as code with &lt;a href=&#34;https://docs.hashicorp.com/sentinel/nomad&#34;&gt;Sentinel&lt;/a&gt; and similar ) require upgrading to Nomad Enterprise.&lt;/p&gt;
&lt;h2 id=&#34;primitives&#34;&gt;Primitives&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;job&lt;/code&gt; is a declarative file which contains groups of tasks, each task being a container/binary/anything run by an exec driver&lt;/li&gt;
&lt;li&gt;&lt;code&gt;system&lt;/code&gt; jobs (run on all client nodes, equivalent to Kubernetes DaemonSets, for monitoring/logging agents/load balancers)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;periodic&lt;/code&gt; jobs (equivalent to cronjobs)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;service&lt;/code&gt;, which registers as a Consul service and is thus discoverable ( via API or DNS)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deployment&lt;/code&gt;, each version of a job, they&amp;rsquo;re tracked and can be rollbacked to&lt;/li&gt;
&lt;li&gt;&lt;code&gt;allocation&lt;/code&gt;, each instance of a task ( group ) on a node&lt;/li&gt;
&lt;li&gt;&lt;code&gt;namespace&lt;/code&gt;, a logical unit to organise jobs in and ACLs around&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;jobs&#34;&gt;Jobs&lt;/h3&gt;
&lt;p&gt;Example of a very basic job that runs a Docker container (&lt;code&gt;jaegertracing/all-in-one:1.21&lt;/code&gt;), with limits of 1000Mhz of CPU and 1024MB of RAM, and registers the service with Consul:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaegertracing/all-in-one:1.21&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;resources&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  cpu &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  memory &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger-query&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }            
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that this is a &lt;em&gt;very&lt;/em&gt; basic job, there are no healthchecks, no persistent storage, no extra configuration, no update strategy, no autoscaling, no exposed ports.&lt;/p&gt;
&lt;h4 id=&#34;deployment-history-and-rollback&#34;&gt;Deployment history and rollback&lt;/h4&gt;
&lt;p&gt;Nomad tracks each job&amp;rsquo;s full definitions and deployment history, and allows you to easily rollback and compare them, via the UI, CLI or API, e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List the versions of the job named &amp;#34;opentelemetry-collector&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job history opentelemetry-collector
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Version     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Stable      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-01-08T21:30:30+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Version     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Stable      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-01-08T21:29:48+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Check the difference between versions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job history -p opentelemetry-collector
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Version     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Stable      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-01-08T21:30:30+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Diff        &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+/- Job: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry-collector&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+/- Task Group: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry-collector&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  +/- Task: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry-collector&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    +/- Config &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          args&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;:  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--config=local/otel/config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      +/- image:    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel/opentelemetry-collector-contrib:0.15.0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel/opentelemetry-collector-contrib:0.16.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ports&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;health&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ports&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;1&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger_thrift_compact&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Version     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Stable      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-01-08T21:29:48+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Revert job &amp;#34;opentelemetry-collector&amp;#34; to version 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job revert opentelemetry-collector &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;state-tracking-and-job-planning&#34;&gt;State tracking and job planning&lt;/h4&gt;
&lt;p&gt;Nomad keeps the desired state and its history, and with &lt;code&gt;nomad job plan&lt;/code&gt;, similar to &lt;code&gt;terraform plan&lt;/code&gt;, allows us to preview what will change upon applying a new job file. There&amp;rsquo;s also a feature to verify nothing has changed between the &lt;code&gt;plan&lt;/code&gt; and &lt;code&gt;run&lt;/code&gt; (equivalent to &lt;code&gt;terraform apply&lt;/code&gt; with a plan file) with the &lt;code&gt;-check-index&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job plan otel.nomad
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+/- Job: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+/- Task Group: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; create/destroy update&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  +/- Task: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opentelemetry-collector&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;forces create/destroy update&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    +/- Config &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          args&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;:  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--config=local/otel/config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      +/- image:    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel/opentelemetry-collector-contrib:0.15.0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;otel/opentelemetry-collector-contrib:0.20.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ports&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;health&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ports&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;1&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jaeger_thrift_compact&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Scheduler dry-run:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- All tasks successfully allocated.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Job Modify Index: &lt;span style=&#34;color:#ae81ff&#34;&gt;413&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To submit the job with version verification run:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad job run -check-index &lt;span style=&#34;color:#ae81ff&#34;&gt;413&lt;/span&gt; otel.nomad
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;When running the job with the check-index flag, the job will only be run &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;job modify index given matches the server-side version. If the index has
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;changed, another user has modified the job and the plan&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt;s results are
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;potentially invalid.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Overall, it&amp;rsquo;s a very useful feature, especially when collaborating, locally or via CI/CD.&lt;/p&gt;
&lt;h4 id=&#34;checking-the-status-and-logs&#34;&gt;Checking the status and logs&lt;/h4&gt;
&lt;p&gt;To check the status of a job, there are a few commands under &lt;code&gt;nomad job&lt;/code&gt; and &lt;code&gt;nomad alloc&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad job status otel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID            &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; otel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Name          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; otel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Submit Date   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-02-27T20:41:29+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Type          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Priority      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Datacenters   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dc1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Namespace     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status        &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; running
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Periodic      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Parameterized &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Task Group  Queued  Starting  Running  Failed  Complete  Lost
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;otel      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;         &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;         &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latest Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID          &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ea533b6f
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; successful
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Deployment completed successfully
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Deployed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Task Group  Desired  Placed  Healthy  Unhealthy  Progress Deadline
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;otel      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;          2021-02-27T20:51:45+01:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Allocations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ID        Node ID   Task Group  Version  Desired  Status   Created  Modified
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;89031cfd  d3cbeb7e  otel      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;        run      running  20s ago  4s ago
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# logs are at the allocation level ( similar to Kubernetes, where they&amp;#39;re at the container level), so we get them with the alloc id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nomad alloc logs 89031cfd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;...&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;lifecycle-and-sidecars&#34;&gt;lifecycle and sidecars&lt;/h4&gt;
&lt;p&gt;Nomad allows defining the lifecycle of tasks in task groups, and their status, with the &lt;code&gt;lifecycle&lt;/code&gt; stanza. We can have &lt;code&gt;prestart&lt;/code&gt; ( for initialisation ), &lt;code&gt;poststart&lt;/code&gt; ( companion, for proxying (aka ambassador and adapter pattern in Kubernetes )) or &lt;code&gt;poststop&lt;/code&gt; for clean up, and via the &lt;code&gt;sidecar&lt;/code&gt; bool we define whether or not it should run as long as the main task(s), e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;init&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      hook &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prestart&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      sidecar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;alpine/httpie&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      command &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://some-internal-service-for-provisioning-stuff.local/v1/new&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#34;job_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;NOMAD_JOB_ID&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;!&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fluentd&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      hook &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;poststart&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # should start after the main task
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      sidecar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # should run as long as the main task does, and be restarted if it fails
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fluentd/fluentd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main-app&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cleanup&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;lifecycle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      hook &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;poststop&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;alpine&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      command &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rm -rf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/var/lib/volume-with-super-secret-data&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;aclrbac&#34;&gt;ACL/RBAC&lt;/h3&gt;
&lt;p&gt;ACL ( access-control list ), or RBAC ( role-based access control ) as it&amp;rsquo;s known in Kubernetes, allow defining who can do what, so that not everyone with network access can have full administrator privileges and run/stop whatever. Nomad&amp;rsquo;s ACL system is pretty similar to Consul and Vault&amp;rsquo;s, and uses JSON ( mostly for non-humans ) or HCL to define &lt;code&gt;policies&lt;/code&gt; with &lt;code&gt;rules&lt;/code&gt;, which describe what action is allowed on what object.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# a basic policy which allows the predefined read policy with read-only access to list and read:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# job, volume and scaling details, and extra capabilities for job creation and log access within the default namespace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  policy &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;read&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  capabilities &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;submit-job&amp;#34;,&amp;#34;dispatch-job&amp;#34;,&amp;#34;read-logs&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Assignment of policies is done only via the CLI, unlike Kubernetes where that happens in YAML, as does policy management:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create/update the policy within Nomad&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad acl policy apply -description &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Application Developer policy&amp;#34;&lt;/span&gt; my-policy my-policy.hcl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad acl token create -name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Test token&amp;#34;&lt;/span&gt; -policy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;my-policy -type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;client
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Accessor ID  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 4e3c1ac7-52d0-6c68-94a2-5e75f17e657e
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Secret ID    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0be3c623-cc90-3645-c29d-5f0629084f68
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Name         &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Test token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Type         &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; client
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Global       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Policies     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;my-policy&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Create Time  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2021-02-10 18:41:53.851133 +0000 UTC
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Create Index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Modify Index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just for comparison, the (in my opinion weirdly verbose to write due to YAML ) syntax for the equivalent in Kubernetes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Role&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;namespace&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;default&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;rules&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;apiGroups&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;] 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;resources&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;services&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#75715e&#34;&gt;# a Nomad job contains both the pod equivalents ( task groups ) and services&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;verbs&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;logs&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;update&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;patch&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And with this token, either as an env variable ( &lt;code&gt;NOMAD_TOKEN&lt;/code&gt;) or flag (&lt;code&gt;-token&lt;/code&gt;) for the CLI or HTTP header ( &lt;code&gt;X-Nomad-Token&lt;/code&gt;) for the API, we can do things.&lt;/p&gt;
&lt;p&gt;ACL policies and tokens are optionally shared with federated clusters for simplified management. We can also have ephemeral tokens via Vault&amp;rsquo;s &lt;a href=&#34;https://www.vaultproject.io/docs/secrets/nomad&#34;&gt;Nomad Secret Backend&lt;/a&gt;, which generates single/short-use tokens with specific policies, but there&amp;rsquo;s no implicit or explicit job role equivalent to Kubernetes&amp;rsquo; &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/&#34;&gt;Service Accounts&lt;/a&gt;, one has to pass through Vault for that ( assign a Vault policy to the job).&lt;/p&gt;
&lt;h2 id=&#34;simplicity&#34;&gt;Simplicity&lt;/h2&gt;
&lt;p&gt;Nomad is easy to install, maintain, update and scale, even with &amp;ldquo;advanced&amp;rdquo; features such as linking multiple clusters across datacenters/regions.&lt;/p&gt;
&lt;h3 id=&#34;running-locally&#34;&gt;Running locally&lt;/h3&gt;
&lt;p&gt;Running Nomad locally for development/testing is just a matter of downloading the binary and running &lt;code&gt;nomad agent -dev&lt;/code&gt; ( significantly easier than &lt;a href=&#34;https://microk8s.io/&#34;&gt;microk8s&lt;/a&gt; or &lt;a href=&#34;https://github.com/kubernetes/minikube&#34;&gt;minikube&lt;/a&gt; or &lt;a href=&#34;https://github.com/kubernetes-sigs/kind&#34;&gt;kind&lt;/a&gt;), and the same goes for Consul and Vault ( which you might need to replicate the production Nomad environment locally).&lt;/p&gt;
&lt;h3 id=&#34;upgrading&#34;&gt;Upgrading&lt;/h3&gt;
&lt;p&gt;Upgrading Nomad servers is just a matter of replacing the binary and restarting the service. There are detailed &lt;a href=&#34;https://www.nomadproject.io/docs/upgrade/upgrade-specific&#34;&gt;upgrade guides&lt;/a&gt; which list the main changes and potential breaking ones/things to take care of, but it&amp;rsquo;s relatively rare ( and will be even less so since it&amp;rsquo;s already on 1.0+). Clients need to be drained first before upgrading ( for which there&amp;rsquo;s also a &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/node-drain&#34;&gt;detailed guide&lt;/a&gt; ), and the behaviour of jobs during that operation can be tweaked via the &lt;a href=&#34;https://www.nomadproject.io/docs/job-specification/migrate&#34;&gt;&lt;code&gt;migrate&lt;/code&gt;&lt;/a&gt; stanza.&lt;/p&gt;
&lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt;
&lt;p&gt;Nomad collects &lt;a href=&#34;https://www.nomadproject.io/docs/operations/telemetry&#34;&gt;extensive metrics&lt;/a&gt; on itself and everything it runs within it, which can be send to compatible agents ( statsD, Datadog ) or scraped by a Prometheus/OpenMetrics-compatible scraper, and they even have &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/prometheus-metrics&#34;&gt;a guide&lt;/a&gt; on setting up Prometheus to monitor and alert.&lt;/p&gt;
&lt;h3 id=&#34;clustermulti-cluster-joining&#34;&gt;Cluster/multi-cluster joining&lt;/h3&gt;
&lt;p&gt;Forming/joining a cluster can be done manually via &lt;code&gt;nomad server join&lt;/code&gt;, via the &lt;a href=&#34;https://www.nomadproject.io/docs/configuration/server_join&#34;&gt;server_join&lt;/a&gt; configuration block( which can use static IPs/DNS, or dynamic &lt;a href=&#34;https://www.nomadproject.io/docs/configuration/server_join#cloud-auto-join&#34;&gt;cloud auto-join&lt;/a&gt; ( based on cloud provider tags or similar)), or via Consul.
Federation is done by joining a server in another cluster via its WAN IP/DNS and port:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nomad server join 172.31.26.138:4648 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;integrations&#34;&gt;Integrations&lt;/h2&gt;
&lt;p&gt;Nomad has an extensive &lt;a href=&#34;https://www.nomadproject.io/api-docs&#34;&gt;API&lt;/a&gt; (which includes cool recent additions like the &lt;a href=&#34;https://www.hashicorp.com/blog/building-on-top-of-hashicorp-nomad-s-event-stream&#34;&gt;event stream&lt;/a&gt;, allowing the creation integrations and tools that act based on what happens in your Nomad cluster), and it integrates well with a bunch of other tools, some of them from Hashicorp, nicely complementing Nomad to rival the features of the more feature-rich Kubernetes and its ecosystem.&lt;/p&gt;
&lt;p&gt;Things like &lt;a href=&#34;https://www.nomadproject.io/docs/integrations/consul-integration&#34;&gt;Service Discovery and K/V storage&lt;/a&gt; (Services and ConfigMaps respectively) and &lt;a href=&#34;https://www.nomadproject.io/docs/integrations/vault-integration&#34;&gt;secret storage&lt;/a&gt; (Secrets) and even features part of the larger Kubernetes ecosystem like &lt;a href=&#34;https://www.nomadproject.io/docs/integrations/consul-connect&#34;&gt;service mesh&lt;/a&gt; are delegated to other, existing, well-used and battle tested parts of the HashiStack (Consul and Vault), which makes sense - it follows the Unix philosophy &amp;ldquo;do one thing and do it well&amp;rdquo;, and makes things easier for Hashicorp and its users - Consul and Vault are already heavily used, stable and very popular in their respective niches, and the decoupling and separation of concerns allows us to use them outside of Nomad (e.g. you can use Vault, hosted or not on Nomad, for secret storage/dynamic secrets/auth for apps running in Nomad or anywhere else; maybe you even already have a running Vault cluster, and you can just connect your Nomad cluster to it and you have the same storage for all your secrets, regardles of where they are used from).&lt;/p&gt;
&lt;p&gt;The big downside is that if you just want to run a Nomad cluster, you kinda &lt;em&gt;need&lt;/em&gt; two other tools to install, maintain, stay up to date on, etc. but seeing that all three are similar ( single binary, Raft consensus algorithm, great documentation including very detailed upgrade guides ), it&amp;rsquo;s not &lt;em&gt;that&lt;/em&gt; complex to achieve.&lt;/p&gt;
&lt;p&gt;There are also integrations, via Consul, with third-party tools such as Traefik and Fabio for automatic Reverse proxy/Load Balancing.&lt;/p&gt;
&lt;h3 id=&#34;integrated-templating&#34;&gt;Integrated Templating&lt;/h3&gt;
&lt;h4 id=&#34;from-consul-or-vault&#34;&gt;From Consul or Vault&lt;/h4&gt;
&lt;p&gt;One way that you can make use of Vault and Consul in Nomad job files is via the &lt;a href=&#34;https://www.nomadproject.io/docs/job-specification/template&#34;&gt;&lt;code&gt;template&lt;/code&gt;&lt;/a&gt; stanza (configuration block) in nomad jobs, which allows the creation of files or environment variables based on templates, and is based Hashicorp&amp;rsquo;s venerable &lt;a href=&#34;https://github.com/hashicorp/consul-template&#34;&gt;consul-template&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# creating a YAML configuration file from Consul K/V and services, Nomad metadata and Vault secrets:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;template&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;bind_port&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;   {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;env&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;NOMAD_PORT_db&amp;#34; }}  # the port &amp;#34;db&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;scratch_dir&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;env&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;NOMAD_TASK_DIR&amp;#34;&lt;/span&gt; }}&lt;span style=&#34;color:#75715e&#34;&gt; # the task folder
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;node_id&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;     {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;env&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;node.unique.id&amp;#34;&lt;/span&gt; }}&lt;span style=&#34;color:#75715e&#34;&gt; # the unique ID of the Nomad node
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;service_key&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service/my-key&amp;#34;&lt;/span&gt; }}&lt;span style=&#34;color:#75715e&#34;&gt; # populated by service/my-key from Consul K/V store
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;loki_addr&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;   {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;loki&amp;#34; }}{{ .Address }}:{{ .Port }}{{ end }} # populated by the IP and port of the service named &amp;#34;loki&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Consul&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;s&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Service&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;catalogue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;some_secret&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; {{ &lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;secret&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;secret/data/my-secret\&amp;#34;  }}{{.Data.data.value}} {{end}}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # populated by the secret/my-secret secret in Vault
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;EOH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local/file.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# doing the same but instead of writing in a YAML file, export the values as env variables:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;template&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  destination &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;secrets/file.env&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # secrets is a special, per-task folder that you can use to store secrets and isn&amp;#39;t browseable via API/CLI/UI. More on that below
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  env         &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;hclv2&#34;&gt;HCLv2&lt;/h4&gt;
&lt;p&gt;HCLv2 greatly improves upon HCLv1 with more dynamism and better type management. One can use variables, for loops, include files, etc. Some examples with common use cases:&lt;/p&gt;
&lt;p&gt;Using an &amp;ldquo;env&amp;rdquo; variable to determine if we&amp;rsquo;re in local dev or production, and set variables accordingly; and using a list variable with the default arguments in all cases, default ones for local/production, additional arguments, and merging them.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: &lt;em&gt;local&lt;/em&gt; variables are local to the file, and &lt;em&gt;variable&lt;/em&gt; variables are more akin to function parameters ( they can be passed via file, env variable, with defaults, etc.)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;variable&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;env&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  default &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;variable&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;list&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    default &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;locals&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  datacenter &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; var.env &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local&amp;#34; ? &amp;#34;dc1&amp;#34; : &amp;#34;eu-west-1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; var.env &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  default_args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--something&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  local_args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--verbose&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  prod_args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--production-mode 1&amp;#34;, &amp;#34;--secure&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; var.env &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;local&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;concat&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;default_args&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;local_args&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;args&lt;/span&gt;) &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;concat&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;default_args&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;prod_args&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;args&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  datacenters &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;datacenter&lt;/span&gt;]&lt;span style=&#34;color:#75715e&#34;&gt; # Nomad expects a list here, hence the []
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;task&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      driver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;config&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        image &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;registry.test.com:0.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        args &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;a&lt;/span&gt;]&lt;span style=&#34;color:#75715e&#34;&gt; # Nomad expects a list here, hence the []
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For comparison, either of those are impossible in Kubernetes-land without third-party tooling - Helm, jsonnet, tanka, ytt, etc. for basic templating/logic, which come with a lot of overhead on top of YAML, and things like &lt;a href=&#34;https://learn.hashicorp.com/tutorials/vault/agent-kubernetes?in=vault/kubernetes&#34;&gt;Vault Agent&lt;/a&gt; for sidecar secret injection or the &lt;a href=&#34;https://github.com/kubernetes-sigs/secrets-store-csi-driver&#34;&gt;Secrets Store CSI driver&lt;/a&gt;, which allows reading secrets as filesystem objects via a CSI driver. Of course, Kubernetes ConfigMaps and Secrets exist for the latter issue, but there are several limitations compared to the Nomad way of doing things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes Secrets aren&amp;rsquo;t really secret, they&amp;rsquo;re base64 encoded strings stored in etcd ( so you&amp;rsquo;re relying on it being encrypted for &amp;ldquo;security&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;Kubernetes ConfigMaps and Secrets are fully static, you can&amp;rsquo;t throw in any dynamism ( an if, a for loop, the IP/port of a service, etc.)&lt;/li&gt;
&lt;li&gt;both are disconnected from deployments - if you update a ConfigMap used by a Pod, the latter needs to be restarted for the changes to be recongized ( compared to Nomad&amp;rsquo;s &lt;code&gt;change_mode&lt;/code&gt; which allows you to control how and if the task is restarted/reloaded upon configuration change)&lt;/li&gt;
&lt;li&gt;you can&amp;rsquo;t mix and match, like having a single file with secrets, a service address, K/V config, etc. ( unless you do somethig manually with an initContainer and bash)&lt;/li&gt;
&lt;li&gt;you can&amp;rsquo;t have dynamic secrets ( like AWS or database credentials with a limited time to live) without external tooling taking care of renews and restarts&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deployment-primitives&#34;&gt;Deployment primitives&lt;/h3&gt;
&lt;p&gt;Nomad supports natively a few deployment methods - rolling updates ( each instance is updated X at a time ), canary ( a small part of the running instances are updated, they&amp;rsquo;re monitored for anomalies/bugs/errors/etc., and if everything is fine over some period of time, the rest are updated as well) and blue/green (two equally-sized environments are running, blue and green one, but only one is serving traffic; the other one gets the updated version in full, tests are run, and once all is good, traffic is switched to it ), and can do automated rollbacks.&lt;/p&gt;
&lt;p&gt;All of that, including timeouts, counts, etc. is configured via the &lt;code&gt;update&lt;/code&gt; stanza :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# generic configuration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # 3 allocations 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  max_parallel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # number of instances to upgrade in parallel
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  health_check &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;checks&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # what determines the state of the allocation - it could be health *checks*, *state* (if all tasks are running) or *manual* for human/monitoring/etc. via the API
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# canary
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # 3 allocations 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  max_parallel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  canary &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # 1 canary allocation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# blue/green
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # 3 allocations 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  max_parallel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  canary &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 3 # canary&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;max_parallel&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Green&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;env&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Canaries or blue/green deployments can be promoted via the CLI, web UI or API ( e.g. automatically based on metrics/logs/traces data). Hashicorp have a &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/job-blue-green-and-canary-deployments&#34;&gt;detailed-ish guide with examples&lt;/a&gt; on their HashiCorp Learn platform.&lt;/p&gt;
&lt;h3 id=&#34;networking&#34;&gt;Networking&lt;/h3&gt;
&lt;p&gt;Networking on Nomad is, at its base, very simple and basic, at least when it comes to containers. By default each task gets an IP (as provided by Docker/etc.) in bridge mode, in a shared namespace with the other tasks in its group ( to allow sidecar proxies ). Ports can be exposed by using host networking, dynamic or static port forwarding and accessed directly or via sidecar proxies, or via a CNI plugin if advanced features are needed.&lt;/p&gt;
&lt;p&gt;The more or less standard/recommended behaviour is inspired by Google&amp;rsquo;s Borg - any scheduled task group gets a random port from the host if it requires it, and service discovery is responsible for linking and discovering services across the dynamic ports. In Nomad&amp;rsquo;s case, that&amp;rsquo;s done via Consul ( either DNS, API or in Nomad with templating). It&amp;rsquo;s also possible to have the containers be IPv6-only, and advertise that to Consul.&lt;/p&gt;
&lt;p&gt;More advanced options include scheduling ports only on &lt;a href=&#34;https://www.nomadproject.io/docs/job-specification/network#host-networks&#34;&gt;specific networks&lt;/a&gt; and only exposing tasks via &lt;a href=&#34;https://www.consul.io/docs/connect&#34;&gt;Consul Connect/Service Mesh&lt;/a&gt;, which can be used with Kubernetes, Nomad, regular virtual or physical machines.&lt;/p&gt;
&lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt;
&lt;p&gt;By default, allocations are ephemeral and with no persistence. Each one gets a shared &lt;code&gt;alloc&lt;/code&gt; folder, to which all tasks within the allocation can read and write, with 3 standard folders inside - &lt;code&gt;data&lt;/code&gt; for &lt;code&gt;ephemeral_disk&lt;/code&gt;-declared data ( more on that later), &lt;code&gt;logs&lt;/code&gt; which contains all tasks&amp;rsquo; logs, and &lt;code&gt;tmp&lt;/code&gt;, which used as scratch space by task drivers. Besides that, each tasks gets its own folder ( on the same level as &lt;code&gt;alloc&lt;/code&gt; ), with &lt;code&gt;local&lt;/code&gt; ( to be used at will, for e.g. configuration files), &lt;code&gt;secrets&lt;/code&gt; (for secrets, and is therefore unavailable for browsing via the UI, API or &lt;code&gt;nomad alloc fs&lt;/code&gt; command, unlike the others) and &lt;code&gt;tmp&lt;/code&gt; subfolders. Tasks can&amp;rsquo;t access other tasks&amp;rsquo; folders, so cross-task things ( e.g. if you&amp;rsquo;re using a sidecar log shipper for custom logs) should use the &lt;code&gt;alloc&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an &lt;a href=&#34;https://www.nomadproject.io/docs/job-specification/ephemeral_disk&#34;&gt;&lt;code&gt;ephemeral_disk&lt;/code&gt;&lt;/a&gt; stanza, which allows for &lt;em&gt;somewhat persistent&lt;/em&gt; storage:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;job&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;ephemeral_disk&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      migrate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      size    &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; # in MB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;      sticky  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will create a 500MB &amp;ldquo;disk&amp;rdquo; ( it isn&amp;rsquo;t an enforced limit, it&amp;rsquo;s more of a capacity planning thing and it&amp;rsquo;s used for scheduling decisions) that should be migrated to another node if the one it&amp;rsquo;s currently on gets drained ( &lt;code&gt;migrate&lt;/code&gt; = true), and Nomad will try to place updated allocations on the same node and move the &lt;code&gt;ephemeral_disk&lt;/code&gt; ( corresponding to the &lt;code&gt;alloc/data&lt;/code&gt; on the allocation level and &lt;code&gt;local&lt;/code&gt; on the task level folders ) to it. This is all &lt;em&gt;best-effort&lt;/em&gt;, with zero guarantees and of course, if the node fails, the data will be lost.&lt;/p&gt;
&lt;p&gt;Actual persistence is achieved in two main ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host volumes ( folders on the hosts mounted inside the allocations ), redundant via some external to the Nomad cluster tooling ( NFS, GlusterFS, Ceph, Portworx, etc.)&lt;/li&gt;
&lt;li&gt;CSI volumes ( more on that below )&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;
&lt;p&gt;A lot of the key components of Nomad are delegated to plugins ( some included and distributed with Nomad, some external, and all with an open spec, so anyone can contribute custom plugins), such as autoscaling, &lt;code&gt;task drivers&lt;/code&gt;, advanced networking (CNI) and storage (CSI) to enable greater flexibility.&lt;/p&gt;
&lt;h4 id=&#34;task-drivers&#34;&gt;Task drivers&lt;/h4&gt;
&lt;p&gt;As mentioned before, Nomad can schedule and run all sorts of different things ( Docker, contairnerd, LXC, rkt, podman, Java, fork/exec, QEMU, firecracker, FreeBSD jails, Windows IIS). A few of them are maintained by the &lt;a href=&#34;https://www.nomadproject.io/docs/drivers/external&#34;&gt;community&lt;/a&gt;, and there&amp;rsquo;s an official &lt;a href=&#34;https://www.nomadproject.io/docs/internals/plugins/task-drivers&#34;&gt;guide&lt;/a&gt; on writing custom ones, which is infinitely more flexible than Kubernetes, which is fixed on Docker/contairnerd ( even if projects such as &lt;a href=&#34;https://github.com/kubevirt/kubevirt&#34;&gt;kubevirt&lt;/a&gt; exist).&lt;/p&gt;
&lt;h4 id=&#34;csi-and-cni&#34;&gt;CSI and CNI&lt;/h4&gt;
&lt;p&gt;In a bid to make Nomad more compatible with &lt;em&gt;cloud-native&lt;/em&gt; software, it implements the CSI and CNI specs for storage and networking respectively, meaning that you can use plugins following those specs ( popularised by Kubernetes and hosted by the &lt;a href=&#34;https://landscape.cncf.io/&#34;&gt;CNCF&lt;/a&gt;) with Nomad. In theory that means that Nomad can tap in to a vast ecosystem of existing tooling and plugins and one can ( more or less ) easily move from Kubernetes to Nomad and keep the same third-party helpers/tooling/infrastructure - external storage system ( AWS EBS/EFS or NetApp or Ceph, etc.), network overlay ( Weave, Flannel, etc.), but in practice there are some limitations, most notably the fact that not &lt;a href=&#34;https://github.com/hashicorp/nomad/issues/8212&#34;&gt;the whole CSI spec is implemented&lt;/a&gt;. Nonetheless, that&amp;rsquo;s a great direction and the HashiCorp team is working on improving.&lt;/p&gt;
&lt;h4 id=&#34;autoscaling&#34;&gt;Autoscaling&lt;/h4&gt;
&lt;p&gt;Nomad supports autoscaling of various types, managed by external autoscalers, and Hashicorp provide the &lt;a href=&#34;https://github.com/hashicorp/nomad-autoscaler&#34;&gt;Nomad Autoscaler&lt;/a&gt; project, which supports horizontal application ( add more instances of task group) and cluster (add more Nomad workers) scaling in the open source version, and dynamic application sizing ( add more resources to a task based on its actual real life usage) in Nomad Enterprise, but anyone can implement a custom autoscaler via Nomad&amp;rsquo;s API.&lt;/p&gt;
&lt;p&gt;Nomad Autoscaler supports plugins for the following components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;APM ( what to query for application metrics to use for decisions ) - Prometheus, Datadog or a limited integrated Nomad one&lt;/li&gt;
&lt;li&gt;strategy ( based on the current and desired state, decide what to do ) - &lt;em&gt;target value&lt;/em&gt; ( what the value of a metric should be) and the Enterprise-only dynamic application sizing &lt;em&gt;average strategy&lt;/em&gt;, &lt;em&gt;max strategy&lt;/em&gt;, &lt;em&gt;percentile strategy&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;target ( what to scale ) - &lt;em&gt;Nomad task group&lt;/em&gt;, &lt;em&gt;dynamic application sizing&lt;/em&gt; for horizontal application scaling, and &lt;em&gt;AWS Autoscaling Group&lt;/em&gt;, &lt;em&gt;Azure Virtual Machine Scale Set&lt;/em&gt; for cluster autoscaling ( a GCP &lt;em&gt;Managed Instance group&lt;/em&gt; plugin is in the works ).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And as per usual, anyone can write custom plugins for specific use cases.&lt;/p&gt;
&lt;h2 id=&#34;advantages&#34;&gt;Advantages&lt;/h2&gt;
&lt;h3 id=&#34;easy-lightweight-and-low-maintenance&#34;&gt;Easy, lightweight and low maintenance&lt;/h3&gt;
&lt;p&gt;Nomad is a single binary, with relatively few moving components ( optionally, but more often than not ) required - most notably Consul, Vault and potentially some plugins. Upgrading, adding extra nodes etc, is easy. Making the jump from test to production is also straightforward and consists of more or less the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;have 3 or 5 servers with Nomad and Consul&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.hashicorp.com/collections/nomad/access-control&#34;&gt;enable ACLs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;enable &lt;a href=&#34;https://learn.hashicorp.com/collections/nomad/transport-security&#34;&gt;cross-node communication encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;add monitoring (via e.g. &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/prometheus-metrics?in=nomad/manage-clusters&#34;&gt;Prometheus&lt;/a&gt; or any Prometheus-compatible tool)&lt;/li&gt;
&lt;li&gt;enable &lt;a href=&#34;https://learn.hashicorp.com/tutorials/nomad/autopilot?in=nomad/manage-clusters&#34;&gt;Autopilot&lt;/a&gt;, which automates some operations-related tasks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Roughly speaking, you can be up and running from zero to pre-production within a day or two, and maintenance is minimal outside of updates, which rarely introduce breaking changes.&lt;/p&gt;
&lt;h3 id=&#34;scale&#34;&gt;Scale&lt;/h3&gt;
&lt;p&gt;On top of all that, Nomad can also scale well. Hashicorp did a few experiments with that, first with &lt;a href=&#34;https://www.hashicorp.com/c1m&#34;&gt;1 million containers&lt;/a&gt; back in 2016, and in December 2020, for the 1.0 release, they ran &lt;a href=&#34;https://www.hashicorp.com/c2m&#34;&gt;2 million containers&lt;/a&gt; across 6,100 AWS Spot instances, with just 3 Nomad servers (AWS i3.16xlarges, but still) orchestrating all of that.&lt;/p&gt;
&lt;h3 id=&#34;hcl&#34;&gt;HCL&lt;/h3&gt;
&lt;h4 id=&#34;no-yaml&#34;&gt;No YAML&lt;/h4&gt;
&lt;p&gt;As I mentioned, Nomad eschews the wildly popular YAML and uses Hashicorp&amp;rsquo;s own HCL ( Hashicorp Configuration Language ), which was created because &lt;a href=&#34;https://github.com/hashicorp/hcl#why&#34;&gt;none of JSON or YAML were good enough&lt;/a&gt; for configuration purposes, and that&amp;rsquo;s still as true as it was a few years ago. JSON is overly verbose and not really fit for configuration ( e.g. no comments - I know that &lt;a href=&#34;https://json5.org/&#34;&gt;JSON5&lt;/a&gt; exists, but isn&amp;rsquo;t widely supported, and the &lt;a href=&#34;https://github.com/json5&#34;&gt;official implementations&lt;/a&gt; are few, and mostly archived ), and YAML is just terrible beyond 10-20 lines or 3-4 levels. It&amp;rsquo;s so bad, there&amp;rsquo;s an entire site dedicated on the subject - &lt;a href=&#34;noyaml.com&#34;&gt;https://noyaml.com/&lt;/a&gt;, which i won&amp;rsquo;t quote in it&amp;rsquo;s entirety, but let&amp;rsquo;s just say that using spaces for logic is a bad idea and leads to weird, undebuggable errors when copy/pasting and templating via external tools ( such as Helm or Jinja - anyone seen Ansible&amp;rsquo;s &amp;ldquo;error at line X, but it probably isn&amp;rsquo;t there&amp;rdquo; message? ).&lt;/p&gt;
&lt;p&gt;Furthermore, both are limited in that templating/logic is impossible/hacky/dependent on third-party tools ( like Helm, jsonnet/tanka, kustomize or ytt), while HCL can do ( in some cases since not that long ago, but nonetheless ) basic logic such as if/else, for loops, dynamic blocks, variable substitution, data types ( maps, lists, objects ), strict typing thereof, file including and plenty of other goodies. You can have basic logic in your configuration if you need it, you can comment it, you can copy/paste at will without fear of breaking anything, you can split your configuration into multiple files ( e.g. sharing a sidecar logging/tracing/etc. agent). It&amp;rsquo;s actually pretty great! There are even (sadly third-party) tools to &lt;code&gt;fmt&lt;/code&gt; ( in Go, and some other Hashicorp tools, like terraform, there&amp;rsquo;s format &lt;code&gt;fmt&lt;/code&gt; subcommand to format your code according to a basic set of rules, making code more easily readable and always looking the same ).&lt;/p&gt;
&lt;h3 id=&#34;self-contained-jobs&#34;&gt;Self-contained jobs&lt;/h3&gt;
&lt;p&gt;A very nice thing about nomad job files is that they contain everything related to the job - all the groups and tasks, sidecars, resultant services, configuration, etc. HCL remains legible even at length ( especially within an IDE or text editor with enough features to be able to highlight corresponding curly brackets {} ), but of course if one wants, there&amp;rsquo;s a &lt;code&gt;file&lt;/code&gt; function to import file contents, so some parts can be split into different files if required/preferred,&lt;/p&gt;
&lt;h3 id=&#34;csi-cni&#34;&gt;CSI, CNI&lt;/h3&gt;
&lt;p&gt;Hashicorp opting for widely used standards where appropriate and practical is a big advantage, allowing Nomad users to profit from developments done in the larger ecosystem. There are caveats, however, and some improvements are needed in Nomad ( e.g. a more complete implementation of the CSI spec ); nonetheless, it&amp;rsquo;s a great direction and the bases are already there.&lt;/p&gt;
&lt;h3 id=&#34;extensibility&#34;&gt;Extensibility&lt;/h3&gt;
&lt;p&gt;The fact that a lot of the main functionalities ( task drivers, device drivers, autoscaling, storage and networking ) are offloaded to plugins is absolutely great. It allows you to move at your own pace when something gets deprecated ( e.g. if you were using &lt;code&gt;rkt&lt;/code&gt; and hadn&amp;rsquo;t had the time to move to something else yet, the fact that you can still run the &lt;code&gt;rkt&lt;/code&gt; task driver, even if it&amp;rsquo;s deprecated and no longer a part of Nomad, is probably reassuring) or add your custom use cases ( e.g. the &lt;a href=&#34;https://www.nomadproject.io/docs/drivers/external/firecracker-task-driver&#34;&gt;Firecracker&lt;/a&gt; and &lt;a href=&#34;https://www.nomadproject.io/docs/drivers/external/iis&#34;&gt;IIS&lt;/a&gt; task drivers were added by community users that needed them). And at the same time, the basic ones are baked in and distributed with the Nomad binary, so you don&amp;rsquo;t need to install anything to do the &amp;ldquo;standard&amp;rdquo; things ( Docker, raw fork/exec, etc.). If you want to make Nomad autoscale on your Proxmox or Nutanix AHV cluster, you can develop it yourself and aren&amp;rsquo;t stuck waiting for Hashicorp to do it.&lt;/p&gt;
&lt;h2 id=&#34;disadvantages&#34;&gt;Disadvantages&lt;/h2&gt;
&lt;h3 id=&#34;ecosystem&#34;&gt;Ecosystem&lt;/h3&gt;
&lt;p&gt;The Kubernetes ecosystem is &lt;em&gt;massive&lt;/em&gt;. There are entire companies, tools and whole niches being built around it ( ArgoCD, Rook, Istio, etc. etc. etc.). In some cases tools exist only because Kubernetes is itself so complex - Helm, Kustomize, there are a bunch of web UIs and IDEs ( &lt;a href=&#34;https://octant.dev/&#34;&gt;Octant&lt;/a&gt;, &lt;a href=&#34;https://kubevious.io/&#34;&gt;Kubevious&lt;/a&gt;, &lt;a href=&#34;https://k8slens.dev/&#34;&gt;Lens&lt;/a&gt;, etc.), specialised tooling to get an overview into the state and security of your Kubernetes cluster ( &lt;a href=&#34;https://sonobuoy.io/&#34;&gt;Sonobuoy&lt;/a&gt;, &lt;a href=&#34;https://github.com/aquasecurity/kube-hunter&#34;&gt;kube-hunter&lt;/a&gt;, &lt;a href=&#34;https://github.com/aquasecurity/kube-bench&#34;&gt;kube-bench&lt;/a&gt;,  &lt;a href=&#34;https://www.armosec.io/&#34;&gt;armosec&lt;/a&gt;, &lt;a href=&#34;https://pixielabs.ai/&#34;&gt;pixie&lt;/a&gt;). Furthermore, there are literally hundreds of &lt;a href=&#34;https://operatorhub.io/&#34;&gt;operators&lt;/a&gt; that allow abstracting the running of complex software within Kubernetes.&lt;/p&gt;
&lt;p&gt;There isn&amp;rsquo;t a lot of software that even comes close, and Nomad doesn&amp;rsquo;t. There&amp;rsquo;s a decent amount of tools it &lt;a href=&#34;https://www.nomadproject.io/docs/ecosystem&#34;&gt;works with&lt;/a&gt;, and CNI and CSI support helps it tap into the wider Kubernetes/cloud native ecosystem, but it still isn&amp;rsquo;t as popular. In practice this means that for running some things, you&amp;rsquo;re on your own - e.g. if you want to use PostgreSQL, Cassandra, Prometheus, CockroachDB or anything of the like, you can&amp;rsquo;t just use existing operator with a few CRDs, you have to write the full Nomad configuration for it to work.&lt;/p&gt;
&lt;h3 id=&#34;managed-service&#34;&gt;Managed service&lt;/h3&gt;
&lt;p&gt;At the time of writing, there is no Nomad managed service akin to &lt;a href=&#34;https://cloud.google.com/kubernetes-engine&#34;&gt;Google Kubernetes Engine&lt;/a&gt;, &lt;a href=&#34;https://aws.amazon.com/eks/&#34;&gt;Amazon Elastic Kubernetes Service&lt;/a&gt;, &lt;a href=&#34;https://www.digitalocean.com/products/kubernetes/&#34;&gt;Digital Ocean Kubernetes&lt;/a&gt;, etc.; if you want to use Nomad, you have to run it yourself ( maintenance is minimal, but still, in some cases offloading the maintenance to a cloud provider is worth the cost even for easy-to-maintain software). Hashicorp have their &lt;a href=&#34;https://www.hashicorp.com/cloud-platform&#34;&gt;Hashicorp Cloud Platform&lt;/a&gt;, which uses Nomad underneath for their managed Vault and Consul offerings; and Armon Dadgar, co-founder of Hashicorp, said at Hashiconf US 2020 that they are planning on offering a HCP Nomad. Until that arrives ( or AWS decide to make a Nomad managed service), you&amp;rsquo;re on your own.&lt;/p&gt;
&lt;h3 id=&#34;enterprise&#34;&gt;Enterprise&lt;/h3&gt;
&lt;p&gt;Hashicorp are a for-profit company with open core software distribution model. That presents some risks, most notably that some day they might decide to take Nomad ( or Terraform or Consul for that matter) in a direction you don&amp;rsquo;t like, or, to the extreme, shift features from the open source Nomad version to the Enterprise one - like when &lt;a href=&#34;https://www.influxdata.com/blog/update-on-influxdb-clustering-high-availability-and-monetization/&#34;&gt;InfluxData removed clustering from InfluxDB OSS&lt;/a&gt; and moved it to InfluxDB Enterprise. I personally consider that &lt;strong&gt;highly&lt;/strong&gt; unlikely ( because doing so would destroy most of the goodwill they have within the community, make conversion to Enterpise versions harder, etc. etc.) and they genuinely seem like nice people, but it&amp;rsquo;s still a possibility. In any case, there&amp;rsquo;s an inherent conflict of interest - Hashicorp wouldn&amp;rsquo;t allow features competing with their Enterprise offering to be added to Nomad OSS, because that would lower it&amp;rsquo;s value proposition.&lt;/p&gt;
&lt;h4 id=&#34;policy-management&#34;&gt;Policy management&lt;/h4&gt;
&lt;p&gt;One of the main things I&amp;rsquo;d consider &amp;ldquo;missing&amp;rdquo; in Nomad OSS is policy management ( as in Open Policy Agent, Gatekeeper and company - roughly equivalent to Kubernetes admission controllers) - it&amp;rsquo;s done only via &lt;a href=&#34;https://docs.hashicorp.com/sentinel/nomad&#34;&gt;Sentinel&lt;/a&gt; which is IMHO a fine policy as code DSL, but it&amp;rsquo;s only available in Nomad Enterprise. One can work around this with &lt;a href=&#34;https://github.com/open-policy-agent/conftest/tree/master/examples/hcl2&#34;&gt;conftest&amp;rsquo;s HCLv2&lt;/a&gt; parser in CI/CD, coupled with ACLs forcing users to only submit jobs via &amp;ldquo;GitOps&amp;rdquo;; but it&amp;rsquo;s certainly not as powerful (e.g. you can&amp;rsquo;t easily use runtime data from Nomad).&lt;/p&gt;
&lt;h2 id=&#34;vs-new-kubernetes&#34;&gt;vs &amp;ldquo;New Kubernetes&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;As I started with my inspiration, &amp;ldquo;new kubernetes&amp;rdquo;, it&amp;rsquo;s fitting to end comparing Nomad to it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;[&amp;hellip;] my guide star is Go. If Kubernetes is C++, what would the Go of orchestration systems look like? Aggressively simple, opinionated, grown slowly and warily, and you can learn it in under a week and get on with what you were actually trying to accomplish&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;~ &lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#guiding-principles&#34;&gt;David Anderson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nomad mostly fits that bill - it&amp;rsquo;s simple and opinionated. In terms of the features proposed, it does by default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#mutable-pods&#34;&gt;mutability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#version-control-all-the-things&#34;&gt;version control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://timewitch.net/post/2019-12-30-pinneddeployments/&#34;&gt;better-controlled deployments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;simplified networking with &lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#ipv6-only-mostly&#34;&gt;IPv6&lt;/a&gt; or &lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#or-just-don-t&#34;&gt;with task groups getting randomly allocated ports by default&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#vms-as-primitives&#34;&gt;virtual machines&lt;/a&gt; (and FreeBSD Jails, and LXC, and etc.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#how-to-storage&#34;&gt;alternative to CSI storage&lt;/a&gt; although it&amp;rsquo;s nothing special, just allowing you to mount host folders (same as Kubernetes)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And it allows, with some work, under some conditions and with some limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.dave.tf/post/new-kubernetes/#very-distributed-clusters&#34;&gt;highly distributed clusters&lt;/a&gt; - more specifically, Nomad&amp;rsquo;s cluster federation is decently featured and stable ( but deploying jobs across multiple regions simultaneously is only available in Nomad Enterprise), and can probably be done over WAN via Consul Mesh/Terminating/Ingress gateways ( also useful for inter-service traffic and failover). Nevertheless, Nomad isn&amp;rsquo;t designed for clients to stay disconnected from the servers for a long time, and Nomad will reschedule allocations on &amp;ldquo;lost&amp;rdquo; nodes after a certain ( tunable ) time has elapsed, so for &amp;ldquo;edge&amp;rdquo; scenarios a cluster per location is more appropriate - as &lt;a href=&#34;https://blog.cloudflare.com/how-we-use-hashicorp-nomad/&#34;&gt;CloudFlare do&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, Nomad doesn&amp;rsquo;t have the concept of control loops, which drastically simplifies it and allocation debugging, but also limits how far you can integrate with it from within to control its behaviour.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Overall, Nomad is a pretty great, simple, opinionated and flexible orchestrator. It has some advantages in features over Kubernetes ( stable cluster federation, task drivers, version control, integrated deployment logic and templating, no YAML), but lacks some other features (CRD), polish ( full CSI spec ) and ecosystem depth.&lt;/p&gt;
&lt;p&gt;Some scenarios where Nomad would be more appropriate than Kubernetes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on-prem deployments ( even with RKE/VMware Tanzu/kubeadm etc., running Nomad on bare metal/virtual machines is drastically easier )&lt;/li&gt;
&lt;li&gt;multi-DC/region presence ( due to cluster federation )&lt;/li&gt;
&lt;li&gt;not only container needs (QEMU, Java, raw exec, FreeBSD jails, IIS, etc.)&lt;/li&gt;
&lt;li&gt;small(-er) sized teams&lt;/li&gt;
&lt;li&gt;limited amount of things to deploy ( e.g. using Kubernetes for Django + Redis + PostgreSQL is certainly overkill; Nomad&amp;rsquo;s overhead is acceptable for such a stack)&lt;/li&gt;
&lt;li&gt;following the KISS ( keep it simple, stupid ) principle&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some scenarios where it might not be more appropriate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it might be useful to tap into the wider Kubernetes ecosystem, e.g. operators - if you want to run PostgreSQL, Redis, Cassandra, ElasticSearch, Kafka with limited human resources, it might be easier to do so via Kubernetes Operators ( whether or not such operational complexity, even abstracted, is worth it with a limited team, is an entirely different discussion)&lt;/li&gt;
&lt;li&gt;if you&amp;rsquo;re, by choice or not, limited to a single public cloud provider, and can outsource the management of Kubernetes (or even a higher level product, like AWS&amp;rsquo; Fargate or GCP&amp;rsquo;s Google Cloud Run/AppEngine), like with GKE and especially &lt;a href=&#34;https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot&#34;&gt;Autopilot&lt;/a&gt;, there&amp;rsquo;s little left to you; ( even then, there&amp;rsquo;s still some complexity that might be unneccessary - e.g. dealing with AWS EKS to run Wordpress might be overkill)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;coming-up-next&#34;&gt;Coming up next&lt;/h2&gt;
&lt;p&gt;I intend to write a few more articles on Nomad, mostly to tell my recent experiences with specific things around it, like log management ( how to run Loki on top of Nomad, ship logs to it), tracing ( Jaeger, integrate with Traefik/Consul, etc.).&lt;/p&gt;
&lt;h2 id=&#34;discuss&#34;&gt;Discuss&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=26291975&#34;&gt;Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/sofixa/status/1367787759960723457&#34;&gt;Twitter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://t.me/devops_lemons&#34;&gt;Telegram&lt;/a&gt;&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Comparing Kubernetes managed services across Digital Ocean, Scaleway, OVHCloud and Linode</title>
      <link>/2020/06/14/comparing-kubernetes-managed-services-across-digital-ocean-scaleway-ovhcloud-and-linode/</link>
      <pubDate>Sun, 14 Jun 2020 18:26:15 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2020/06/14/comparing-kubernetes-managed-services-across-digital-ocean-scaleway-ovhcloud-and-linode/</guid>
      <description>
        
          
          
          
        
        
        &lt;p&gt;&lt;em&gt;This article was updated:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;15/06 to add an SLA &amp;amp; Support section (thanks T from the &lt;a href=&#34;https://t.me/devopsish&#34;&gt;DevOps&amp;rsquo;ish Telegram group&lt;/a&gt; for the great idea); add the just released option to deploy Traefik v2 with Kapsule; explicitly mention that instance pricing is hourly&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;19/06 to update Kapsule&amp;rsquo;s latest available version (v1.18.4, less than 22 hours after public release!)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;21/07 to mention Scaleway&amp;rsquo;s &lt;a href=&#34;https://blog.scaleway.com/2020/price-evolutions-cloud-instances/#:~:text=In%20order%20to%20continue%20to,pricing%20based%20on%20your%20usage.&#34;&gt;price hike&lt;/a&gt; and newer Kapsule versions&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Everybody knows about the &amp;ldquo;big three&amp;rdquo; cloud providers - Amazon Web Services, Google Cloud Platform and Microsoft Azure. However, there are a few other, less known competitors, which provide fewer services, but have some advantages (most notably in terms of cost and complexity) and are perfectly viable choices, depending on size and requirements. In recent years, with the advent of Kubernetes, the features gap is being bridged because with a managed k8s service and some related ones (load balancers, block and object storage, managed databases) one can go a long way before needing the full might of AWS&amp;rsquo; 175 (at time of writing) services. And thanks to the ubiquity of Kubernetes, migrating to a new, more feature complete cloud provider&amp;rsquo;s isn&amp;rsquo;t that complex ( a lot less than if you have custom orchestration and cloud-specific deployment logic), if you do someday outgrow your current choice.&lt;/p&gt;
&lt;p&gt;Especially when starting (be it in a hobby capacity, a side project, or a start-up), relatively simple configuration and pricing can be a huge advantage. Everybody could do with not needing schematics like this one by &lt;a href=&#34;https://twitter.com/quinnypig/status/1172239124251709449?lang=en&#34;&gt;Corey Quinn&lt;/a&gt;:&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;https://19x50e48lpyz2s9tzz3qjjsn-wpengine.netdna-ssl.com/wp-content/uploads/2019/12/dbg010-datatxfr-infographic-20191219.jpg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;In this article I&amp;rsquo;d like to compare how some of those smaller, more developer-oriented providers fare in terms of managed Kubernetes and associated services. I&amp;rsquo;ll also throw in a brief comparison to AWS or GCP from time to time to put things in perspective.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: When I say &amp;ldquo;managed Kubernetes service&amp;rdquo;, I mean a service where the master nodes (Kubernetes control plane) are hosted and managed by the provider. It&amp;rsquo;s not about Container as a service services like AWS Fargate, Google Cloud Run or Scaleway Serverless where Kubernetes might be running behind the scenes, but you only deal with it via an abstraction layer (like Knative) at the container level.&lt;/p&gt;
&lt;h2 id=&#34;criteria&#34;&gt;Criteria&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes features&lt;/li&gt;
&lt;li&gt;complexity&lt;/li&gt;
&lt;li&gt;tooling&lt;/li&gt;
&lt;li&gt;ecosystem&lt;/li&gt;
&lt;li&gt;cost&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;competitors&#34;&gt;Competitors&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll compare Digital Ocean, Scaleway, OVHCloud and Linode, some of the most popular traditional VPS providers, which have also branched out into the managed Kubernetes space, keeping with their developer-oriented, low cost, low complexity model. Why only them? They were the only ones I could find within the first two pages of Google search that weren&amp;rsquo;t enterprise-only (IONOS) or too similar in model, complexity and pricing to AWS/GCP/Azure (IBM, Oracle). &lt;a href=&#34;https://www.civo.com/kube100&#34;&gt;Civo&lt;/a&gt; was also pointed out to me on the &lt;a href=&#34;https://t.me/devopsish&#34;&gt;DevOps&amp;rsquo;ish Telegram group&lt;/a&gt;, but they&amp;rsquo;re only in private beta.&lt;/p&gt;
&lt;h2 id=&#34;brief-history-and-overview&#34;&gt;Brief history and overview&lt;/h2&gt;
&lt;h3 id=&#34;digital-ocean&#34;&gt;Digital Ocean&lt;/h3&gt;
&lt;p&gt;Founded in 2011 as a VPS provider (&amp;ldquo;droplets&amp;rdquo; in DO parlance), their product range has been extended to add managed databases (PostgreSQL, MySQL and Redis), managed Kubernetes (main focus of this article), load balancers and object storage (Spaces). They have mostly a good reputation and are easy to use. Currently they have 8 locations around the world (New York and San Francisco in the USA, Amsterdam in the Netherlands, Singapore, London in the UK, Frankfurt in Germany, Toronto in Canada and Bangalore in India).&lt;/p&gt;
&lt;h3 id=&#34;scaleway&#34;&gt;Scaleway&lt;/h3&gt;
&lt;p&gt;Formerly a sub-brand of the Online.net (founded in 1999) part of the French Iliad group which offered custom-made ARM servers, since last year it&amp;rsquo;s the main brand for their public cloud offerings, which includes bare metal servers, traditional VPSes (x86), object storage, archival storage, managed Kubernetes (Kapsule, which I&amp;rsquo;ve &lt;a href=&#34;/2019/11/21/getting-started-with-scaleways-managed-kubernetes-service-kapsule/&#34;&gt;explored before on my blog&lt;/a&gt;, serverless offerings (Functions and Containers as a service), IoT/message queue, managed databases (PostgreSQL and soon MySQL), load balancers and soon &lt;em&gt;AI inference&lt;/em&gt;. Currently they have 2 locations (Paris, France and Amsterdam, Netherlands), with a third one in Poland coming sometime in 2020, and others planned for &lt;a href=&#34;https://www.iliad.fr/presse/2019/CP_130619_Scaleway_Eng.pdf&#34;&gt;&amp;ldquo;Asia and Latin America&amp;rdquo; &amp;ldquo;by end-2020&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;ovhcloud&#34;&gt;OVHCloud&lt;/h3&gt;
&lt;p&gt;Founded in 1999 and formerly known as OVH, they started as a managed hosting and VPS provider, and have expanded in telecoms, managed OpenStack, VMware vSphere and Kubernetes, email hosting, managed databases (MySQL, MariaDB, PostgreSQL, Redis), load balancers, Anti-DDoS, Data and Analytics platform. It&amp;rsquo;s by far the biggest of the bunch, in terms of services, clients and locations (Roubaix, Strasbourg, Gravelines, Paris in France, Franfkurt in Germany, Warsaw in Poland, London in the UK, Beauharnois in Canada, Vint Hill in the USA, Singapore, Sydney in Australia).&lt;/p&gt;
&lt;h3 id=&#34;linode&#34;&gt;Linode&lt;/h3&gt;
&lt;p&gt;Created in 2003 as a VPS provider (&amp;ldquo;Linodes&amp;rdquo; in Linode parlance), Linode have grown to also provide object storage, load balancers and Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: not all of the locations listed for the different cloud providers have their respective managed Kubernetes service&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;getting-started&#34;&gt;Getting started&lt;/h2&gt;
&lt;h3 id=&#34;creating-an-account&#34;&gt;Creating an account&lt;/h3&gt;
&lt;p&gt;Creating an account is basically the same thing across all four providers - sign up, confirm your email, set up a payment method, done.&lt;/p&gt;
&lt;p&gt;Digital Ocean and OVHCloud require you create a &amp;ldquo;project&amp;rdquo; to organise your resources. In DO, that&amp;rsquo;s just an organisational unit to group certain types of resources (but not Kubernetes clusters, for instance), and makes no difference, functionalities or billing-wise. In OVHCloud, a &amp;ldquo;public cloud project&amp;rdquo; is the level on which you interact with billing, quotas and IAM (Identity and Access Management, users and their rights).&lt;/p&gt;
&lt;h4 id=&#34;sharing-access&#34;&gt;Sharing access&lt;/h4&gt;
&lt;p&gt;In Digital Ocean you can create &lt;a href=&#34;https://www.digitalocean.com/docs/accounts/teams/&#34;&gt;teams&lt;/a&gt; and add users with different access levels (which boil down to owner with full access, billing access, and access to DO resources); on OVHCloud the same can be done on the &amp;ldquo;public cloud project&amp;rdquo; level (with similar roles for billing and developers); Linode allows adding users with detailed ACLs (create a new linode, power on/off, create images, delete, etc.). Scaleway used to be the only ones without anything similar, but they recently added &lt;em&gt;Organizations&lt;/em&gt; in beta, which allow sharing access at different levels (similar to DO) with different team members.&lt;/p&gt;
&lt;h3 id=&#34;navigating-the-web-ui&#34;&gt;Navigating the web UI&lt;/h3&gt;
&lt;p&gt;All of the web interfaces are pretty similar - clean, with a lot of information provided at a glance and many actions readily available, with the exception of OVHCloud (I&amp;rsquo;ll get into the disaster it is in a bit).&lt;/p&gt;
&lt;h4 id=&#34;digital-ocean-1&#34;&gt;Digital Ocean&lt;/h4&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/do-web-ui.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;Simple, elegant, everything is there at a glance. You can see billing usage, create new resources, check out documentation, switch projects and accounts/teams from the dashboard, and there&amp;rsquo;s a menu with all services on the left. Each resource creation presents an estimate of the monthly bill for it, which is pretty nice to visualise. You can search by name or IP. On each droplet&amp;rsquo;s page there is integrated monitoring with basic CPU, memory, load, disk, disk I/O, bandwidth graphs and basic alerting rules; backup and restore options (including a virtual console or boot from a recovery ISO). Overall, great UX.&lt;/p&gt;
&lt;h4 id=&#34;scaleway-1&#34;&gt;Scaleway&lt;/h4&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/scw-web-ui.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;Pretty similar to the Digital Ocean - simple, clean, everything is easily accessible. There&amp;rsquo;s a &amp;ldquo;Create&amp;rdquo; button up top, a detailed resources and billing overview, links to documentation, and a menu on the side with all services. You can attach a virtual console to the instances (requires a user with password auth enabled though), use cloud-init for the initial bootstrap, &amp;ldquo;protect&amp;rdquo; them to prevent accidental halt/deletion, and every creation previews an estimated monthly and hourly price. Each resource page (compute, object storage, etc.) has direct links to the associated documentation, which is handy.&lt;/p&gt;
&lt;h4 id=&#34;ovhcloud-1&#34;&gt;OVHCloud&lt;/h4&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/ovh-web-ui.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;Completely different thing. Their &amp;ldquo;console&amp;rdquo; (OVHCloud Control Panel or Manager), is actually a mix of a bunch of different consoles for different branches of products, and is painfully slow (each console takes ~10s to load when first accessing it) and chaotic. It absolutely shows they&amp;rsquo;re a bigger company with various product ranges that evolved weirdly over the years, yet they could probably organise them better. AWS have everything from basic compute through satellite communications to quantum computers and the AWS Console is much clearer. Things aren&amp;rsquo;t helped by the confusing naming schemes and product lines - &lt;em&gt;Web&lt;/em&gt;, &lt;em&gt;Server&lt;/em&gt;, &lt;em&gt;Public cloud&lt;/em&gt;, &lt;em&gt;Telecom&lt;/em&gt;, &lt;em&gt;Sunrise&lt;/em&gt; are product lines/sub-consoles, with unclear, sometimes overlapping product names like &lt;em&gt;Cloud Web&lt;/em&gt; and &lt;em&gt;Hosting&lt;/em&gt; under &lt;em&gt;Web&lt;/em&gt;; &lt;em&gt;Private Cloud&lt;/em&gt; under &lt;em&gt;Cloud&lt;/em&gt; and &lt;em&gt;Public Cloud&lt;/em&gt; under &lt;em&gt;Public cloud&lt;/em&gt;. Some services are referenced by different names throughout documentation, blog posts and consoles. It&amp;rsquo;s a complete mess and it requires some clicking around (which is slow) or reading documentation just to understand how to get to the parts that interest you, which only brings up more questions:&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/ovh-docs.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;&lt;em&gt;Cloud&lt;/em&gt;, &lt;em&gt;Cloud Web&lt;/em&gt;, &lt;em&gt;Private Cloud&lt;/em&gt; and &lt;em&gt;Public Cloud&lt;/em&gt; are listed as separate products/product lines. If &lt;em&gt;OVH Load balancer&lt;/em&gt; is under &lt;em&gt;Cloud&lt;/em&gt; and &lt;em&gt;Managed Kubernetes&lt;/em&gt; is under &lt;em&gt;Public Cloud&lt;/em&gt;, does that mean I can&amp;rsquo;t use load balancers with their k8s service?&lt;/p&gt;
&lt;p&gt;Thankfully they provide a &lt;a href=&#34;https://www.ovh.com/manager/#/catalog&#34;&gt;&lt;em&gt;Product catalogue&lt;/em&gt;&lt;/a&gt; that at least lists all services with descriptions and categories in a somewhat clear fashion:&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/ovh-catalogue.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;It would appear that &lt;em&gt;Private cloud/Hosted Private Cloud/SDDC&lt;/em&gt; is a VMware-centred offering, and &lt;em&gt;Public Cloud&lt;/em&gt; is OpenStack-based (which is why you get a Horizon interface on top of the OVHCloud one), their Kubernetes service being based on the latter.&lt;/p&gt;
&lt;h4 id=&#34;linode-1&#34;&gt;Linode&lt;/h4&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/img/comparing-managed-k8s/linode-web-ui.jpeg&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;Back a to clean and nice interface. You get a quick glance of existing resources, an easy way to create new ones via &amp;ldquo;Create button&amp;rdquo;, a powerful search, a sidebar menu with all services and settings, and cost estimations on each creation. Similar to DO, each instance&amp;rsquo;s interface also has some basic graphs.&lt;/p&gt;
&lt;h3 id=&#34;cli--api&#34;&gt;CLI &amp;amp; API&lt;/h3&gt;
&lt;h4 id=&#34;digital-ocean-2&#34;&gt;Digital Ocean&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/digitalocean/doctl&#34;&gt;doctl&lt;/a&gt;, Golang-based (static binaries for many platforms, distribution via homebrew and snapd) CLI, somewhat resembles &lt;code&gt;kubectl&lt;/code&gt; in organisation (&lt;code&gt;doctl subject action&lt;/code&gt;, e.g. &lt;code&gt;doctl kubernetes cluster list&lt;/code&gt;), and can do pretty much everything Digital Ocean related - listing, creating, updating various resources and related actions (like getting a k8s cluster&amp;rsquo;s kubeconfig, and even, for snapd installs, connecting/integrating it with kubectl and ssh), inlcuding billing related(getting invoices).&lt;/p&gt;
&lt;p&gt;Their &lt;a href=&#34;https://developers.digitalocean.com/&#34;&gt;API&lt;/a&gt; covers pretty much everything and has &lt;a href=&#34;https://developers.digitalocean.com/libraries/&#34;&gt;libraries in multiple languages&lt;/a&gt;. There are great docs and guides.&lt;/p&gt;
&lt;h4 id=&#34;scaleway-2&#34;&gt;Scaleway&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/scaleway/scaleway-cli&#34;&gt;scw&lt;/a&gt;, Golang-based (static binaries for many plaforms, distribution via homebrew and Chocolatey), is inspired by the &lt;code&gt;docker&lt;/code&gt; CLI, only manages compute instances and is currently under heavy redevelopment (v1.2 -&amp;gt; v2, in beta, and also following the &lt;code&gt;kubectl&lt;/code&gt; mantras) to handle the new Scaleway services (including Kapsule).&lt;/p&gt;
&lt;p&gt;Their &lt;a href=&#34;https://developers.scaleway.com/en/&#34;&gt;API&lt;/a&gt; covers all services and is well documented.&lt;/p&gt;
&lt;h4 id=&#34;ovhcloud-2&#34;&gt;OVHCloud&lt;/h4&gt;
&lt;p&gt;OVH have no actively maintained CLI, &lt;a href=&#34;https://github.com/ovh/ovh-cli&#34;&gt;&lt;code&gt;ovh-cli&lt;/code&gt;&lt;/a&gt; being archived since ~2018.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an &lt;a href=&#34;https://api.ovh.com/&#34;&gt;API&lt;/a&gt;, and associated Python and PHP SDK&amp;rsquo;s which cover some scenarios, but, weirdly, the &lt;a href=&#34;https://api.ovh.com/console/#/kube&#34;&gt;Kuberentes methods&lt;/a&gt; are deprecated. Apparently they were moved under the &lt;a href=&#34;https://api.ovh.com/console/#/cloud&#34;&gt;&lt;code&gt;/cloud/&lt;/code&gt;&lt;/a&gt; section. Docs are much more basic (OpenAPI-style descriptions of the parameters, little extra explications, context or examples ) than DO or Scaleway.&lt;/p&gt;
&lt;h4 id=&#34;linode-2&#34;&gt;Linode&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/linode/linode-cli&#34;&gt;linode-cli&lt;/a&gt; is a Python-based (distibution and installation via PyPi) flexible CLI that allows creating/updating/deleting/listing pretty much any Linode resource (Linodes, domains, managed kubernetes, etc.).&lt;/p&gt;
&lt;p&gt;Their &lt;a href=&#34;https://developers.linode.com/&#34;&gt;API&lt;/a&gt; is fully featured, and they have &lt;a href=&#34;https://developers.linode.com/libraries-tools/&#34;&gt;libraries and tools&lt;/a&gt; for various languages and tasks.&lt;/p&gt;
&lt;h4 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;All 4 have complete APIs, but Digital Ocean, Scaleway and Linode also have great tooling (libraries, SDKs, CLIs)&lt;/p&gt;
&lt;h3 id=&#34;terraform-providers&#34;&gt;Terraform providers&lt;/h3&gt;
&lt;p&gt;All 4 have terraform providers with varying levels of maturity. Digital Ocean, Scaleway and Linode cover all of their services (including Kubernetes), while OVHCloud&amp;rsquo;s one doesn&amp;rsquo;t (somewhat understandable considering their complex web of services and products).&lt;/p&gt;
&lt;h2 id=&#34;kubernetes&#34;&gt;Kubernetes&lt;/h2&gt;
&lt;h3 id=&#34;digital-ocean-kubernetes-service&#34;&gt;Digital Ocean Kubernetes Service&lt;/h3&gt;
&lt;p&gt;Digital Ocean Kubernetes Service is currently available in 10 datacenters across 8 locations covering most of the world (North America, Europe and Asia). It supports recent-ish versions of Kubernetes (v1.17, the latest being v1.18), and new clusters can be created via the web interface, API, CLI and terraform. Node pools can be composed of Standard, CPU-Optimised, Memory-optimised or General Purpose droplets, and you can mix and match them as you want to fit different workloads. Cluster-autoscaler is available for dynamically sized node pools, but only when creating via terraform or doctl; via the web UI a node pool &lt;a href=&#34;https://www.digitalocean.com/docs/kubernetes/how-to/autoscale/&#34;&gt;can only be modified&lt;/a&gt;, but not created, as autoscaling. Clusters come with &lt;code&gt;cilium&lt;/code&gt; as the CNI plugin, a Kubernetes dashboard (with automatic SSO when coming from the DO web interface), automatic patches in maintenance windows (only patch versions, e.g. v1.17.0 to v1.17.1, but not upgrades like v1.17 to v1.18, those have to be manually launched), basic cluster and node-level metrics with some nice graphs, thanks to the their &lt;a href=&#34;https://github.com/digitalocean/do-agent&#34;&gt;do-agent&lt;/a&gt; which runs on all nodes, which can even be used for basic alerting (only simple rules, metric X is above or below fixed value Y for duration Z on droplet or droplets by tag).&lt;/p&gt;
&lt;p&gt;DO also provide a basic managed Container Registry, which is however in &lt;em&gt;early availability&lt;/em&gt; and pricing is specific and fixed (you need to subscribe do a Digital Ocean Spaces(their object storage) plan at $5/month for 250GB of storage and 1TB outbound data transfer), but access is easy (you need a DO API token, which can be read-only or read/write) from within your CLI or Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;Digital Ocean&amp;rsquo;s &lt;a href=&#34;https://github.com/digitalocean/autoscaler&#34;&gt;cluster-autoscaler&lt;/a&gt;, &lt;a href=&#34;https://github.com/digitalocean/digitalocean-cloud-controller-manager&#34;&gt;Cloud Controller Manager&lt;/a&gt; (which allows the creation of Load balancers from within the cluster) and &lt;a href=&#34;https://github.com/digitalocean/csi-digitalocean/&#34;&gt;CSI plugin&lt;/a&gt; are all open source and available on GitHub to consult and contribute to. Documentation and &lt;a href=&#34;https://www.digitalocean.com/docs/kubernetes/how-to/&#34;&gt;how-to tutorials&lt;/a&gt; are top notch, and explain important bits like &lt;a href=&#34;https://www.digitalocean.com/docs/kubernetes/how-to/add-load-balancers/&#34;&gt;creating&lt;/a&gt; and &lt;a href=&#34;https://www.digitalocean.com/docs/kubernetes/how-to/configure-load-balancers/&#34;&gt;configuring&lt;/a&gt; load balancers, &lt;a href=&#34;https://www.digitalocean.com/docs/kubernetes/how-to/add-volumes/&#34;&gt;adding block storage&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;Operations (cluster creation, upgrades) are pretty fast and usually complete within a few minutes.&lt;/p&gt;
&lt;p&gt;All in all, you get a pretty complete and feature rich solution - the only thing I&amp;rsquo;d say is &amp;ldquo;missing&amp;rdquo; is log management, something one might take for granted coming from AWS/GCP/Azure.&lt;/p&gt;
&lt;h3 id=&#34;scaleway-kapsule&#34;&gt;Scaleway Kapsule&lt;/h3&gt;
&lt;p&gt;Scaleway Kapsule is currently only available in the Paris region, but stays &lt;em&gt;very&lt;/em&gt; close to Kubernetes releases (v1.18.6, latest release, was available less than a day after being on GitHub), which is really rare, I haven&amp;rsquo;t found another provider so up to date (for reference, the closest, OVHCloud, are on v1.18.1, GCP are &lt;em&gt;in preview&lt;/em&gt; on v1.17.6, and AWS are still on v1.16.8). Clusters can be created via the web UI, API and terraform, all with the same options, which are pretty rich:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CNI (Container Network Interface) can be any one of &lt;code&gt;cilium&lt;/code&gt; (default), &lt;code&gt;calico&lt;/code&gt;, &lt;code&gt;weave&lt;/code&gt; or &lt;code&gt;flannel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ingress can be any of none (default), &lt;code&gt;nginx&lt;/code&gt; or &lt;code&gt;traefik&lt;/code&gt; (versions 1.7 or 2.2), which can also be modified in-place after creation&lt;/li&gt;
&lt;li&gt;autoscaling and autohealing of nodes&lt;/li&gt;
&lt;li&gt;nodes come in a variety of sizes from 3 different product lines, DEV (2-4 vCPUs and 2-12GB RAM), GP1 (General Purpose, 4-48 vCPUs and 16-256GB RAM) and RENDER (which include dedicated NVIDIA Tesla P100 16GB GPUs alongside 10 cores (half of an Intel Xeon Gold 6148))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;rsquo;s a default node pool and you can add extra ones later on, each with its own autoscaling configuration. Besides that, you can opt in Kapsule deploying a Kubernetes dashboard for you (in a dedicated namespace, following best practices). Every cluster also comes with a wildcard DNS you can use to test things, but there&amp;rsquo;s no monitoring/metrics/alerting included (besides &lt;code&gt;metrics-server&lt;/code&gt; running on clusters by default), only &lt;a href=&#34;https://www.scaleway.com/en/docs/monitor-kubernetes-kapsule-with-kube-state-metrics-node-exporter/&#34;&gt;docs&lt;/a&gt; about about how you can add them yourself. They do, however, have a basic managed container registry available, where storage is cheap (€0.025/GB/month) and networking is free within the same region (€0.03/GB/month outside), but access to a private instance of it requires a Scaleway API Token, each of which has full read/write access to the whole of your Scaleway account, so it&amp;rsquo;s not great, security-wise.&lt;/p&gt;
&lt;p&gt;Scaleway&amp;rsquo;s &lt;a href=&#34;https://github.com/scaleway/scaleway-cloud-controller-manager&#34;&gt;Cloud Controller Manager&lt;/a&gt; and &lt;a href=&#34;https://github.com/scaleway/scaleway-csi&#34;&gt;CSI plugin&lt;/a&gt; are also open source and available on GitHub, and their &lt;a href=&#34;https://developers.scaleway.com/en/&#34;&gt;documentation&lt;/a&gt; and &lt;a href=&#34;https://www.scaleway.com/en/docs/#cat-elements-compute&#34;&gt;tutorials&lt;/a&gt; are also pretty great and detailed, and include important things like &lt;a href=&#34;https://www.scaleway.com/en/docs/using-a-load-balancer-to-expose-your-kubernetes-kapsule-ingress-controller-service/&#34;&gt;creating load balanacers&lt;/a&gt;, &lt;a href=&#34;https://www.scaleway.com/en/docs/use-loki-to-manage-k8s-application-logs/&#34;&gt;using Loki for logs management&lt;/a&gt; and plenty of others. Cluster upgrades are available via the API (and terraform).&lt;/p&gt;
&lt;p&gt;Operations (creation, upgrades, scale ups and downs) are pretty fast.&lt;/p&gt;
&lt;p&gt;Similar to Digital Ocean, you get a pretty complete and feature rich managed Kubernetes, with the main things &amp;ldquo;missing&amp;rdquo; being integrated monitoring/metrics/alerting and log management.&lt;/p&gt;
&lt;h3 id=&#34;ovhcloud-managed-kubernetes-service&#34;&gt;OVHCloud Managed Kubernetes Service&lt;/h3&gt;
&lt;p&gt;OVHCloud&amp;rsquo;s Kubernetes service is only available in two datacenters, in Canada and France (more to come in 2020), and, even if they keep up with Kubernetes versions faster than DO (v1.18.1 is latest available, and they promise they&amp;rsquo;ll have new versions available in the quarter after release), it works a bit differently, and not necessarily in a good way. Organisationally, Kubernetes clusters and nodes are under their &lt;em&gt;Public Cloud&lt;/em&gt; services, and billing is under the respective &lt;em&gt;Public Cloud&lt;/em&gt; project. You have to first create a cluster (control plane hosted by OVHCloud), and only after it&amp;rsquo;s created you can add individual nodes, each of which is rather slow (at least compared to DO and Scaleway) - ~5 minutes for the cluster creation (and apparently it&amp;rsquo;s a feature because they even notify you by email when your cluster has been created) and 5-10 minutes for each node. Node pools and autoscaling are  on their &lt;a href=&#34;https://docs.ovh.com/sg/en/kubernetes/available-upcoming-features/&#34;&gt;official roadmap&lt;/a&gt; and are available as experimental features in their &lt;a href=&#34;https://api.ovh.com/console/#/cloud/project/%7BserviceName%7D/kube#POST&#34;&gt;API&lt;/a&gt;. On that roadmap are also bare metal nodes, which can be great for performance. By default clusters are on the &amp;ldquo;maximum security&amp;rdquo; security policy, which means they get all patch updates automatically, and you can do upgrades manually (via the web interface or the API).&lt;/p&gt;
&lt;p&gt;Nodes come in different &lt;em&gt;flavors&lt;/em&gt; (sizes) and &lt;em&gt;flavor families&lt;/em&gt; (CPU, RAM, IOPS (which come with dedicated NVMe drives)), but not all are available depending on location (e.g. at the time of writing, in Gravelins, France, anything with more 8vCPUs from the CPU optimised or 30GB RAM from the memory optimised wasn&amp;rsquo;t available, and there were no instances at all, of any type, from the IOPS-optimised family). &lt;code&gt;Canal&lt;/code&gt;(calico for policy and flannel for networking) is used as the CNI plugin.&lt;/p&gt;
&lt;p&gt;OVHCloud&amp;rsquo;s Managed Container Registry is far more advanced than Digital Ocean or Scaleway&amp;rsquo;s, since it&amp;rsquo;s based on &lt;a href=&#34;https://goharbor.io/&#34;&gt;CNCF&amp;rsquo;s Harbor project&lt;/a&gt;, and it includes detailed RBAC (Role-Based Access Control), vulnerability scans of images, and Helm chart hosting alongside OCI-compatible images, but &lt;a href=&#34;https://www.ovhcloud.com/en/public-cloud/prices/#1682&#34;&gt;pricing&lt;/a&gt; is a bit specific and inflexible - there are different tiers and you pay for a combination of storage (200GB, 600GB or 2TB) and number of concurrent connections (15, 45, 90), while networking is free. There&amp;rsquo;s no included by default monitoring/metrics/alerting or logging, but they have a (somewhat old, but probably still usable) &lt;a href=&#34;https://www.ovh.com/blog/how-to-monitor-your-kubernetes-cluster-with-ovh-metrics/&#34;&gt;doc&lt;/a&gt; on how to send metrics from your clusters to their OVH Observability/Metrics platform (based on Warp10), and &lt;a href=&#34;https://docs.ovh.com/fr/logs-data-platform/kubernetes-fluent-bit/&#34;&gt;another one about sending logs to their Logs Data Platform&lt;/a&gt; (based on Graylog). Their documentation is pretty decent, even if there are some losses in translation with French idioms/phrases slipping in the English versions.&lt;/p&gt;
&lt;p&gt;Operations feel slow - on top of the aforementioned 5-10 minutes per adding a node, a load balancer takes around the same time to create, and even the Kubernetes API sometimes takes a bit more to respond than usual. OVHCloud run Kubernetes on top of OpenStack and probably use the official &lt;a href=&#34;https://github.com/kubernetes/cloud-provider-openstack&#34;&gt;cloud-provider-openstack&lt;/a&gt; and the associated cloud controller manager and Cinder CSI plugin.&lt;/p&gt;
&lt;p&gt;Overall, it&amp;rsquo;s hit and miss. There are some great things about OVHCloud&amp;rsquo;s Kubernetes service, mostly in related services (Harbor is a great registry, there are fully featured metrics and logs platforms), but the Kubernetes itself is direly missing in even basic features like node pools, and the pricing on those related services is on static plans (instead of pay per use) and in general everything about it feels slow and clunky. At least their roadmap is public and they intend to improve some of the major downfalls, and hopefully work on the speed and UX.&lt;/p&gt;
&lt;h3 id=&#34;linode-kubernetes-engine&#34;&gt;Linode Kubernetes Engine&lt;/h3&gt;
&lt;p&gt;Linode&amp;rsquo;s LKE is available in 10 locations across North America, Europe and Asia Pacific (and they even provide a handy &lt;a href=&#34;https://www.linode.com/speed-test/&#34;&gt;speed test page&lt;/a&gt; to help you pick the closest region), and, similar to Digital Ocean, have a relatively recent version of Kubernetes (v1.17.x, the latest being v1.18.x) available. Clusters can be created via terraform, web interface, CLI or API, come with &lt;code&gt;calico&lt;/code&gt; as the CNI and their node pools can be composed of nodes from the Standard (1-32 vCPUs, 2-192GB RAM), Dedicated (2-48 dedicated virtual cores, 4-96GB RAM) or High Memory (1-16 CPU, 24-300GB RAM) ranges; sadly their GPU instances are not available. There are basic graphs per instance (CPU, IPv4 and IPv6 network traffic, and Disk I/O) coming from their &lt;a href=&#34;https://www.linode.com/docs/platform/longview/what-is-longview/&#34;&gt;Longview&lt;/a&gt; agent, which is deployed on all Kubernetes nodes, which can then also be turned into basic alerting (enabled by default with sane thresholds), as well as decent audit logs.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s no cluster (node) autoscaling, no cluster upgrades (v1.16 to v1.17), and no node patches/upgrades, only automatic control plane patches by Linode. And even though they don&amp;rsquo;t provide a managed Docker registry, they have &lt;a href=&#34;https://www.linode.com/docs/kubernetes/how-to-setup-a-private-docker-registry-with-lke-and-object-storage/&#34;&gt;a how-to guide&lt;/a&gt; on how to set up one with their Object Storage and the &lt;a href=&#34;https://hub.helm.sh/charts/stable/docker-registry&#34;&gt;Docker registry Helm chart&lt;/a&gt;, and, of course, if you&amp;rsquo;re going to run one yourself, you can always install &lt;a href=&#34;https://goharbor.io/&#34;&gt;Harbor&lt;/a&gt; for the extra features.&lt;/p&gt;
&lt;p&gt;Their &lt;a href=&#34;https://www.linode.com/docs/kubernetes/&#34;&gt;documentation&lt;/a&gt; is pretty detailed and of good quality, and so are their open source tools (CLI, SDK, API, terraform provider, &lt;a href=&#34;https://github.com/linode/linode-cloud-controller-manager&#34;&gt;cloud controller manager&lt;/a&gt;, &lt;a href=&#34;https://github.com/linode/linode-blockstorage-csi-driver&#34;&gt;CSI plugin&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Operations are pretty fast (and you can even quantify it thanks to their logs, which show it took ~60s for an instance to become available).&lt;/p&gt;
&lt;p&gt;Overall, LKE is decent but lacking some very important features (cluster upgrades and autoscaling).&lt;/p&gt;
&lt;h3 id=&#34;features-comparison&#34;&gt;Features comparison&lt;/h3&gt;
&lt;p&gt;Legend&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature/service present and in GA&lt;/li&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature/service present, in GA, and much more advanced than competitors&#39;&lt;/li&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature/service present in beta&lt;/li&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature/service not present&lt;/li&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature/service on roadmap&lt;/li&gt;
&lt;li&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M352 288h-16v-88c0-4.42-3.58-8-8-8h-13.58c-4.74 0-9.37 1.4-13.31 4.03l-15.33 10.22a7.994 7.994 0 0 0-2.22 11.09l8.88 13.31a7.994 7.994 0 0 0 11.09 2.22l.47-.31V288h-16c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8h64c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 192c-53.02 0-96-50.15-96-112 0-61.86 42.98-112 96-112s96 50.14 96 112c0 61.87-43 112-96 112zm272 32h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; feature available, but it costs extra or is in a separate service billed separately&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Digital Ocean&lt;/th&gt;
&lt;th&gt;Scaleway&lt;/th&gt;
&lt;th&gt;OVHCloud&lt;/th&gt;
&lt;th&gt;Linode&lt;/th&gt;
&lt;th&gt;Google&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Up to date Kubernetes&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; v1.17&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; v1.18&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; v1.18&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; v1.17&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; v1.17 in preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free control plane&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; only for the first zonal cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes dashboard&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; optional&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; replaced by a GKE dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingress Controller&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; optional, Nginx/ Traefik v1 or v2&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; optional, GKE Ingress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bare metal Instances&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU Instances&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cluster Autoscaler&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cluster Patches (v1.17.x)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic Cluster Patches&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cluster Upgrades (v1.xx)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metrics&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M352 288h-16v-88c0-4.42-3.58-8-8-8h-13.58c-4.74 0-9.37 1.4-13.31 4.03l-15.33 10.22a7.994 7.994 0 0 0-2.22 11.09l8.88 13.31a7.994 7.994 0 0 0 11.09 2.22l.47-.31V288h-16c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8h64c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 192c-53.02 0-96-50.15-96-112 0-61.86 42.98-112 96-112s96 50.14 96 112c0 61.87-43 112-96 112zm272 32h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M352 288h-16v-88c0-4.42-3.58-8-8-8h-13.58c-4.74 0-9.37 1.4-13.31 4.03l-15.33 10.22a7.994 7.994 0 0 0-2.22 11.09l8.88 13.31a7.994 7.994 0 0 0 11.09 2.22l.47-.31V288h-16c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8h64c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 192c-53.02 0-96-50.15-96-112 0-61.86 42.98-112 96-112s96 50.14 96 112c0 61.87-43 112-96 112zm272 32h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform provider&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM/ Team management&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNI plugin&lt;/td&gt;
&lt;td&gt;cilium&lt;/td&gt;
&lt;td&gt;cilium, calico, weave or flannel&lt;/td&gt;
&lt;td&gt;canal&lt;/td&gt;
&lt;td&gt;calico&lt;/td&gt;
&lt;td&gt;GKE custom or calico&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPC (Private network)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unlimited network transfer&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; except for SYD and SGP*&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 640 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M352 288h-16v-88c0-4.42-3.58-8-8-8h-13.58c-4.74 0-9.37 1.4-13.31 4.03l-15.33 10.22a7.994 7.994 0 0 0-2.22 11.09l8.88 13.31a7.994 7.994 0 0 0 11.09 2.22l.47-.31V288h-16c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8h64c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 192c-53.02 0-96-50.15-96-112 0-61.86 42.98-112 96-112s96 50.14 96 112c0 61.87-43 112-96 112zm272 32h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IPv6 dualstack&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-zone/ datacenter clusters&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;* &amp;ldquo;Outbound public traffic is also free and unlimited, with the exception of the Singapore (SGP) and Sydney (SYD) regions, where 1,024 GB/month per project, per datacentre is available. Each additional GB will be charged for&amp;rdquo; &lt;a href=&#34;https://www.ovhcloud.com/en/public-cloud/faq/&#34;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Additional Services&lt;/th&gt;
&lt;th&gt;Digital Ocean&lt;/th&gt;
&lt;th&gt;Scaleway&lt;/th&gt;
&lt;th&gt;OVHCloud&lt;/th&gt;
&lt;th&gt;Linode&lt;/th&gt;
&lt;th&gt;Google&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Block storage&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object Storage&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Spaces&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Object Storage&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Object storage (based on Swift)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Google Cloud Storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archival Storage&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; C14&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Cloud Archive&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Cloud Storage for data archiving&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load Balancer&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Managed Container Registry&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; basic&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; basic&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Harbor&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; GCR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Managed Databases&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; PgSQL, MySQL, Redis&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; PgSQL, MySQL*&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; PgSQL, MySQL, MariaDB, Redis&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; a lot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Management&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Secret Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Managed Message broker&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; IoT Hub (MQTT)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; ioStream&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Pub/Sub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless (Functions)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Knative&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Cloud Functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless (Containers)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Knative&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;  Cloud Run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; AI Inference&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Data &amp;amp; Analytics&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;  Cloud AI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Warehouse&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Data Analytics Platform (based on Hadoop)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;  BigQuery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Processing&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Data Processing (based on Spark)&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 352 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Dataprep/ Dataproc/ Dataflow&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;* Only PgSQL is currently publicly available as a managed database by Scaleway, MySQL is in private beta&lt;/p&gt;
&lt;h2 id=&#34;pricing&#34;&gt;Pricing&lt;/h2&gt;
&lt;p&gt;All four providers have relatively simple pricing when it comes to their managed Kubernetes services - the control plane is free, you only pay for compute, memory, storage and networking (load balancers, extra public IPs) you consume, which are billed with hourly granularity (practical for autoscaling). There&amp;rsquo;s however a caveat with some of them - Digital Ocean and Linode have an account-level monthly public network transfer cap based on amount and size of instances you run (starting at &lt;a href=&#34;https://www.digitalocean.com/pricing/&#34;&gt;1TB/droplet for DO&lt;/a&gt; and &lt;a href=&#34;https://www.linode.com/pricing/&#34;&gt;2TB/linode for Linode&lt;/a&gt;, per full month), and anything on top is billed ($0.01/GB). Scaleway and OVHCloud have free network transfer, with the latter having an exception for instances located in their Singapore and Sydney datacenters, which are capped at 1024 GB/project/month (but they don&amp;rsquo;t have the Kubernetes service anyway).&lt;/p&gt;
&lt;h3 id=&#34;compute&#34;&gt;Compute&lt;/h3&gt;
&lt;p&gt;Back in April Scaleway posted this comparison in prices between them and competitors (i checked the numbers and they aren&amp;rsquo;t lying):

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;https://images-www.scaleway.com/wp-content/uploads/2020/04/08134712/instances_gp-benchmark_en.jpg&#34;   /&gt;
    
  &lt;/figure&gt;

&lt;/p&gt;
&lt;p&gt;(Linode are missing, but their pricing is identical to Digital Ocean&amp;rsquo;s - and I mean that literally, the only difference in &lt;a href=&#34;https://www.linode.com/pricing/&#34;&gt;Linode Standard Plans&lt;/a&gt; vs &lt;a href=&#34;https://www.digitalocean.com/pricing/#standard-droplets&#34;&gt;Standard Droplets&lt;/a&gt; is the network transfer each instance adds to your cap - compute, memory, even local storage space are the same and with the same price)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; Pricing is in USD regardless of location for Digital Ocean and Linode, in EUR for Scaleway, and OVHCloud propose different currencies depending on your location (EUR in Eurozone countries, PLN in Poland, CAD in Canada, etc.) The course at the time of writing is 1 USD = 0.89EUR | 1 EUR = 1.13 USD , but that doesn&amp;rsquo;t change the scale too drastically because the difference between Scaleway and OVHCloud, Digital Ocean/Linode, and then AWS/GCP/Azure is too big. In further comparisons, I&amp;rsquo;ll use prices in their original currency, as billed, and in parenthesis convert the values to euros/US dollars using today&amp;rsquo;s course.&lt;/p&gt;
&lt;p&gt;And it&amp;rsquo;s a great comparison, which shows they&amp;rsquo;re &lt;del&gt;slightly cheaper&lt;/del&gt; pretty much the same with their &lt;a href=&#34;https://blog.scaleway.com/2020/price-evolutions-cloud-instances/&#34;&gt;price hike&lt;/a&gt; starting 01/08/2020 when it comes to General Purpose instances compared to OVHCloud, and very cheaper compared to DO/Linode, and even more so to AWS/GCP/Azure. However they provide little flexibility in terms of CPU/RAM combinations, so if one requires a different ratio, they might not be the best option.&lt;/p&gt;
&lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt;
&lt;h4 id=&#34;block-storage&#34;&gt;Block Storage&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Storage class&lt;/th&gt;
&lt;th&gt;Price per GB/month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Digital Ocean&lt;/td&gt;
&lt;td&gt;SSD, 800-5000 IOPS, 20-200 MB/sec depending on block size&lt;/td&gt;
&lt;td&gt;$0.10 (€0.089)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;SSD, 5000 IOPS&lt;/td&gt;
&lt;td&gt;€0.08 ($0.09)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;SSD+, 10000 IOPS (coming mid-2020)&lt;/td&gt;
&lt;td&gt;€0.12 ($0.14)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHCloud&lt;/td&gt;
&lt;td&gt;Classic, 250 IOPS guaranteed&lt;/td&gt;
&lt;td&gt;€0.04 / 0.06 CA$ ($0.045 )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHCloud&lt;/td&gt;
&lt;td&gt;High speed, up to  3000 IOPS&lt;/td&gt;
&lt;td&gt;€0.08 / 0.138 CA$ ($0.09)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linode&lt;/td&gt;
&lt;td&gt;up to 5000 IOPS,  150MB/s&lt;/td&gt;
&lt;td&gt;$0.10 (€0.089)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Scaleway seem to have the best price/performance rate, Linode and Digital Ocean are again very similar, and OVHCloud are in a category of their own with very cheap but very slow storage, and a &amp;ldquo;high speed&amp;rdquo; class which is slower than the competition but more acceptable.&lt;/p&gt;
&lt;h4 id=&#34;object-storage&#34;&gt;Object storage&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Storage included&lt;/th&gt;
&lt;th&gt;Additional storage cost GB/month&lt;/th&gt;
&lt;th&gt;Outbound Transfer included&lt;/th&gt;
&lt;th&gt;Additional Outbound Transfer GB/month&lt;/th&gt;
&lt;th&gt;Basic price per month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Digital Ocean&lt;/td&gt;
&lt;td&gt;250GB&lt;/td&gt;
&lt;td&gt;$0.02 (€0.018)&lt;/td&gt;
&lt;td&gt;1TB&lt;/td&gt;
&lt;td&gt;$0.01 (€0.0089)&lt;/td&gt;
&lt;td&gt;$5 (€4.45)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;75GB&lt;/td&gt;
&lt;td&gt;€0.01 ($0.011)&lt;/td&gt;
&lt;td&gt;75GB&lt;/td&gt;
&lt;td&gt;€0.01 ($0.011)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHCloud&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;€0.01 / 0.015 CA$ ($0.011)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;€0.01 / 0.015 CA$ ($0.011)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linode&lt;/td&gt;
&lt;td&gt;250GB&lt;/td&gt;
&lt;td&gt;$0.02 (€0.018)&lt;/td&gt;
&lt;td&gt;1TB&lt;/td&gt;
&lt;td&gt;$0.01 (€0.0089)&lt;/td&gt;
&lt;td&gt;$5 (€4.45)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Once again, Scaleway are cheaper than everyone else (to be fair, they have the same prices as OVHCloud, but they have a decent free tier of 75GB of storage and 75GB transfer/month to start), and Digital Ocean and Linode have identical pricing.&lt;/p&gt;
&lt;h3 id=&#34;networking&#34;&gt;Networking&lt;/h3&gt;
&lt;h4 id=&#34;load-balancers&#34;&gt;Load balancers&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Load balancer class&lt;/th&gt;
&lt;th&gt;Price per month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Digital Ocean&lt;/td&gt;
&lt;td&gt;Load balancer&lt;/td&gt;
&lt;td&gt;$10 (€8.90)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;LB-GP-S, 200Mbps&lt;/td&gt;
&lt;td&gt;€8.99 ($10.11)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;LB-GP-M, 500Mbps&lt;/td&gt;
&lt;td&gt;€19.99 ($22.47)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;LB-GP-L, 1Gbps, Multicloud&lt;/td&gt;
&lt;td&gt;€49.99 ($56.20)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHCloud&lt;/td&gt;
&lt;td&gt;Network Load Balancer&lt;/td&gt;
&lt;td&gt;€10 / 16 CA$ ($11.24)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linode&lt;/td&gt;
&lt;td&gt;Nodebalancer&lt;/td&gt;
&lt;td&gt;$10 (€8.90)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Digital Ocean and Linode, with identical pricing once more, come out slightly cheaper than Scaleway, which are the only ones with different tiers and &lt;em&gt;guaranteed&lt;/em&gt; throughput and OVHCloud.&lt;/p&gt;
&lt;h4 id=&#34;network-transfer&#34;&gt;Network transfer&lt;/h4&gt;
&lt;p&gt;As I already mentioned, OVHCloud and Scaleway have unlimited (in volume) network transfer, while Linode and Digital Ocean apply an account-wide cap based on number and type of instances (starting from 1TB/droplet for DO, 2TB/ Linode for Linode), and anything extra costs $0.01/GB.&lt;/p&gt;
&lt;h2 id=&#34;sla--support&#34;&gt;SLA &amp;amp; Support&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Support tier&lt;/th&gt;
&lt;th&gt;SLA&lt;/th&gt;
&lt;th&gt;Response time&lt;/th&gt;
&lt;th&gt;Price per month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Digital Ocean&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;99.99% droplets and block storage&lt;/td&gt;
&lt;td&gt;No guarantee&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;99.9% network, 99.99% instances&lt;/td&gt;
&lt;td&gt;No guarantee&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;Developer&lt;/td&gt;
&lt;td&gt;99.9% network, 99.99% instances&lt;/td&gt;
&lt;td&gt;&amp;lt;12 hours&lt;/td&gt;
&lt;td&gt;€2.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;td&gt;99.9% network, 99.99% instances&lt;/td&gt;
&lt;td&gt;&amp;lt;2 hours&lt;/td&gt;
&lt;td&gt;&amp;ldquo;Starting at €49&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaleway&lt;/td&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;99.9% network, 99.99% instances&lt;/td&gt;
&lt;td&gt;&amp;lt;30 minutes&lt;/td&gt;
&lt;td&gt;&amp;ldquo;Starting at €499&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;99.999% instances&lt;/td&gt;
&lt;td&gt;No guarantee, ~8 hours (working hours)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud&lt;/td&gt;
&lt;td&gt;Premium&lt;/td&gt;
&lt;td&gt;99.999% instances&lt;/td&gt;
&lt;td&gt;No guarantee, ~2 hours (working hours)&lt;/td&gt;
&lt;td&gt;€50 / 72 CA$, 12 months minimum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud&lt;/td&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;td&gt;99.999% instances&lt;/td&gt;
&lt;td&gt;30mn - 8 hours depending on severity (24/7)&lt;/td&gt;
&lt;td&gt;&amp;ldquo;starting at&amp;rdquo; €250 / 360 CA$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud&lt;/td&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;99.999% instances&lt;/td&gt;
&lt;td&gt;15 minutes for P1 (24/7)&lt;/td&gt;
&lt;td&gt;&amp;ldquo;starting at&amp;rdquo; €5000 / &amp;ldquo;contact us&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linode&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;99.99% for all services&lt;/td&gt;
&lt;td&gt;No guarantee&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;99.99% for EC2&lt;/td&gt;
&lt;td&gt;No guarantee&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GCP&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;99.5% for a single GCE instance&lt;/td&gt;
&lt;td&gt;No guarantee&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;You can calculate how much is 99.9% with &lt;a href=&#34;https://uptime.is/&#34;&gt;uptime.is&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;OVHCloud and Scaleway are the only ones to offer business suport, and the former have the best SLA (99.999%, better than AWS EC2 at 99.99 or GCP at 99.5, which, to be fair, make it easier to run multi-zonal/regional, so an individual instance&amp;rsquo;s availability is of lesser importance), compared to everyone else&amp;rsquo;s 99.99%.&lt;/p&gt;
&lt;h2 id=&#34;conclusion-1&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Overall, it&amp;rsquo;s a pretty close match between Scaleway and Digital Ocean, with the latter beating based on availability (8 locations vs 1), but the former edging on features alone, and then some more based on pricing. OVHCloud simply aren&amp;rsquo;t ready yet (no node pools and no autoscaling are deal breakers) and with a poor UX and tooling, while Linode is too basic for most non-test workloads (recreating clusters to upgrade Kubernetes versions is too cumbersome) while costing almost exactly the same as DO.&lt;/p&gt;
&lt;p&gt;Of course, neither of them are on par with AWS or GCP in terms of geographical locations or services, and probably never could be. Nevertheless, they&amp;rsquo;re more than sufficient for lots of workloads, hitting a sweet spot of simple, cost-effective and feature-rich (or at least having the basic building blocks for those features - thanks to &lt;a href=&#34;https://github.com/operator-framework/awesome-operators&#34;&gt;Operators&lt;/a&gt; running pretty much anything yourself is getting easier), while still using widely available standards (Kubernetes) that allow mobility across cloud providers, if the needed arises.&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Getting started with Scaleway&#39;s managed Kubernetes service - Kapsule</title>
      <link>/2019/11/21/getting-started-with-scaleways-managed-kubernetes-service-kapsule/</link>
      <pubDate>Thu, 21 Nov 2019 18:26:15 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2019/11/21/getting-started-with-scaleways-managed-kubernetes-service-kapsule/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Scaleway is a French cloud provider that mostly specialises in (custom designed) bare metal ARM servers, standard VPSes, and has recently started adding some additional services like x86 bare metal servers, Load Balancers, a new and improved object storage, managed databases, container registry, managed firewalls, and, hotly anticipated, a managed Kubernetes Service, &lt;em&gt;Kapsule&lt;/em&gt;. There&amp;rsquo;s plenty of competition in the managed Kubernetes space, but Scaleway have a few potential advantages, most notably:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the possibility to have bare metal and ARM-based node pools (not yet available in the public beta, but ARM is kind of Scaleway&amp;rsquo;s speciality, so it&amp;rsquo;d be surprising if they didn&amp;rsquo;t offer it)&lt;/li&gt;
&lt;li&gt;decent integrated ecosystem - Load Balancers, Container Registry, block and object storage, and plenty of others &lt;em&gt;soon&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;pricing, which is on par with Digital Ocean&amp;rsquo;s pricing (even if the smallest possible node type is pretty big at 4vCPU/16GB RAM and at 39 euros/month), the control plane is free, and associated services aren&amp;rsquo;t expensive - load balancers are at 9 euros/month, container registry is at 0.025 euros/GB/month for storage, with networking free within the same region and at 0.03 euros/GB/month inter-region&lt;/li&gt;
&lt;li&gt;cluster upgrades, which aren&amp;rsquo;t offered by everyone (and for a long time neither Digital Ocean nor OVH proposed it, and Kapsule is younger than either of them)&lt;/li&gt;
&lt;li&gt;cluster autoscaling (based on the &lt;a href=&#34;https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler&#34;&gt;cluster autoscaler Kubernetes project&lt;/a&gt;), which, again, isn&amp;rsquo;t offered by everyone&lt;/li&gt;
&lt;li&gt;EU-based (datacenters in Paris and Amsterdam)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, let&amp;rsquo;s give a Kapsule cluster a spin and see if it lives up to my expectations.&lt;/p&gt;
&lt;h2 id=&#34;kapsule-overview&#34;&gt;Kapsule Overview&lt;/h2&gt;
&lt;p&gt;Currently Kapsule is in beta, so some features aren&amp;rsquo;t ready yet (like cluster autoscaling or upgrades from the web UI), and for now only the Paris region is supported.&lt;/p&gt;
&lt;p&gt;Kapsule clusters can use calico, weave, flannel or cilium for the overlay network, and upon creation Scaleway can optionally deploy traefik (1.x, for now) or nginx ingress controllers, and the Kubernetes dashboard (which of course you can do later on your own, via Helm or otherwise, but it&amp;rsquo;s a nice touch). You get an automatic wildcard DNS with your cluster&amp;rsquo;s &lt;code&gt;id.nodes.k8s.fr-par.scw.cloud&lt;/code&gt;, which can come in handy for testing.&lt;/p&gt;
&lt;h2 id=&#34;deploying-a-cluster&#34;&gt;Deploying a cluster&lt;/h2&gt;
&lt;p&gt;For now, cluster deployment is possible via &lt;a href=&#34;https://developers.scaleway.com/en/products/k8s/api/#post-d34797&#34;&gt;the API&lt;/a&gt;, the web console or &lt;a href=&#34;https://www.terraform.io/docs/providers/scaleway/r/k8s_cluster_beta.html&#34;&gt;terraform&lt;/a&gt; (which sadly wasn&amp;rsquo;t available when i started writing this post).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s deploy a small cluster via the API. First you&amp;rsquo;ll need your organization id and a token secret key, both available from the &lt;a href=&#34;https://console.scaleway.com/account/credentials&#34;&gt;credentials page&lt;/a&gt; of the Scaleway console, and export the latter for easier reuse to &lt;code&gt;SCALEWAY_TOKEN&lt;/code&gt; . Then, create a JSON file along these lines (updating the organization_id with yours), which is the bare minimum to create a 1.14.8 (on purpose, to test cluster upgrades to a more recent version, 1.15.x, later on) Kubernetes cluster with 2 GP-1S nodes in the default node pool, with calico and treafik ingress:&lt;/p&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34;&gt; 
&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 576 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Creating the following resources will cost you money, as per &lt;a href=&#34;https://www.scaleway.com/en/pricing/&#34;&gt;Scaleway&#39;s pricing page&lt;/a&gt;.
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;organization_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;k8s-test&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.14.8&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cni&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;calico&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dashboard&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ingress&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;default_pool_commercial_type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gp1_s&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;default_pool_autoscaling&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;default_pool_size&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then POST it to the Scaleway API in the right region (fr-par only for now):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XPOST  -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; -d @data.json https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we get a response straight away with the cluster ID and the DNS wildcard:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;autoscaler_config&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;balance_similar_node_groups&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;estimator&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;binpacking&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expander&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;random&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expendable_pods_priority_cutoff&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;-10&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_daemonsets_utilization&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_delay_after_add&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10m&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_disable&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_ip&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_port&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://f50f0126-b994-47a9-9949-b68a3ed1335b.api.k8s.fr-par.scw.cloud:6443&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cni&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;calico&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-09-15T15:32:01.278854200Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_core_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_mem_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_node_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dns_wildcard&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.f50f0126-b994-47a9-9949-b68a3ed1335b.nodes.k8s.fr-par.scw.cloud&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;f50f0126-b994-47a9-9949-b68a3ed1335b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;k8s-bal&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;organization_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;creating&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;sub_status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;no_details&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;: [],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-09-15T15:32:01.278854200Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.14.8&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Note down the cluster ID, and store it in a varialbe (like &lt;code&gt;CLUSTER_ID&lt;/code&gt;) for future use, so that you can check the status and get the kubeconfig file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XGET  -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;CLUSTER_ID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XGET  -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;CLUSTER_ID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/kubeconfig?dl=1&amp;#34;&lt;/span&gt; &amp;gt; /tmp/mycluster.kubeconfig&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the cluster is ready, we can check connectivity with &lt;code&gt;kubectl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export KUBECONFIG&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/tmp/mycluster.kubeconfig
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl cluster-info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Kubernetes master is running at https://f50f0126-b994-47a9-9949-b68a3ed1335b.api.k8s.fr-par.scw.cloud:6443
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CoreDNS is running at https://f50f0126-b994-47a9-9949-b68a3ed1335b.api.k8s.fr-par.scw.cloud:6443/api/v1/namespaces/kube-system/services/coredns:dns/proxy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To further debug and diagnose cluster problems, use &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;kubectl cluster-info dump&amp;#39;&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;testing-the-traefik-ingress-controller&#34;&gt;Testing the traefik ingress controller&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s create a simple Ingress for the Treafik dashboard deployed for us by Scaleway to test it and the Traefik Ingress Controller.&lt;/p&gt;
&lt;p&gt;First, generate a file which will contain the basic auth credentials with &lt;code&gt;htpasswd&lt;/code&gt; (apache2-utils package on Debian/Ubuntu), with the &lt;code&gt;-B&lt;/code&gt; option which forces bcrypt instead of the horribly outdated and insecure MD5 used by default, and create a Kubernetes secret in the &lt;code&gt;kube-system&lt;/code&gt; namespace based on it :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;htpasswd -c -B ./auth admin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;New password:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Re-type new password:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Adding password &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; user admin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create secret generic traefik-dash-basic-auth --from-file auth --namespace&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;kube-system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, create an Ingress object for the Traefik dashboard, swapping &lt;code&gt;XXX&lt;/code&gt; in the host field with your cluster id:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;extensions/v1beta1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Ingress&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;traefik-web-ui&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;namespace&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;kube-system&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;annotations&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;traefik.ingress.kubernetes.io/auth-type&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;basic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;traefik.ingress.kubernetes.io/auth-secret&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;traefik-dash-basic-auth&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;rules&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;host&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dashboard.XXX.nodes.k8s.fr-par.scw.cloud&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;http&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;path&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;backend&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;serviceName&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ingress-traefik&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;servicePort&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;admin&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and apply it:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -n&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;kube-system -f traefik-ingress.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;After that, going to dashboard.XXX.nodes.k8s.fr-par.scw.cloud should get you to the traefik dashboard, protected by the username and password you created with &lt;code&gt;htpasswd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So our cluster is up and running, and so is the Traefik ingress.&lt;/p&gt;
&lt;h3 id=&#34;kapsule-with-scaleways-container-registry&#34;&gt;Kapsule with Scaleway&amp;rsquo;s Container Registry&lt;/h3&gt;
&lt;p&gt;Scaleway provide a managed container registry service, called simply &amp;ldquo;Container Registry&amp;rdquo;. It&amp;rsquo;s rather barebones - no security scanning or anything, just a basic Docker Registry that is separated in &lt;code&gt;namespaces&lt;/code&gt; which have regionally unique names, can&amp;rsquo;t be recreated and can either be publicly accessible or private. If they are private, accessing them requires Scaleway API tokens, which aren&amp;rsquo;t scoped and thus give full read/write access to the Scaleway API, which isn&amp;rsquo;t great. You only pay for storage (0.025/GB/month) and traffic outside of the same region (a Kapsule cluster in fr-par pulling from a Container Registry in fr-par will cost nothing).&lt;/p&gt;
&lt;p&gt;To use it, you only need to create a namespace(more details on that below), &lt;code&gt;docker login&lt;/code&gt;, &lt;code&gt;docker build&lt;/code&gt; / &lt;code&gt;docker tag&lt;/code&gt; your image, and &lt;code&gt;docker push&lt;/code&gt; it, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker login rg.fr-par.scw.cloud -u anyuser -p &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker build . -t rg.fr-par.scw.cloud/sofixa/golang-example-web-server-k8s:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker push rg.fr-par.scw.cloud/sofixa/golang-example-web-server-k8s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To be able to use the container image created from inside Kapsule, if your registry is private, you need to configure the registry authentication on your cluster (&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/&#34;&gt;link to the official docs&lt;/a&gt;), by first creating the secret in your namespace with the Scaleway token:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl -n&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;lt;your-namespace&amp;gt; create secret docker-registry regcred --docker-server&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;rg.fr-par.scw.cloud --docker-username&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;anyuser --docker-password&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; --docker-email&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;lt;your-email&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then using &lt;code&gt;imagePullSecrets&lt;/code&gt; in your template spec on Deployments/Daemon Sets/Stateful Sets/Pods:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;matchLabels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# Label selector that determines which Pods belong to the DaemonSet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;template&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# Pod template&amp;#39;s label selector&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;rg.fr-par.scw.cloud/xxx/golang-example-web-server-k8s:1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;imagePullSecrets&lt;/span&gt;: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;regcred&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3 id=&#34;kapsule-with-scaleways-load-balancer&#34;&gt;Kapsule with Scaleway&amp;rsquo;s Load balancer&lt;/h3&gt;
&lt;p&gt;Scaleway&amp;rsquo;s Load Balancer service is an active-passive Load balancer that supports multiple frontends (listeners) and multiple backends (targets), which can be of different types, with pre-defined healthchecks for backends like PostgreSQL, MySQL, Redis, LDAP or plain old TCP or HTTP. It can do SSL offloading (via automatically provisioned Let&amp;rsquo;s Encrypt certificates) or SSL passthrough (by configuring a frontend and backend with TCP/443).&lt;/p&gt;
&lt;p&gt;To create a Scaleway Load Balancer from inside Kapsule, you need to create a Service of Type &lt;code&gt;LoadBalancer&lt;/code&gt;, like this:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;targetPort&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;type&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;LoadBalancer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Which creates a LB with one frontend on port 80, one backend with all Kapsule nodes containing your service (targeting it on port 80), with round-robin load balancing (the default). The Scaleway Cloud Controller doesn&amp;rsquo;t seem to be fully documented yet, so here is a list of the available annotations (kudos to ben from Scaleway&amp;rsquo;s Community Slack for sharing them):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-forward-port-algorithm #annotation to choose the load balancing algorithm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-sticky-sessions #annotation to enable cookie-based session persistence
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-sticky-sessions-cookie-name #annotation for the cookie name for sticky sessions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-type #health check used
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-delay #time between two consecutive health checks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-timeout #additional check timeout, after the connection has been already established
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-max-retries #number of consecutive unsuccessful health checks, after wich the server will be considered dead
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-http-uri #URI that is used by the &amp;#34;http&amp;#34; health check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-http-method #method used by the &amp;#34;http&amp;#34; health check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-http-code #HTTP code that the &amp;#34;http&amp;#34; health check will be matching against
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-mysql-user #MySQL user used to check the MySQL connection when using the &amp;#34;mysql&amp;#34; health check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-pgsql-user #PgSQL user used to check the PgSQL connection when using the &amp;#34;pgsql&amp;#34; health check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-send-proxy-v2 #annotation that enables PROXY protocol version 2 (must be supported by backend servers)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-timeout-server # maximum server connection inactivity time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-timeout-connect #maximum initical server connection establishment time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-timeout-tunnel #maximum tunnel inactivity time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-on-marked-down-action# annotation that modifes what occurs when a backend server is marked down&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Details about them and their possible values are available on the &lt;a href=&#34;https://developers.scaleway.com/en/products/lb/api/#post-db0bfe&#34;&gt;Load Balancer API docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cluster-upgrades&#34;&gt;Cluster upgrades&lt;/h2&gt;
&lt;p&gt;One of the most interesting features of Kapsule is the possibility to do rolling cluster upgrades, let&amp;rsquo;s test it!&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll create a random service behind a Load Balancer to test if our service stays up during the upgrade, as it should. To see what&amp;rsquo;s going on, the service will based on a DaemonSet (a pod running on each node) with a simple Golang http server which prints the node hostname. Along the way we&amp;rsquo;ll test Scaleway&amp;rsquo;s Load Balancer and Container Registry services.&lt;/p&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;First, create your container registry with a similar JSON file, editing the appropriate lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;My awesome container registry&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;organization_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;is_public&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and POST it to Scaleway&amp;rsquo;s API endpoint for Container Registry namespaces:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://api.scaleway.com/registry/v1/regions/%7Bregion%7D/namespaces&#34;&gt;https://api.scaleway.com/registry/v1/regions/{region}/namespaces&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XPOST  -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; -d @data.json https://api.scaleway.com/registry/v1/regions/fr-par/namespaces&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Second, clone the &lt;a href=&#34;https://github.com/sofixa/golang-example-web-server-k8s&#34;&gt;example code in my GitHub repository&lt;/a&gt; , build its Docker container, and push it to your registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone git@github.com:sofixa/golang-example-web-server-k8s.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd golang-example-web-server-k8s/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;docker build . -t rg.fr-par.scw.cloud/xxx/golang-example-web-server-k8s:1.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;docker push rg.fr-par.scw.cloud/xxx/golang-example-web-server-k8s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the image is successfully uploaded to the registry, let&amp;rsquo;s create a DaemonSet from it and a Load Balancer in front with the manifest files (based on the examples from the &lt;a href=&#34;#kapsule-with-scaleway-s-load-balancer&#34;&gt;Load Balancer&lt;/a&gt; and the &lt;a href=&#34;#kapsule-with-scaleway-s-container-registry&#34;&gt;Container Registry&lt;/a&gt; sections) in the same repository ( the DaemonSet manifest will try to use a &lt;code&gt;regcred&lt;/code&gt; secret to authentify to your registry, so if your registry is public, you should remove the &lt;code&gt;imagePullSecrets&lt;/code&gt; part from it):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create namespace test-golang
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;namespace/test-golang created
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -n&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;test-golang -f daemon-set.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;daemonset.apps/golang-test created
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -n&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;test-golang -f load-balancer.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service/golang-test created&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To get the Load Balancer&amp;rsquo;s external IP, &lt;code&gt;get&lt;/code&gt; the corresponding service and copy the &lt;code&gt;EXTERNAL-IP&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get svc -n&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;test-golang
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME          TYPE           CLUSTER-IP      EXTERNAL-IP     PORT&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;S&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;        AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;golang-test   LoadBalancer   10.38.179.245   51.159.25.121   80:31120/TCP   5d23h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the load balancer is ready, &lt;code&gt;curl&lt;/code&gt;-ing it&amp;rsquo;s public IP should get you a &lt;code&gt;200&lt;/code&gt; response code with a similar response body:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -v http://51.159.25.121   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* Rebuilt URL to: http://51.159.25.121/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*   Trying 51.159.25.121...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* TCP_NODELAY set
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* Connected to 51.159.25.121 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;51.159.25.121&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; port &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; GET / HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; Host: 51.159.25.121
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; User-Agent: curl/7.58.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; Accept: */*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt; HTTP/1.1 &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt; OK
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt; Date: Mon, &lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt; Nov &lt;span style=&#34;color:#ae81ff&#34;&gt;2019&lt;/span&gt; 20:11:57 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt; Content-Length: &lt;span style=&#34;color:#ae81ff&#34;&gt;65&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt; Content-Type: text/plain; charset&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;utf-8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hello world from scw-k8s-test-default-16b716e81c7a4!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* Connection &lt;span style=&#34;color:#75715e&#34;&gt;#0 to host 51.159.25.121 left intact&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Notice the response, which contains the node name, composed of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cluster name &lt;code&gt;k8s-test&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;node pool name &lt;code&gt;default&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;node id &lt;code&gt;16b716e81c7a4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;the-test&#34;&gt;The test&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s set up &lt;a href=&#34;https://github.com/tsenart/vegeta&#34;&gt;vegeta&lt;/a&gt;, a HTTP load testing tool, to test if our cluster continues to respond during a cluster upgrade. Follow the &lt;a href=&#34;https://github.com/tsenart/vegeta#install&#34;&gt;installation instructions&lt;/a&gt;, and do a quick test on your load balancer&amp;rsquo;s IP:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GET http://51.159.25.121&amp;#34;&lt;/span&gt; | vegeta attack -rate&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1/s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wResult	Attack
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              SeqCode	TimestampLatencBytesOutBytesInError
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                                           Body
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Timeb���6P&amp;lt;bAAHello world from scw-k8s-test-default-3cb12e55883e4!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;d���6*&amp;lt;H.�AAHello world from scw-k8s-test-default-3cb12e55883e4!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Everything seems to be working (ignore the binary output, vegeta output isn&amp;rsquo;t meant to be parsed directly by humans), you can quit/Ctrl+C the process.
You can now launch a continuous &amp;ldquo;attack&amp;rdquo; in vegeta parlance, storing the results in a json file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GET http://51.159.25.121&amp;#34;&lt;/span&gt; | vegeta attack -rate&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1/s | vegeta encode &amp;gt; results.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;cat&lt;/code&gt;-ing the file should result in a similar output, which contains all sorts of useful information for a normal load test (the main purpose of vegeta), but for our test case, only the response code and body (which is base64 encoded) matter:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;cat&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;results.json&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;jq&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;attack&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;seq&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T21:24:15.375938851+01:00&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;latency&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;21093314&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bytes_out&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bytes_in&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;65&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;SGVsbG8gd29ybGQgZnJvbSBzY3ctazhzLWVsb3F1ZW50LWxlaG1hbm4tZGVmYXVsdC0zY2IxMmU1NTg4M2U0IQo=&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code&gt;base64decode&lt;/code&gt; / &lt;code&gt;base64 -d&lt;/code&gt; on that body will get the same result as a bare curl:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;head -n &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; results.json | jq .body | base64 -i -d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hello world from scw-k8s-test-default-3cb12e55883e4!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the vegeta load test is running, time to launch an upgrade to the Kapsule cluster.&lt;/p&gt;
&lt;h3 id=&#34;the-upgrade&#34;&gt;The upgrade&lt;/h3&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34;&gt; 
&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 576 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; Always read the full Kubernetes release notes when doing an upgrade. API&#39;s get depreceated, breaking changes happen, stuff is no longer compatible, you should always check.
&lt;/div&gt;
&lt;p&gt;Kubernetes cluster upgrades are done in two main stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the control plane and all its components&lt;/li&gt;
&lt;li&gt;the worker node pools, a node at a time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;During the control plane upgrade, it remains accessible (worst case scenario you might get an EOF or two).
For a worker node to be updated, it needs to be drained from all pods. Scaleway do this for you automatically, but for that to happen there must be enough resources on the other nodes for all the pods required to be scheduled.&lt;/p&gt;
&lt;p&gt;Usually you can only upgrade a minor version at a time (e.g. 1.14.x to 1.15.x, but not 1.16.x directly), and this is the case with Scaleway. In any case, doing the upgrade over API is cooler, so that&amp;rsquo;s what we&amp;rsquo;ll do. All that&amp;rsquo;s required is a small JSON file with the version wanted (remember, only patches or a single minor version upwards are supported) and a boolean wether we want to upgrade the nodes as well (duh).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.15.5&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;upgrade_pools&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All that&amp;rsquo;s left to do is to POST that to the /upgrade endpoint:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XPOST -d @data.json  -H &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SCALEWAY_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;CLUSTER_ID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/upgrade&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Which would get a similar result:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;organization_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;37a7df83-e2f2-43aa-a181-170a52aec2ac&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T19:46:54.261230Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T20:49:16.331469260Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;k8s-test&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_ip&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_port&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_node_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;updating&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;sub_status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;deploy_controlplane&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.15.5&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cni&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;calico&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;: [],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_core_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_mem_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;34359738368&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b.api.k8s.fr-par.scw.cloud:6443&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dns_wildcard&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b.nodes.k8s.fr-par.scw.cloud&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;autoscaler_config&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_disable&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_delay_after_add&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10m&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;estimator&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;binpacking&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expander&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;random&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_daemonsets_utilization&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;balance_similar_node_groups&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expendable_pods_priority_cutoff&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;-10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;To check the status of the upgrade, you can use &lt;code&gt;GET&lt;/code&gt; the status of the cluster and the node pools via the Scaleway API on the &lt;code&gt;cluster&lt;/code&gt;, &lt;code&gt;pools&lt;/code&gt; and &lt;code&gt;nodes&lt;/code&gt; endpoints or &lt;code&gt;kubectl get nodes&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;curl&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-XGET&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-H&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: ${SCALEWAY_TOKEN}&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/${CLUSTER_ID}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;organization_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;37a7df83-e2f2-43aa-a181-170a52aec2ac&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T19:46:54.261230Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T21:04:47.430331Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;k8s-test&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_ip&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_port&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_node_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ready&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;sub_status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;deploy_controlplane&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.15.5&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cni&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;calico&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;: [],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_core_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_mem_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;34359738368&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b.api.k8s.fr-par.scw.cloud:6443&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dns_wildcard&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b.nodes.k8s.fr-par.scw.cloud&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;autoscaler_config&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_disable&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scale_down_delay_after_add&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10m&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;estimator&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;binpacking&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expander&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;random&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_daemonsets_utilization&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;balance_similar_node_groups&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expendable_pods_priority_cutoff&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;-10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;curl&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-XGET&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-H&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: ${SCALEWAY_TOKEN}&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/${CLUSTER_ID}/pools&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;total_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;pools&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;feb2c164-8805-4130-b5d3-57889dc35652&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T19:46:54.266926Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T21:02:09.443695Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_node_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;updating&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.16.2&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commercial_type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gp1_xs&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;autoscaling&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;min_size&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;max_size&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_core_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_mem_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;34359738368&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;container_runtime&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;autohealing&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;curl&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-XGET&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;-H&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;X-Auth-Token: ${SCALEWAY_TOKEN}&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://api.scaleway.com/k8s/v1beta2/regions/fr-par/clusters/${CLUSTER_ID}/nodes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;total_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;16b716e8-1c7a-4486-9861-067717cd44ea&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T19:47:52.240391Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T21:06:40.605505Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;pool_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;feb2c164-8805-4130-b5d3-57889dc35652&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ready&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;npd_status&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;DiskPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;KernelDeadlock&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;MemoryPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;NetworkUnavailable&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;PIDPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;Ready&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;scw-k8s-test-default-16b716e81c7a4&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;public_ip_v4&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;51.158.69.231&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;public_ip_v6&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fr-par&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3cb12e55-883e-404e-9617-9716a1ab22aa&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cluster_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ae336b4a-7875-4150-8b1c-ed1e4c9f3b2b&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T19:47:54.410118Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T21:06:40.732254Z&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;pool_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;feb2c164-8805-4130-b5d3-57889dc35652&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;notready&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;npd_status&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;DiskPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unknown&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;KernelDeadlock&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;MemoryPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unknown&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;NetworkUnavailable&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;PIDPressure&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unknown&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;Ready&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unknown&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;scw-k8s-test-default-3cb12e55883e4&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;public_ip_v4&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;51.15.217.30&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;public_ip_v6&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get nodes         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                                             STATUS                        ROLES    AGE   VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scw-k8s-test-default-16b716e81c7a4   Ready                         &amp;lt;none&amp;gt;   77m   v1.15.5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scw-k8s-test-default-3cb12e55883e4   NotReady,SchedulingDisabled   &amp;lt;none&amp;gt;   76m   v1.14.8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Upgrades are pretty quick (&amp;lt;5 minutes) if your cluster is empty, as was mine, but as usual, your mileage might vary.
However, they aren&amp;rsquo;t fully non-disruptive - checking the negative results of the vegeta run, we see there were a few timeouts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;less&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;results.json&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;jq&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;.&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;(.code&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;attack&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;seq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;41&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T22:02:41.187717035+01:00&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;latency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;30000794729&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_out&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_in&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Get http://51.159.25.121: net/http: request canceled (Client.Timeout exceeded while awaiting headers)&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;attack&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;seq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T22:02:42.187457957+01:00&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;latency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;30000935369&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_out&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_in&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Get http://51.159.25.121: net/http: request canceled (Client.Timeout exceeded while awaiting headers)&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;attack&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;seq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;43&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2019-11-11T22:02:43.187827619+01:00&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;latency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;30000555385&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_out&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bytes_in&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Get http://51.159.25.121: net/http: request canceled (Client.Timeout exceeded while awaiting headers)&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks like the Load balancer&amp;rsquo;s health check isn&amp;rsquo;t frequent enough to detect that the backend is down during upgrades. The Load Balancer &lt;a href=&#34;https://developers.scaleway.com/en/products/lb/api/#put-ec872a&#34;&gt;API docs&lt;/a&gt; show that it is possible to tweak the delay between checks (not available via the web UI though). As mentioned before, there are a few (not yet publicly documented) annotations we can use on our service object for that (the available choices and detailed explanations are available on the &lt;a href=&#34;https://developers.scaleway.com/en/products/lb/api/#post-db0bfe&#34;&gt;Load Balancer API page&lt;/a&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-delay &lt;span style=&#34;color:#75715e&#34;&gt;# time between two consecutive health checks, in milliseconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-timeout &lt;span style=&#34;color:#75715e&#34;&gt;# additional check timeout, after the connection has been already established&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-max-retries &lt;span style=&#34;color:#75715e&#34;&gt;# number of consecutive unsuccessful health checks, after wich the server will be considered dead&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is what our Service object could look like (example values, the precise ones will vary depending on your environment):
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;annotations&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-delay&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;10000&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# a check every 10s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-timeout&lt;/span&gt;:  &lt;span style=&#34;color:#ae81ff&#34;&gt;3000&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# a 3s timeout, which can be dangerously low&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;service.beta.kubernetes.io/scw-loadbalancer-health-check-max-retries&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# 2 retries&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#3c3d38&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;golang-test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;targetPort&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;type&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;LoadBalancer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;quick to provision and good provisioning tooling (API, terraform)&lt;/li&gt;
&lt;li&gt;good amount of features/integrations (cluster upgrades, autohealing, optional installation of dashboard, ingress for Kapsule, automatic cetrs via Let&amp;rsquo;s Encrypt and various healthchecks for Load Balancer)&lt;/li&gt;
&lt;li&gt;Container Registry is good enough and inexpensive (0.025 eur/GB/month for storage and 0.03 eur/GB/month traffic outside of the same region)&lt;/li&gt;
&lt;li&gt;Kubernetes versions come out pretty quickly (~1 week for 1.16)&lt;/li&gt;
&lt;li&gt;ecosystem is good - Scaleway have managed Databases, Object and Block storage, Load Balancers (which will soon be &lt;em&gt;multi-cloud&lt;/em&gt;) and a few potentially very interesting services in beta/preview like Serverless Functions, VPCs, IoT Hub, AI Inference, Domains (which includes promissing features like &amp;ldquo;&lt;em&gt;Dynamic routing capabilities: balance traffic depending on resource health and more to come&lt;/em&gt;&amp;rdquo; ), striking, for me, a fine balance between more basic platforms (Linode, Vultr, Digital Ocean to an extent) and full featured clouds (AWS, GCP, Azure) while still retaining pricing closer to the former&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;only relatively expensive instance types are available (starting at 40 eur/month), for now, making Kapsule less affordable compared to the main competitors - hopefully that will change soon, and we might even get bare metal nodes one day&lt;/li&gt;
&lt;li&gt;Container Registry auth requires a full Scaleway token, which gives full read/write API access - read-only tokens would be a cool addition&lt;/li&gt;
&lt;li&gt;documentation is somewhat lacking in some areas&lt;/li&gt;
&lt;li&gt;there&amp;rsquo;s no way to monitor/get statistics from services like Load Balancer or Container Registry; for Kapsule Heapster and metrics-server are preinstalled, so there&amp;rsquo;s access to Kubernetes-level statistics, but nothing else&lt;/li&gt;
&lt;li&gt;there&amp;rsquo;s no way to create and manage Scaleway ressources (other than Load Balancer and block storage) from inside Kapsule, like with GCP&amp;rsquo;s &lt;a href=&#34;https://cloud.google.com/config-connector/docs/reference/resources&#34;&gt;Cloud Connector&lt;/a&gt; (Note: you can probably use &lt;a href=&#34;https://kubeform.com/&#34;&gt;AppsCode Kubeform&lt;/a&gt; for that, since it&amp;rsquo;s just a Kubernetes CRD wrapper around terraform providers, and Scaleway&amp;rsquo;s terraform provider is pretty decent)&lt;/li&gt;
&lt;li&gt;cluster upgrades can result in small (a few seconds) downtimes with the default configuration, some fine tuning is required&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, in conclusion, Kapsule and the Scaleway stack are very interesting and evolving quickly, but come with some rough edges (well, Kapsule is still in beta, so completely normal). Once those are polished, Scaleway Kapsule and the rest of their ecosystem will make for a very compelling development / small-to-mid scale cloud environment, with just the right amount of managed services and features for a bargain price, and EU data sovereignty, which can be a requirement/plus in some cases.&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Using HashiCorp Sentinel to validate Terraform configuration/plan</title>
      <link>/2019/05/23/using-hashicorp-sentinel-to-validate-terraform-configuration/plan/</link>
      <pubDate>Thu, 23 May 2019 15:22:15 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2019/05/23/using-hashicorp-sentinel-to-validate-terraform-configuration/plan/</guid>
      <description>
        
          
          
          
        
        
        &lt;p&gt;Let me preface this by saying that i really like HashiCorp, their products and their open core business model. Their Enterprise stack is great with awesome features (Vault selective intercluster replication, Terraform team collaboration tooling, Sentinel Policy as Code, etc.), but if itss for personal use or a small business case that doesn&amp;rsquo;t require all Terraform Enterpirse Features and associated budget, using the freely available Sentinel Simulator in a somewhat hacky way could be a viable option (certainly beats having to write a custom tool to achieve the same thing).&lt;/p&gt;
&lt;h2 id=&#34;use-case&#34;&gt;Use case&lt;/h2&gt;
&lt;p&gt;I have some terraform configuration files, and mostly, plan files that i&amp;rsquo;d like to validate before applying. Things like the terraform version is appropriate, resources to add aren&amp;rsquo;t too big/expensive, there&amp;rsquo;s always a tag with some key, etc. I could write a custom tool to achieve that, or i could take advantage of Sentinel, HashiCorp&amp;rsquo;s Policy as Code framework/tool, which is sadly closed source and available only in Enterprise versions of HashiCorp&amp;rsquo;s stack. However, HashiCorp have &lt;a href=&#34;https://docs.hashicorp.com/sentinel/intro/getting-started/install&#34;&gt;Sentinel Simulator&lt;/a&gt; freely available to download, which &amp;ldquo;enables you to develop and test Sentinel policies locally on your own machine or in a CI environment&amp;rdquo;, which sounds great for what i need.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-with-sentinel-simulator&#34;&gt;Getting started with Sentinel Simulator&lt;/h2&gt;
&lt;p&gt;Start by downloading &lt;a href=&#34;https://docs.hashicorp.com/sentinel/downloads.html&#34;&gt;Sentinel Simulator&lt;/a&gt;&amp;rsquo;s latest version for your OS and architecture, setting the appropriate permissions (&lt;code&gt;chmod +x sentinel&lt;/code&gt; on *nix) and executing the binary, which should result in a similar output:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./sentinel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Usage: sentinel &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;--version&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;--help&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &amp;lt;command&amp;gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&amp;lt;args&amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Available commands are:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    apply      Execute a policy and output the result
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    doc        Show documentation &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; an import from a doc file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt        Format Sentinel policy to a canonical format
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    test       Test policies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    version    Prints the Sentinel Simulator version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Once that&amp;rsquo;s out of the way, you can start writing a policy - which is just a file with rules that assert and parse conditions and return true/false (pass/fail).&lt;/p&gt;
&lt;p&gt;An example policy is the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file: basic.sentinel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hour &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; hour &amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; and hour &amp;lt; &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With it, we declare a static variable &lt;code&gt;hour&lt;/code&gt; which is 4, and in the main rule (each policy needs to have a main rule) we check if  the &lt;code&gt;hour&lt;/code&gt; variable is between 0 and 12. Since it is, we&amp;rsquo;ll get a true/pass with exit code 0 when doing a &lt;code&gt;sentinel apply&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sentinel apply basic.sentinel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Pass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rules can be very complex (&lt;a href=&#34;https://docs.hashicorp.com/sentinel/intro/getting-started/rules&#34;&gt;Sentinel&amp;rsquo;s rule getting started guide&lt;/a&gt;), and most interestingly, can use dynamic data sources with &lt;a href=&#34;https://docs.hashicorp.com/sentinel/intro/getting-started/imports&#34;&gt;imports&lt;/a&gt;, which are, roughly speaking, plugins that communicate with an external data source like time, terraform plan output, etc.&lt;/p&gt;
&lt;p&gt;An example use of the time import and more complex rules (which do the same thing, checking if the hour is between 0 and 12), with a print:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file: time.sentinel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;import &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hour &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time.now.hour
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;minute &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time.now.minute
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;current time is&amp;#34;&lt;/span&gt;, hour, minute&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;past_midnight &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; hour &amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;before_noon   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; hour &amp;lt; &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    past_midnight and 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    before_noon
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Here we&amp;rsquo;re importing the &lt;a href=&#34;https://docs.hashicorp.com/sentinel/imports/time&#34;&gt;&amp;ldquo;time&amp;rdquo; plugin&lt;/a&gt;, and using the time.now.hour attribute (which gives us the current hour) to compare against 0 and 12, allowing us to do time-based rules (e.g. enforce &amp;ldquo;read-only Friday&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;In my case, since it&amp;rsquo;s 15:25, it will fail:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Thu May &lt;span style=&#34;color:#ae81ff&#34;&gt;23&lt;/span&gt; 15:25:29 UTC &lt;span style=&#34;color:#ae81ff&#34;&gt;2019&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./sentinel apply time.sentinel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Fail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Execution trace. The information below will show the values of all
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;the rules evaluated and their intermediate boolean expressions. Note that
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;some boolean expressions may be missing &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; short-circuit logic was taken.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Print messages:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;current time is &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;25&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FALSE - time.sentinel:10:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  TRUE - time.sentinel:11:5 - past_midnight
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TRUE - time.sentinel:7:24 - hour &amp;gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  FALSE - time.sentinel:12:5 - before_noon
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    FALSE - time.sentinel:8:24 - hour &amp;lt; &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FALSE - time.sentinel:8:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;before_noon&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TRUE - time.sentinel:7:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;past_midnight&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can do much more than simple comparisons (contains, is, not contains, is not, is not undefined, etc. - &lt;a href=&#34;https://docs.hashicorp.com/sentinel/language/&#34;&gt;full spec of the Sentinel language here&lt;/a&gt;)&lt;/p&gt;
&lt;h3 id=&#34;advanced-reading&#34;&gt;Advanced reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.hashicorp.com/sentinel/language/spec&#34;&gt;Sentinel Language Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.hashicorp.com/sentinel/language/funcs/&#34;&gt;Builtin Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.hashicorp.com/sentinel/imports/&#34;&gt;Standard imports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.hashicorp.com/sentinel/writing/testing&#34;&gt;Writing Sentinel Tests, inlcuding mocking data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-good-stuff&#34;&gt;The good stuff&lt;/h2&gt;
&lt;p&gt;Sentinel, &lt;a href=&#34;https://docs.hashicorp.com/sentinel/app/terraform/&#34;&gt;when used as a part of Terraform Enterpirse&lt;/a&gt;, has some terraform-related plugins like tfplan, which allow to do validations based on planned values. Sentinel Simulator, however, doesn&amp;rsquo;t have those closed source plugins, so the only way to use it in a similar fashion is via its &lt;a href=&#34;https://docs.hashicorp.com/sentinel/imports/json&#34;&gt;JSON parser plugin&lt;/a&gt;, since terraform configuration and plan can be previewed as JSON (Note: &lt;code&gt;terraform show (plan|state) -json&lt;/code&gt; exists only in terraform 0.12, for prior versions you&amp;rsquo;d need to use a tool like &lt;a href=&#34;https://github.com/palantir/tfjson&#34;&gt;tfjson&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;If you are already on terraform 0.12, &lt;a href=&#34;#terraform-show--json-starting-from-terraform-012&#34;&gt;skip to the relevant section&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;using-tfjson&#34;&gt;Using tfjson&lt;/h3&gt;
&lt;p&gt;First you need to install a (functional) version of tfjson, like &lt;a href=&#34;https://github.com/tapirs/tfjson&#34;&gt;tapirs/tfjson&lt;/a&gt; via go get:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go get github.com/tapirs/tfjson
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tfjson
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;usage: tfjson terraform.tfplan&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As an example, I manage my Digital Ocean Kubernetes cluster via terraform, I&amp;rsquo;ll increase the node_count to 3, and do a &lt;code&gt;terraform plan -out terraform.plan&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;terraform plan -out terraform.plan                                                                                                                    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Refreshing Terraform state in-memory prior to plan...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The refreshed state will be used to calculate this plan, but will not be
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;persisted to local or remote state storage.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;digitalocean_kubernetes_cluster.my_digital_ocean_cluster: Refreshing state... &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;ID: f8ee8505-af76-437e-864f-3751371374d8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;An execution plan has been generated and is shown below.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Resource actions are indicated with the following symbols:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ~ update in-place
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Terraform will perform the following actions:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ~ digitalocean_kubernetes_cluster.my_digital_ocean_cluster
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      node_pool.0.node_count: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Plan: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; to add, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; to change, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; to destroy.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;This plan was saved to: terraform.plan
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To perform exactly these actions, run the following command to apply:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    terraform apply &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;terraform.plan&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Running tfjson on the &lt;code&gt;terraform.plan&lt;/code&gt; file results in a JSON with the resources that will get added/modified with the appropriate values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;tfjson&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;terraform.plan&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;digitalocean_kubernetes_cluster.my_digital_ocean_cluster&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;destroy_tainted&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;node_pool.0.node_count&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sentinel can read JSON, either inline via the &lt;a href=&#34;https://docs.hashicorp.com/sentinel/imports/json&#34;&gt;json plugin&lt;/a&gt; or via the &lt;a href=&#34;https://docs.hashicorp.com/sentinel/commands/config#global-1&#34;&gt;global values configuration&lt;/a&gt;, which is available as a configuration file (&lt;code&gt;sentinel apply -config config.json&lt;/code&gt;) or an a command-line flag (&lt;code&gt;sentinel apply -global key=value&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Assuming tfjson&amp;rsquo;s output, an example policy that checks &lt;code&gt;destroy&lt;/code&gt; is true (meaning that applying the plan will result in destruction of resources - normally you&amp;rsquo;d want to check the opposite but this is just a test) :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file: tf.policy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;input.destroy is&amp;#34;&lt;/span&gt;,input.destroy&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;input.destroy is true&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we just need to pass the output of tfjson as the global variable &lt;code&gt;input&lt;/code&gt; to Sentinel:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sentinel apply -global input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;`tfjson terraform.plan`&amp;#34;&lt;/span&gt; tf.policy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Fail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Execution trace. The information below will show the values of all
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;the rules evaluated and their intermediate boolean expressions. Note that
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;some boolean expressions may be missing &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; short-circuit logic was taken.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Print messages:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;input.destroy is false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FALSE - tf.policy:2:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, the JSON output of &lt;code&gt;tfjson&lt;/code&gt; was successfully read, parsed and evaluated.&lt;/p&gt;
&lt;p&gt;Sadly, this would only work for the simplest of checks (&lt;code&gt;destroy&lt;/code&gt; is false) due to the way tfjson&amp;rsquo;s output is structured and Sentinel parses JSON (you can&amp;rsquo;t iterate on root-level keys). To be able to do more complex checks, a hacky workaround is required, to encapsulate tfjson&amp;rsquo;s output before passing it to Sentinel:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sentinel apply -global input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{\&amp;#34;data\&amp;#34;: `tfjson terraform.plan`}&amp;#34;&lt;/span&gt; tf.policy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
With the slighly modified policy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file: tf.policy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;input.data.destroy is&amp;#34;&lt;/span&gt;, input.data.destroy&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;input.data.destroy is true&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now a more complex policy with multiple advanced checks:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file: tf.policy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;input.data.destroy is&amp;#34;&lt;/span&gt;, input.data.destroy&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;no_destroys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input.data.destroy is false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dont_touch_my_kube &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;data&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; data as i, j &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		// skipping the destroy value since there is a dedicated rule &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; it
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; i contains &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;digitalocean_kubernetes_cluster&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Refusing modification of digitalocean_kubernetes_cluster resources&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;true&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; no_destroys and dont_touch_my_kube&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;input.data&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sentinel apply -global input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{\&amp;#34;data\&amp;#34;: `tfjson terraform.plan`}&amp;#34;&lt;/span&gt; tf.policy 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Fail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Execution trace. The information below will show the values of all
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;the rules evaluated and their intermediate boolean expressions. Note that
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;some boolean expressions may be missing &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; short-circuit logic was taken.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Print messages:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;input.data.destroy is false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;digitalocean_kubernetes_cluster.my_digital_ocean_cluster
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Refusing modification of digitalocean_kubernetes_cluster resources
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FALSE - tf.policy:23:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  TRUE - tf.policy:23:15 - no_destroys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TRUE - tf.policy:4:2 - input.data.destroy is false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  FALSE - tf.policy:23:31 - dont_touch_my_kube&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;input.data&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TRUE - tf.policy:3:1 - Rule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;no_destroys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Since there are no destroys, the first rule is successful, but the second (which is a function to be able to properly parse the JSON object) fails since there are modifications to be done on a &lt;code&gt;digitalocean_kubernetes_cluster&lt;/code&gt; resource, which isn&amp;rsquo;t allowed.&lt;/p&gt;
&lt;h3 id=&#34;terraform-show--json-starting-from-terraform-012&#34;&gt;Terraform show -json (starting from terraform 0.12)&lt;/h3&gt;
&lt;p&gt;Since terraform version 0.12 (which includes some very cool new features, if you haven&amp;rsquo;t checked it out &lt;a href=&#34;https://www.hashicorp.com/blog/announcing-terraform-0-12&#34;&gt;here&amp;rsquo;s the announcement blog post&lt;/a&gt;), there&amp;rsquo;s a &lt;code&gt;-json&lt;/code&gt; option to terraform show which works on terraform plans, so you can preview them in JSON format, perfect for checks via Sentinel or other tools. Let&amp;rsquo;s see what that looks like with Sentinel:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;terraform -v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Terraform v0.12.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+ provider.digitalocean v1.3.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;terraform plan -out terraform.plan
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;terraform show -json terraform.plan 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This should result in a pretty sizeable JSON, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;terraform version&lt;/li&gt;
&lt;li&gt;providers&amp;rsquo; configuration&lt;/li&gt;
&lt;li&gt;all current resources&lt;/li&gt;
&lt;li&gt;planned changes&lt;/li&gt;
&lt;li&gt;output changes&lt;/li&gt;
&lt;li&gt;yet unknown values&lt;/li&gt;
&lt;li&gt;variables&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, it&amp;rsquo;s pretty cool and you can get wild with policies. Off the top of my head:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;providers&amp;rsquo; configuration doesn&amp;rsquo;t have static values, only variables / Vault data source&lt;/li&gt;
&lt;li&gt;terraform version is good&lt;/li&gt;
&lt;li&gt;there are no variables with X or Y (like passwords or generic admin username)&lt;/li&gt;
&lt;li&gt;no resources are used at the root level (only modules)&lt;/li&gt;
&lt;li&gt;and the plain old (value X isn&amp;rsquo;t bigger than Y), like AWS/GCP/Azure instance types, Lambda memory settings, security groups SSH open from 0.0.0.0/, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few examples for inspiration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# file tf.policy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;allowed_node_sizes &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;s-1vcpu-2gb&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;allowed_regions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ams3&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;allowed_tf_versions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.12.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;node_pool_max_size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tf_version &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	input.terraform_version in allowed_tf_versions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;no_destroys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; input.resource_changes as change &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; change.change.actions contains &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			print&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No destroys allowed&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;true&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;max_nodepool_size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; input.resource_changes as change &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; change.address contains &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;digitalocean_kubernetes_cluster&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; change.change.after.node_pool as pool &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; pool.node_count &amp;gt; node_pool_max_size &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					error&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Node pool&amp;#34;&lt;/span&gt;, pool.name, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;shouldn&amp;#39;t exceed max node size&amp;#34;&lt;/span&gt;, node_pool_max_size, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;it&amp;#39;s currently&amp;#34;&lt;/span&gt;, pool.node_count&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;true&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;region_check &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; input.configuration.root_module.resources as resource &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; resource.expressions.region.constant_value not in allowed_regions &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;true&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;node_size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; input.resource_changes as change &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; change.address contains &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;digitalocean_kubernetes_cluster&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; change.change.after.node_pool as pool &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; pool.size not in allowed_node_sizes &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;					&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;true&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rule &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	tf_version and no_destroys&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; and region_check&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; and max_nodepool_size&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; and node_size&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This example policy checks the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node types&lt;/li&gt;
&lt;li&gt;number of nodes&lt;/li&gt;
&lt;li&gt;no destroys&lt;/li&gt;
&lt;li&gt;terraform version hasn&amp;rsquo;t been updated&lt;/li&gt;
&lt;li&gt;no resources are created outside of the allowed region (AMS3)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To run it, you need to apply sentinel with &lt;code&gt;terraform show&lt;/code&gt;&amp;rsquo;s output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sentinel apply -global input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;`terraform show -json terraform.plan`&amp;#34;&lt;/span&gt; tf.policy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It took me roughly 15 minutes to write and test basic functionality, and i have a decent chunk of stuff covered (for my limited use case).&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Sentinel is an awesome Policy As Code tool from HashiCorp which can be run locally via Sentinel Simulator and be used to validate any sort of JSON, like the output from a terraform plan.&lt;/p&gt;
&lt;h2 id=&#34;coming-up-next&#34;&gt;Coming up next&lt;/h2&gt;
&lt;p&gt;While searching for a Policy/Validation as code tool, i asked around the &lt;a href=&#34;https://t.me/devopsish&#34;&gt;DevOps&amp;rsquo;ish Telegram group&lt;/a&gt; and someone proposed &lt;a href=&#34;https://github.com/instrumenta/conftest&#34;&gt;conftest&lt;/a&gt;, which seems more flexible, advanced and complicated (with a Go-like syntax compared to Sentinel&amp;rsquo;s HCL-like DSL), not to mention free, open source and usable directly without workarounds. I&amp;rsquo;d like to give it a try and compare the two tools.&lt;/p&gt;

        
        </description>
    </item>
    
    <item>
      <title>Creating a static blog with Hugo on Firebase Hosting delivered with Drone CI</title>
      <link>/2018/10/23/creating-a-static-blog-with-hugo-on-firebase-hosting-delivered-with-drone-ci/</link>
      <pubDate>Tue, 23 Oct 2018 20:22:21 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2018/10/23/creating-a-static-blog-with-hugo-on-firebase-hosting-delivered-with-drone-ci/</guid>
      <description>
        
          
          
          
        
        
        &lt;h2 id=&#34;preface&#34;&gt;Preface&lt;/h2&gt;
&lt;p&gt;Hello there. After years of hesitation, i finally got the courage to start my blog as an excuse to play with some cool tech i don&amp;rsquo;t have the chance to do at work.
Of course, there is no fun in using something easy like WordPress, so i chose &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt;, a static site generator. This way i can have everything in Git, and have a CI/CD pipeline that deploys it somewhere.&lt;/p&gt;
&lt;h2 id=&#34;the-stack&#34;&gt;The stack&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been eyeing Hugo for more than a year, and i prefer its syntax and flexibility to Jekyll, so that&amp;rsquo;s that. For Git GitHub should do the trick; for CI/CD, i&amp;rsquo;ve always liked &lt;a href=&#34;https://drone.io/&#34;&gt;Drone&lt;/a&gt; on paper - configuration is in simple .yml file per repo, everything is a plugin (which in itself is just a Docker container), and it seems like a good opportunity to give it an actual go.&lt;/p&gt;
&lt;p&gt;Originally i thought about using AWS S3 for hosting the static files, and CloudFront for CDN and SSL, but i already work with AWS and it&amp;rsquo;s something i&amp;rsquo;ve already done, so there was no challenge. Google Cloud Platform it is then, with its nice &amp;ldquo;Always Free&amp;rdquo; tier.&lt;/p&gt;
&lt;p&gt;However, upon some reading on the Google Cloud Storage (GCS) docs and Henry Lawson&amp;rsquo;s &lt;a href=&#34;https://henrylawson.net/static-website-hosting-on-google-cloud-platform-gcp&#34;&gt;blog post on the subject&lt;/a&gt; i realised that blindly applying what i know about AWS won&amp;rsquo;t work. Like him, i imagined it the following way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Static content gets uploaded to GCS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Google Cloud CDN serves it with a custom SSL cert&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, there are a few problems with that - GCS doesn&amp;rsquo;t need CDN because it does caching by default, but it doesn&amp;rsquo;t support SSL with custom domains. Not a problem, i&amp;rsquo;ll just use Cloud CDN for that! Well, apparently it requires a Load Balancer, which costs money and seems way too overkill.&lt;/p&gt;
&lt;p&gt;So, &lt;a href=&#34;https://firebase.google.com/docs/hosting/&#34;&gt;Firebase Hosting&lt;/a&gt; enters the stage. It&amp;rsquo;s oriented towards static site hosting, supports SSL with custom domains and also has an always free tier. Furthermore, the &lt;a href=&#34;https://firebase.google.com/products/&#34;&gt;Firebase suite&lt;/a&gt; has some pretty interesting products which can come to use for a static blog/ongoing experiment, most notably &lt;a href=&#34;https://firebase.google.com/products/firestore/&#34;&gt;Cloud Firesotre&lt;/a&gt;, a managed NoSQL database, which, coupled with &lt;a href=&#34;https://firebase.google.com/products/functions/&#34;&gt;Cloud Functions&lt;/a&gt; i can use to add some dynamic parts.&lt;/p&gt;
&lt;h2 id=&#34;roadmap&#34;&gt;Roadmap&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m assuming you already have Hugo installed and running - if that&amp;rsquo;s not the case, you can check out &lt;a href=&#34;https://gohugo.io/getting-started/quick-start/&#34;&gt;Hugo&amp;rsquo;s Quick Start guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll start by setting up Firebase and DroneCI, and then creating a pipeline to generate the static files with Hugo and deploy them to Firebase Hosting. Once that&amp;rsquo;s up and running, i&amp;rsquo;ll look into adding the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;tests before deploying the pipeline - a spellchecker, for instance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a dynamic comment section and a newsletter with the help of Cloud Functions and other parts of the Firebase/Google Cloud Platform suite&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;search with &lt;a href=&#34;https://lunrjs.com/&#34;&gt;lunr.js&lt;/a&gt;, &lt;a href=&#34;http://fusejs.io/&#34;&gt;fuse.js&lt;/a&gt;, &lt;a href=&#34;https://www.algolia.com&#34;&gt;algolia&lt;/a&gt; or something else&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, let&amp;rsquo;s get started.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-with-firebase-hosting&#34;&gt;Getting started with Firebase Hosting&lt;/h2&gt;
&lt;p&gt;First you need to create your Firebase project. To do that, you have to connect to the &lt;a href=&#34;https://console.firebase.google.com/&#34;&gt;Firebase Console&lt;/a&gt; with a Google account, and click on the big &amp;ldquo;Add project&amp;rdquo; button. There you have to create a project with a cool name (in my case it&amp;rsquo;s just &amp;ldquo;Blog&amp;rdquo;, you can be more original than that), or use an existing one from Google Cloud Platform. Once its created / selected, we arrive at the pretty slick looking Firebase console. There are plenty of features, but for now i&amp;rsquo;ll just stick to the CLI (easier to document, gitify, redo one day if necessary).&lt;/p&gt;
&lt;p&gt;To start using the Firebase CLI, you need to have Node.js and npm installed, afterwards it&amp;rsquo;s as easy a single command to install and another one to login (which opens a page where you sign in with your Google account and authorise the CLI to access your Google Cloud Platform):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install -g firebase-tools
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;firebase login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you have to create a folder which will contain our project (or if you already have a folder with Hugo, just cd inside), and initialise the Firebase CLI in it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir blog &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; cd blog
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;firebase init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The CLI then launches an interactive setup which asks questions, like which services do we want to setup (for now just Hosting ), what Firebase project are we working on, security rules, the folder we want to publish to Firebase Hosting (public by default and a sensible choice considering it&amp;rsquo;s also Hugo&amp;rsquo;s default):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;You&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;re about to initialize a Firebase project in this directory:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  /home/ato/blog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;? Which Firebase CLI features do you want to setup for this folder?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Press Space to select features, then Enter to confirm your choices.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; ◯ Database: Deploy Firebase Realtime Database Rules
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; ◯ Firestore: Deploy rules and create indexes for Firestore
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; ◯ Functions: Configure and deploy Cloud Functions
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;❯◉ Hosting: Configure and deploy Firebase Hosting sites
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; ◯ Storage: Deploy Cloud Storage security rules
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;=== Project Setup
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;First, let&amp;#39;&lt;/span&gt;s associate this project directory with a Firebase project.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;You can create multiple project aliases by running firebase use --add,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;but &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; now we&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;ll just set up a default project.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;? Select a default Firebase project for this directory: (Use arrow keys)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  [don&amp;#39;&lt;/span&gt;t setup a default project&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;❯ Blog &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;create a new project&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; Hosting Setup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Your public directory is the folder &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;relative to your project directory&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; that
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;will contain Hosting assets to be uploaded with firebase deploy. If you
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;have a build process &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; your assets, use your build&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt;s output directory.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;? What &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; you want to use as your public directory? &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;public&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;? Configure as a single-page app &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;rewrite all urls to /index.html&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;? &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;y/N&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Wrote public/404.html
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Wrote public/index.html
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  Writing configuration info to firebase.json...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  Writing project information to .firebaserc...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Firebase initialization complete!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now you have the Firebase CLI installed and configured.&lt;/p&gt;
&lt;p&gt;Since it installed a default index.html in the public folder (public in my case), you can test if everything is running fine locally with the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;firebase serve --only hosting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; Serving from &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/home/ato/blog&amp;#39;&lt;/span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: Serving hosting files from: public
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: Local server: http://localhost:5000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Opening http://localhost:5000 should give us the default Firebase page.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s deploy it to Firebase Hosting:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;firebase deploy                                       
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; Deploying to &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;blog-314450&amp;#39;&lt;/span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: beginning deploy...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: found &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; files in public
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: file upload complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: finalizing version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: version finalized
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: releasing new version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: release complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Deploy complete!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Project Console: https://console.firebase.google.com/project/blog-314450/overview
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hosting URL: https://blog-314450.firebaseapp.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you go check the URL at the end, you should see the same default Firebase index.html.&lt;/p&gt;
&lt;p&gt;So far, Firebase Hosting is up and running. Time to deploy our Hugo generated website to it!&lt;/p&gt;
&lt;h2 id=&#34;generating-static-files-with-hugo-and-deploying-them-on-firebase-hosting&#34;&gt;Generating static files with Hugo and deploying them on Firebase Hosting&lt;/h2&gt;
&lt;p&gt;Generating static HTML with Hugo is as simple as running a single command, which will put the files in the public folder (by default, modifiable with the publishDir parameter in your site&amp;rsquo;s config):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Building sites …
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   | EN  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+------------------+----+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Pages            | &lt;span style=&#34;color:#ae81ff&#34;&gt;37&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Paginator pages  |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Non-page files   |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Static files     | &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Processed images |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Aliases          | &lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Sitemaps         |  &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Cleaned          |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that&amp;rsquo;s it, you should now have the HTML ready in the public folder, and all that&amp;rsquo;s left is to run &lt;em&gt;firebase deploy&lt;/em&gt; and deploy to your website on Firebase Hosting:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;➜  blog git:&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;master&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; ✗ firebase deploy                                                                                                                                                                
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; Deploying to &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;blog-314450&amp;#39;&lt;/span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  deploying hosting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: beginning deploy...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: found &lt;span style=&#34;color:#ae81ff&#34;&gt;67&lt;/span&gt; files in public
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: file upload complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: finalizing version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: version finalized
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: releasing new version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: release complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Deploy complete!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Project Console: https://console.firebase.google.com/project/blog-314450/overview
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hosting URL: https://blog-314450.firebaseapp.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Refreshing the webpage should now show your webite up and running, fully static and for free.&lt;/p&gt;
&lt;p&gt;Now, that was simple enough, but you don&amp;rsquo;t want to actually do this manually every time, so let&amp;rsquo;s set up a CI/CD pipeline that will rebuild the Hugo site and deploy it to Firebase every time there&amp;rsquo;s a new commit (it goes without saying, Hugo uses text files for everything, and if it&amp;rsquo;s text and it matters, it should be stored in Git).&lt;/p&gt;
&lt;h2 id=&#34;getting-started-with-drone&#34;&gt;Getting started with Drone&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://drone.io&#34;&gt;Drone&lt;/a&gt; is a &lt;em&gt;cloud-native&lt;/em&gt; CI/CD system, heavily based around Docker. Pipelines are defined with YAML files, contain multiple stages and each stage is a plugin (which is a Docker container that uses environment variables to read it&amp;rsquo;s configuration and it does stuff). There&amp;rsquo;s a plethora of &lt;a href=&#34;http://plugins.drone.io/&#34;&gt;official plugins&lt;/a&gt;, and it&amp;rsquo;s pretty easy to create a new one in &lt;a href=&#34;http://docs.drone.io/creating-custom-plugins-golang/&#34;&gt;Golang&lt;/a&gt; or even &lt;a href=&#34;http://docs.drone.io/creating-custom-plugins-bash/&#34;&gt;Bash&lt;/a&gt; - basically anything that could run inside Docker. There&amp;rsquo;s already an existing &lt;a href=&#34;http://plugins.drone.io/drone-plugins/drone-hugo/&#34;&gt;plugin&lt;/a&gt; for Hugo, which will handle the generation of static files.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: at the time of writing, the latest version of Drone is 0.8&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Installation&amp;rdquo; is pretty easy - you just have to run two Docker containers available on Docker Hub. It&amp;rsquo;s even easier with Docker Compose, which orchestrates that with a relatively simple YAML file (for getting started with it, you can check &lt;a href=&#34;https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-16-04&#34;&gt;Digital Ocean&amp;rsquo;s great installation guide&lt;/a&gt; ).&lt;/p&gt;
&lt;p&gt;After you have Docker Compose up and running, create the following docker-compose.yml file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Docker Compose configuration version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;version&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# With the services block we define each &amp;#34;service&amp;#34; (Docker container and associated configuration) we want to run&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;drone-server&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# drone-server, which is the backend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;drone/drone:0.8&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# the Docker image we&amp;#39;re using, which is drone/drone (group/project:version) from the public Docker Hub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;ports&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# the list of ports to expose - with an optional host-port:container port mapping&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;8000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;9000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;volumes&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# Docker Volumes, the way to manage persistent data, in this case Drone&amp;#39;s internal SQLite database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;drone-server-data:/var/lib/drone/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;restart&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;always&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# If the container dies / crashes, dockerd will restart it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;environment&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# Drone-specific environment variables we use to configure our container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_OPEN=true&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# is our Drone instance publicly available, true or false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_HOST=${DRONE_HOST}&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# the URL on which Drone will be accessible, in a &amp;lt;scheme&amp;gt;://&amp;lt;hostname&amp;gt; format&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_SECRET=${DRONE_SECRET}&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# a random secret string shared between drone and drone-agent to secure communication&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;# activate GitHub authentication for Drone - http://docs.drone.io/install-for-github/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_GITHUB=true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_GITHUB_CLIENT=${DRONE_GITHUB_CLIENT}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_GITHUB_SECRET=${DRONE_GITHUB_SECRET}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;drone-agent&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# drone-agent, which is the frontend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;drone/agent:0.8&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;command&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;agent&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# a command to execute upon starting the container, in this case launching Drone Agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;restart&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;depends_on&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# explicit dependency to make sure the Agent will start only after Drone Server is alive and well&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;drone-server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;volumes&lt;/span&gt;: &lt;span style=&#34;color:#75715e&#34;&gt;# we&amp;#39;re passing the Docker socket so that Drone Agent can manage the host&amp;#39;s dockerd and spawn containers on it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_SERVER=drone-server:9000&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# drone-server will resolve to the drone-server container&amp;#39;s IP automagically&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;DRONE_SECRET=${DRONE_SECRET}&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# same secret we passed to drone-server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;volumes&lt;/span&gt;:  &lt;span style=&#34;color:#75715e&#34;&gt;# we define the drone-server-data volume&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;drone-server-data:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Highlighted are the lines you probably should change, as well as those that require your input - &lt;em&gt;${SOMETHING}&lt;/em&gt; needs to be replaced with the appropriate value (GitHub credentials, Drone URL, etc.).
The most important ones are DRONE_SECRET and the version control configuration (&lt;a href=&#34;http://docs.drone.io/install-for-github/&#34;&gt;GitHub&lt;/a&gt;, &lt;a href=&#34;http://docs.drone.io/install-for-gitlab/&#34;&gt;GitLab&lt;/a&gt;, &lt;a href=&#34;http://docs.drone.io/install-for-gitea/&#34;&gt;Gitea&lt;/a&gt;, &lt;a href=&#34;http://docs.drone.io/install-for-gogs/&#34;&gt;Gogs&lt;/a&gt; and &lt;a href=&#34;http://docs.drone.io/install-for-bitbucket-cloud/&#34;&gt;BitBucket Cloud&lt;/a&gt; are supported ).&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve modified the file to your liking, run the following command to get everything up:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker-compose up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If everything is fine, you should see something like this (basically docker-compose creating the Docker containers and what they need to run(virtual network, volume) and then Drone&amp;rsquo;s logs, which are pretty verbose ):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating network &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dronecompose_default&amp;#34;&lt;/span&gt; with the default driver
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating dronecompose_drone-server_1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating dronecompose_drone-agent_1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Attaching to dronecompose_drone-server_1, dronecompose_drone-agent_1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;WARNING&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; Running in &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;debug&amp;#34;&lt;/span&gt; mode. Switch to &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;release&amp;#34;&lt;/span&gt; mode in production.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  |  - using env:	export GIN_MODE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;release
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  |  - using code:	gin.SetMode&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;gin.ReleaseMode&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /logout                   --&amp;gt; github.com/drone/drone/server.GetLogout &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /login                    --&amp;gt; github.com/drone/drone/server.HandleLogin &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/user                 --&amp;gt; github.com/drone/drone/server.GetSelf &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/user/feed            --&amp;gt; github.com/drone/drone/server.GetFeed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/user/repos           --&amp;gt; github.com/drone/drone/server.GetRepos &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/user/token           --&amp;gt; github.com/drone/drone/server.PostToken &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/user/token           --&amp;gt; github.com/drone/drone/server.DeleteToken &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/users                --&amp;gt; github.com/drone/drone/server.GetUsers &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/users                --&amp;gt; github.com/drone/drone/server.PostUser &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/users/:login         --&amp;gt; github.com/drone/drone/server.GetUser &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; PATCH  /api/users/:login         --&amp;gt; github.com/drone/drone/server.PatchUser &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/users/:login         --&amp;gt; github.com/drone/drone/server.DeleteUser &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name   --&amp;gt; github.com/drone/drone/server.PostRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name   --&amp;gt; github.com/drone/drone/server.GetRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/builds --&amp;gt; github.com/drone/drone/server.GetBuilds &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/builds/:number --&amp;gt; github.com/drone/drone/server.GetBuild &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/logs/:number/:pid --&amp;gt; github.com/drone/drone/server.GetProcLogs &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/logs/:number/:pid/:proc --&amp;gt; github.com/drone/drone/server.GetBuildLogs &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/files/:number --&amp;gt; github.com/drone/drone/server.FileList &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/files/:number/:proc/&lt;span style=&#34;color:#ae81ff&#34;&gt;\*&lt;/span&gt;file --&amp;gt; github.com/drone/drone/server.FileGet &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/secrets --&amp;gt; github.com/drone/drone/server.GetSecretList &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/secrets --&amp;gt; github.com/drone/drone/server.PostSecret &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/secrets/:secret --&amp;gt; github.com/drone/drone/server.GetSecret &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; PATCH  /api/repos/:owner/:name/secrets/:secret --&amp;gt; github.com/drone/drone/server.PatchSecret &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name/secrets/:secret --&amp;gt; github.com/drone/drone/server.DeleteSecret &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/registry --&amp;gt; github.com/drone/drone/server.GetRegistryList &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/registry --&amp;gt; github.com/drone/drone/server.PostRegistry &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/repos/:owner/:name/registry/:registry --&amp;gt; github.com/drone/drone/server.GetRegistry &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; PATCH  /api/repos/:owner/:name/registry/:registry --&amp;gt; github.com/drone/drone/server.PatchRegistry &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name/registry/:registry --&amp;gt; github.com/drone/drone/server.DeleteRegistry &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; PATCH  /api/repos/:owner/:name   --&amp;gt; github.com/drone/drone/server.PatchRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name   --&amp;gt; github.com/drone/drone/server.DeleteRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/chown --&amp;gt; github.com/drone/drone/server.ChownRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/repair --&amp;gt; github.com/drone/drone/server.RepairRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/move --&amp;gt; github.com/drone/drone/server.MoveRepo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/builds/:number --&amp;gt; github.com/drone/drone/server.PostBuild &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name/builds/:number --&amp;gt; github.com/drone/drone/server.ZombieKill &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/builds/:number/approve --&amp;gt; github.com/drone/drone/server.PostApproval &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/repos/:owner/:name/builds/:number/decline --&amp;gt; github.com/drone/drone/server.PostDecline &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-agent_1   | &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;time&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2018-09-26T20:52:39Z&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;debug&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;request next execution&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name/builds/:number/:job --&amp;gt; github.com/drone/drone/server.DeleteBuild &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; DELETE /api/repos/:owner/:name/logs/:number --&amp;gt; github.com/drone/drone/server.DeleteBuildLogs &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/badges/:owner/:name/status.svg --&amp;gt; github.com/drone/drone/server.GetBadge &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/badges/:owner/:name/cc.xml --&amp;gt; github.com/drone/drone/server.GetCC &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /hook                     --&amp;gt; github.com/drone/drone/server.PostHook &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/hook                 --&amp;gt; github.com/drone/drone/server.PostHook &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /stream/events            --&amp;gt; github.com/drone/drone/server.EventStreamSSE &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /stream/logs/:owner/:name/:build/:number --&amp;gt; github.com/drone/drone/server.LogStreamSSE &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/info/queue           --&amp;gt; github.com/drone/drone/server.GetQueueInfo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /authorize                --&amp;gt; github.com/drone/drone/server.HandleAuth &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /authorize                --&amp;gt; github.com/drone/drone/server.HandleAuth &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /authorize/token          --&amp;gt; github.com/drone/drone/server.GetLoginToken &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/builds               --&amp;gt; github.com/drone/drone/server.GetBuildQueue &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/         --&amp;gt; github.com/drone/drone/server/debug.IndexHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/heap     --&amp;gt; github.com/drone/drone/server/debug.HeapHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/goroutine --&amp;gt; github.com/drone/drone/server/debug.GoroutineHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/block    --&amp;gt; github.com/drone/drone/server/debug.BlockHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/threadcreate --&amp;gt; github.com/drone/drone/server/debug.ThreadCreateHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/cmdline  --&amp;gt; github.com/drone/drone/server/debug.CmdlineHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/profile  --&amp;gt; github.com/drone/drone/server/debug.ProfileHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/symbol   --&amp;gt; github.com/drone/drone/server/debug.SymbolHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; POST   /api/debug/pprof/symbol   --&amp;gt; github.com/drone/drone/server/debug.SymbolHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /api/debug/pprof/trace    --&amp;gt; github.com/drone/drone/server/debug.TraceHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /metrics                  --&amp;gt; github.com/drone/drone/server/metrics.PromHandler.func1 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /version                  --&amp;gt; github.com/drone/drone/server.Version &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone-server_1  | &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;GIN-debug&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; GET    /healthz                  --&amp;gt; github.com/drone/drone/server.Health &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt; handlers&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first part indicates which container is the log coming from (most of them during startup are from drone-server; during builds they&amp;rsquo;re mostly on the agent side), what system is it coming from (&lt;a href=&#34;https://github.com/gin-gonic/gin&#34;&gt;GIN&lt;/a&gt; is an HTTP framework for Golang) and various details. All seems fine, so let&amp;rsquo;s do our first pipeline!&lt;/p&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34;&gt;
&lt;i class=&#34;inline-svg&#34; &gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 576 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z&#34;/&gt;&lt;/svg&gt;&lt;/i&gt; I&#39;d highly recommend you setup an SSL cert ([Drone docs about that](http://docs.drone.io/configure-ssl/), or even [Let&#39;s Encrypt](http://docs.drone.io/configure-lets-encrypt/) which is also supported by Drone)
&lt;/div&gt;
&lt;h3 id=&#34;creating-your-first-pipeline-with-drone&#34;&gt;Creating your first pipeline with Drone&lt;/h3&gt;
&lt;p&gt;Connect to Drone&amp;rsquo;s web UI, which is available at DRONE_HOST. Once there, it will automatically log you in / demand that you log in with your version control sytem (Drone doesn&amp;rsquo;t handle authentification, it delegates that part to the VCS). After that, you can enable DroneCI on the projects you want it, add a .drone.yml file, commit it to master and off we go!&lt;/p&gt;
&lt;p&gt;A .drone.yml file is just a bunch of YAML which defines our pipeline and its stages (which can be based on regular Docker containers with the commands parameter or special Drone plugins (which are special Docker containers)), with conditions (only run stage X on master/tag; if the pipeline succeeds/fails notify via Slack, etc. etc.)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;pipeline&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;hugo&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;plugins/drone-hugo:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;validate&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;
*plugins* points to the [DockerHub organisation](https://hub.docker.com/r/plugins/) for drone-plugins
&lt;/div&gt;
&lt;p&gt;This defines a pipeline with a single stage, called &amp;ldquo;hugo&amp;rdquo;, which uses the plugins/drone-hugo:latest image from DockerHub (if you specify the full URL it can be a custom Docker Registry), with the validate:true option (it will check the configuration files for errors). You can read the full documentation of the &lt;a href=&#34;http://plugins.drone.io/drone-plugins/drone-hugo/&#34;&gt;Drone Hugo Plugin&lt;/a&gt;, but that&amp;rsquo;s the base, with optional parameters like theme, buildDrafts, etc.&lt;/p&gt;
&lt;p&gt;So now all that is left is to add the .drone.yml file to your repo and push it to GitHub/equivalent.&lt;/p&gt;
&lt;p&gt;Commit and push, and now the pipeline should run successfully:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+ hugo check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Contains some verification checks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+ hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   | EN  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+------------------+----+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Pages            | &lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Paginator pages  |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Non-page files   |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Static files     | &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Processed images |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Aliases          |  &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Sitemaps         |  &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Cleaned          |  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Total in &lt;span style=&#34;color:#ae81ff&#34;&gt;312&lt;/span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that you have the static files generated, the next step is having them deployed to Firebase Hosting.&lt;/p&gt;
&lt;h3 id=&#34;adding-a-deploy-to-firebase-step-in-our-pipeline&#34;&gt;Adding a deploy to Firebase step in our pipeline&lt;/h3&gt;
&lt;p&gt;First you need to deal with authentification. Firebase supports token authentification (instead of with your regular Google Account), and for that you need to run the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;firebase login:ci&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Which will open a browser window, and guide you through connecting to your Google Account and giving the appropriate rights to the token, and in the end print out the token.&lt;/p&gt;
&lt;p&gt;As you know, every time you commit credentials to Git, little kittens die. Luckily Drone &lt;a href=&#34;http://docs.drone.io/manage-secrets/&#34;&gt;can easily manage secrets&lt;/a&gt; with the Drone CLI (which you need tp &lt;a href=&#34;http://docs.drone.io/cli-installation/&#34;&gt;install&lt;/a&gt; and &lt;a href=&#34;http://docs.drone.io/cli-authentication/&#34;&gt;login into&lt;/a&gt; first).
To add a new secret to the Drone store, use the &lt;em&gt;drone secret add&lt;/em&gt; command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drone secret add &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -repository sofixa/blog &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -image sofixa/drone-firebase &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -name token &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;  -value &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FIREBASE_TOKEN&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This would add a secret available to the sofixa/blog repository, only on stages running with the sofixa/drone-firebase image, with the name token and value of $FIREBASE_TOKEN(which you should replace with the token you got from firebase login:ci).&lt;/p&gt;
&lt;p&gt;To add a second stage which deploys to Firebase using the &lt;em&gt;token&lt;/em&gt; secret you&amp;rsquo;ve just added, modify the .drone.yaml :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;pipeline&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;hugo&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;plugins/hugo:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;validate&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;firebase&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;sofixa/drone-firebase&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;project_id&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;blog-314450&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;message&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Autodeploy of commit $$COMMIT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;targets&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;hosting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# this will extrapolate the token secret as a parameter with its value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;secrets&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;source&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;target&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;plugin_token&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now commit and push to your Git Repository, and Drone should pick up an extra step (firebase) and deploy your Hugo generated static files to Firebase hosting with a similar output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Now using project blog-314450
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;===&lt;/span&gt; Deploying to &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;blog-314450&amp;#39;&lt;/span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  deploying hosting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: beginning deploy...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: found &lt;span style=&#34;color:#ae81ff&#34;&gt;47&lt;/span&gt; files in public
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting: adding files to version &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0/47&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0%&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: file upload complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: finalizing version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: version finalized
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;i  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: releasing new version...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  hosting&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;blog-314450&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;: release complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✔  Deploy complete!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Project Console: https://console.firebase.google.com/project/blog-314450/overview
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hosting URL: https://blog-314450.firebaseapp.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that&amp;rsquo;s it! You know have a static website with Hugo on Firebase Hosting, delivered automatically every time you commit in your repository.&lt;/p&gt;
&lt;p&gt;Possible improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;spellcheck stage&lt;/li&gt;
&lt;li&gt;scheduled runs to pick up planned articles with a future publish date&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;

        
        </description>
    </item>
    
    <item>
      <title>Hello, world!</title>
      <link>/2018/04/21/hello-world/</link>
      <pubDate>Sat, 21 Apr 2018 02:50:28 +0200</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/2018/04/21/hello-world/</guid>
      <description>
        
          
          
          
        
        
        
        
        </description>
    </item>
    
    <item>
      <title></title>
      <link>/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/about/</guid>
      <description>
        
          
          
          
        
        
        &lt;p style=&#34;text-align:center;&#34;&gt; 
&amp;nbsp; &lt;a href=&#39;/index.xml&#39; target=&#34;_blank&#34; rel=&#34;noopener&#34; title=&#39;Rss&#39;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;30&#34; height=&#34;30&#34; viewBox=&#34;0 0 20 20&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;feather feather-rss&#34;&gt;&lt;path d=&#34;M4 11a9 9 0 0 1 9 9&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M4 4a16 16 0 0 1 16 16&#34;&gt;&lt;/path&gt;&lt;circle cx=&#34;5&#34; cy=&#34;19&#34; r=&#34;1&#34;&gt;&lt;/circle&gt;&lt;/svg&gt;&lt;/a&gt; &amp;nbsp;

&amp;nbsp; &lt;a href=&#39;https://www.linkedin.com/in/adrianttodorov&#39; target=&#34;_blank&#34; rel=&#34;noopener&#34; title=&#39;Linkedin&#39;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;30&#34; height=&#34;30&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;&lt;path d=&#34;M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z&#34;&gt;&lt;/path&gt;&lt;rect x=&#34;2&#34; y=&#34;9&#34; width=&#34;4&#34; height=&#34;12&#34;&gt;&lt;/rect&gt;&lt;circle cx=&#34;4&#34; cy=&#34;4&#34; r=&#34;2&#34;&gt;&lt;/circle&gt;&lt;/svg&gt;&lt;/a&gt; &amp;nbsp;

&amp;nbsp; &lt;a href=&#39;https://github.com/sofixa&#39; target=&#34;_blank&#34; rel=&#34;noopener&#34; title=&#39;Github&#39;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;30&#34; height=&#34;30&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;&lt;path d=&#34;M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22&#34;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt; &amp;nbsp;

&amp;nbsp; &lt;a href=&#39;https://gitlab.com/sofixa&#39; target=&#34;_blank&#34; rel=&#34;noopener&#34; title=&#39;Gitlab&#39;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;30&#34; height=&#34;30&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;&lt;path d=&#34;M22.65 14.39L12 22.13 1.35 14.39a.84.84 0 0 1-.3-.94l1.22-3.78 2.44-7.51A.42.42 0 0 1 4.82 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.49h8.1l2.44-7.51A.42.42 0 0 1 18.6 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.51L23 13.45a.84.84 0 0 1-.35.94z&#34;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt; &amp;nbsp;

&amp;nbsp; &lt;a href=&#39;mailto:adrian.todorov@atodorov.ninja&#39; target=&#34;_blank&#34; rel=&#34;noopener&#34; title=&#39;Email&#39;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;30&#34; height=&#34;30&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;&lt;path d=&#34;M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z&#34;&gt;&lt;/path&gt;&lt;polyline points=&#34;22,6 12,13 2,6&#34;&gt;&lt;/polyline&gt;&lt;/svg&gt;&lt;/a&gt; &amp;nbsp;

&lt;/p&gt;
&lt;p&gt;Hi, my name is Adrian Todorov and this is my personal blog.&lt;/p&gt;
&lt;p&gt;Currently I&amp;rsquo;m a Staff Solutions Architect at HashiCorp, giving advice on Nomad, Vault, Consul, and everything they interact with.&lt;/p&gt;
&lt;p&gt;I started my career in tech as a web developer, and afterwards I moved to Site Reliability Engineering, focusing more on various types of infrastructure, their automation and monitoring. I spent a few years running vSphere, Kubernetes and Nomad in production, as well as covering the role of a virtualisation and storage admin, and an AWS architect; developing internal tooling, and automating all the things I had to do more than once with extensive use of Terraform (including homemade Terraform providers), Ansible, Python and Golang.&lt;/p&gt;
&lt;p&gt;Proud alumni of the first class of the original &lt;a href=&#34;https://42.fr/&#34;&gt;Ecole 42&lt;/a&gt;, which taught me a lot about programming, debugging, and the importance of community.&lt;/p&gt;
&lt;p&gt;At home I like exploring technology I can&amp;rsquo;t use at work, so I have some home automation (with Home Assistant), and my personal infrastructure is managed with Terraform, Ansible and GitHub on top of a local lab running Nomad, combined with CloudFlare, GCP and Scaleway (managed Kubernetes). Everything is monitored with Grafana Cloud (Prometheus, Loki, Grafana).&lt;/p&gt;
&lt;p&gt;Tech I&amp;rsquo;m interested in and have running somewhere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The HashiStack, obviously (Nomad, Consul, Vault, Terraform)&lt;/li&gt;
&lt;li&gt;Orchestrators in general, mostly Nomad and Kubernetes&lt;/li&gt;
&lt;li&gt;Observability (Prometheus, Grafana, Loki, Jaeger, InfluxDB once upon a time, OpenTelemetry, DataDog, NewRelic, etc.)&lt;/li&gt;
&lt;li&gt;Automating all the things&lt;/li&gt;
&lt;li&gt;Python, Golang, Bash&lt;/li&gt;
&lt;li&gt;Home automation with Home Assistant, with tons of Zigbee devices, some ESP32s, and a few Raspberry Pis scattered around&lt;/li&gt;
&lt;li&gt;Networking, specifically with VyOS and Ubiquiti gear, with some cheap multi-gig Zyxel switches&lt;/li&gt;
&lt;/ul&gt;

        
        </description>
    </item>
    
    <item>
      <title></title>
      <link>/1/01/01/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>adrian.todorov@atodorov.ninja (Adrian Todorov)</author>
      <guid>/1/01/01/</guid>
      <description>
        
          
          
          
        
        
        &lt;h1 id=&#34;tracee&#34;&gt;Tracee&lt;/h1&gt;
&lt;h1 id=&#34;debugging-scratch-containers&#34;&gt;Debugging Scratch containers&lt;/h1&gt;

        
        </description>
    </item>
    
  </channel>
</rss>