<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Viktor Gamov</title>
    <description>The latest articles on Forem by Viktor Gamov (@gamussa).</description>
    <link>https://forem.com/gamussa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F14702%2F619aae29-bc19-47be-9084-8c46fc7db094.jpg</url>
      <title>Forem: Viktor Gamov</title>
      <link>https://forem.com/gamussa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gamussa"/>
    <language>en</language>
    <item>
      <title>Installing Kong's API Gateway with Docker</title>
      <dc:creator>Viktor Gamov</dc:creator>
      <pubDate>Fri, 10 Sep 2021 19:57:32 +0000</pubDate>
      <link>https://forem.com/kong/installing-kong-s-api-gateway-with-docker-56gg</link>
      <guid>https://forem.com/kong/installing-kong-s-api-gateway-with-docker-56gg</guid>
      <description>&lt;p&gt;&lt;a href="https://konghq.com/kong"&gt;Kong Gateway&lt;/a&gt; is an API layer for managing APIs and microservices. The easiest way to get started running Kong Gateway is to use Docker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/sJEID1xEZMg"&gt;In this video&lt;/a&gt;, I'll explain how to run Kong Gateway using Docker and Docker Compose.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/sJEID1xEZMg&amp;lt;br&amp;gt;%0A"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cY0Il_5U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pk7203v19has9r4yk0z.jpg" alt="Installing Kong's API Gateway with Docker"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Kubernetes Ingress Controller as an API Gateway</title>
      <dc:creator>Viktor Gamov</dc:creator>
      <pubDate>Tue, 23 Mar 2021 14:18:22 +0000</pubDate>
      <link>https://forem.com/kong/using-kubernetes-ingress-controller-as-an-api-gateway-1lmh</link>
      <guid>https://forem.com/kong/using-kubernetes-ingress-controller-as-an-api-gateway-1lmh</guid>
      <description>&lt;p&gt;&lt;em&gt;In this first section, I’ll provide a quick overview of the business case and the tools you can use to create a Kubernetes ingress API gateway. If you’re already familiar, you could skip ahead to the tutorial section.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Digital transformation has led to a high velocity of data moving through APIs to applications and devices. Companies with legacy infrastructures are experiencing inconsistencies, failures and increased costs. And most importantly, dissatisfied customers.&lt;/p&gt;

&lt;p&gt;All this has led to significant restructuring and modernization, especially within IT. A primary strategy is to embrace Kubernetes and decouple monolithic systems. On top of that, IT leadership is tasking DevOps teams to find systems, like an &lt;a href="https://konghq.com/learning-center/api-gateway/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community" rel="noopener noreferrer"&gt;API gateway&lt;/a&gt; or Kubernetes ingress controller, to support API traffic growth while minimizing costs.&lt;/p&gt;

&lt;p&gt;API gateways are crucial components of &lt;a href="https://konghq.com/learning-center/microservices/microservices-architectures/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community" rel="noopener noreferrer"&gt;microservice architectures&lt;/a&gt;. The API gateway acts as a single entry point into a distributed system, providing a unified interface for clients who don’t need to care (or know) that the system aggregates their API call response from multiple microservices.&lt;/p&gt;

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

&lt;p&gt;Some everyday use cases for API gateways include:&lt;/p&gt;

&lt;p&gt;• Routing inbound requests to the appropriate microservice&lt;br&gt;
• Presenting a unified interface to a distributed architecture by aggregating responses from multiple backend services&lt;br&gt;
• Transforming microservice responses into the format required by the caller&lt;br&gt;
• Implementing non-functional/policy concerns such as authentication, logging, monitoring and observability, rate-limiting, IP filtering, and attack mitigation&lt;br&gt;
• Facilitating deployment strategies such as blue/green or canary releases&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API gateways can simplify the development and maintenance of a microservice architecture. As a result, freeing up development teams to focus on the business logic of individual components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like &lt;a href="https://konghq.com/case-study/papa-johns-accelerates-time-to-market-with-kong?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community" rel="noopener noreferrer"&gt;Papa John’s&lt;/a&gt;, many companies select a Kubernetes API gateway at the beginning or partway through their transition to multi-cloud. Doing so makes it necessary to choose a solution that can function with on-prem services and the cloud.&lt;/p&gt;
&lt;h2&gt;
  
  
  Kubernetes
&lt;/h2&gt;

&lt;p&gt;Kubernetes is becoming the hosting platform of choice for distributed architectures. It offers auto-scaling, fault tolerance and zero-downtime deployments out of the box.&lt;/p&gt;

&lt;p&gt;By providing a widely accepted, standard approach with a carefully designed API, Kubernetes has spawned a thriving ecosystem of products and tools that make it much easier to deploy and maintain complex systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Kubernetes Ingress Controller
&lt;/h2&gt;

&lt;p&gt;As a native Kubernetes application, Kong is installed and managed precisely as any other Kubernetes resource. It integrates well with other CNCF projects and automatically updates itself with zero downtime in response to cluster events like pod deployments. There’s also a great &lt;a href="https://konghq.com/products/kong-gateway/kong-plugins/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community" rel="noopener noreferrer"&gt;plugin ecosystem&lt;/a&gt; and native gRPC support.&lt;/p&gt;

&lt;p&gt;This article will walk through how easy it is to set up the open source &lt;a href="https://github.com/Kong/kubernetes-ingress-controller#kong-for-kubernetes" rel="noopener noreferrer"&gt;Kong Ingress Controller&lt;/a&gt; as a Kubernetes API gateway on a cluster.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use Case: Routing API Calls to Backend Services
&lt;/h2&gt;

&lt;p&gt;To keep this article to a manageable size, I will only cover a single, straightforward use case.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0zr2fvjy9a9vsil3u2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0zr2fvjy9a9vsil3u2n.png" alt="Kong foo/bar routing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will create a Kubernetes cluster, deploy two dummy microservices, “foo” and “bar,” install and configure Kong to route inbound calls to &lt;code&gt;/foo&lt;/code&gt; to the foo microservice and send calls to &lt;code&gt;/bar&lt;/code&gt; to the bar microservice.&lt;/p&gt;

&lt;p&gt;The information in this post barely scratches the surface of what you can do with Kong, but it’s a good starting point.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;There are a few things you’ll need to work through in this article.&lt;/p&gt;

&lt;p&gt;I’m going to create a “real” Kubernetes cluster on DigitalOcean because it’s quick and easy, and I like to keep things as close to real-world scenarios as possible. If you want to work locally, you can use minikube or KinD. You will need to fake a load-balancer, though, either using the minikube tunnel or setting up a port forward to the API gateway.&lt;/p&gt;

&lt;p&gt;For DigitalOcean, you will need:&lt;/p&gt;

&lt;p&gt;• A DigitalOcean account&lt;br&gt;
• A DigitalOcean API token with read and write scopes&lt;br&gt;
• The doctl command-line tool&lt;/p&gt;

&lt;p&gt;To build and push docker images representing our microservices, you will need:&lt;/p&gt;

&lt;p&gt;• Docker&lt;br&gt;
• An account on Docker Hub&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Optional because you can deploy the images I’ve already created.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You will also need kubectl to access the Kubernetes cluster.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up doctl
&lt;/h2&gt;

&lt;p&gt;After installing &lt;code&gt;doctl&lt;/code&gt;, you’ll need to authenticate using the DigitalOcean API token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;doctl&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;Enter&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;access&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="nx"&gt;paste&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;prompted&lt;/span&gt;
&lt;span class="nx"&gt;Validating&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Kubernetes Cluster
&lt;/h2&gt;

&lt;p&gt;Now that you have authenticated &lt;code&gt;doctl&lt;/code&gt;, you can create your Kubernetes cluster with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;doctl&lt;/span&gt; &lt;span class="nx"&gt;kubernetes&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;mycluster&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;vcpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;gb&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: The command spins up a Kubernetes cluster on DigitalOcean. Doing so will incur charges (approximately $0.01/hour, at the time of writing) as long as it is running. Please remember to destroy any resources you create when you finish with them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The command creates a cluster with a single worker node of the smallest viable size in the New York data center. It’s the smallest and simplest cluster (and also the cheapest to run). You can explore other options by running &lt;code&gt;doctl kubernetes --help&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The command will take several minutes to complete, and you should see an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;doctl&lt;/span&gt; &lt;span class="nx"&gt;kubernetes&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;mycluster&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;vcpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;gb&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;Notice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cluster&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;provisioning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waiting&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;running&lt;/span&gt;
&lt;span class="p"&gt;....................................................&lt;/span&gt;
&lt;span class="nx"&gt;Notice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cluster&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetching&lt;/span&gt; &lt;span class="nx"&gt;credentials&lt;/span&gt;
&lt;span class="nx"&gt;Notice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Adding&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="nx"&gt;credentials&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;kubeconfig&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/Users/david/.kube/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;Notice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Setting&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;nyc1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mycluster&lt;/span&gt;
&lt;span class="nx"&gt;ID&lt;/span&gt;                                      &lt;span class="nx"&gt;Name&lt;/span&gt;         &lt;span class="nx"&gt;Region&lt;/span&gt;    &lt;span class="nx"&gt;Version&lt;/span&gt;        &lt;span class="nx"&gt;Auto&lt;/span&gt; &lt;span class="nx"&gt;Upgrade&lt;/span&gt;    &lt;span class="nx"&gt;Status&lt;/span&gt;     &lt;span class="nx"&gt;Node&lt;/span&gt; &lt;span class="nx"&gt;Pools&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nx"&gt;cf2159a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="nx"&gt;c1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;423&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;907&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="nx"&gt;f19c3f9a01&lt;/span&gt;    &lt;span class="nx"&gt;mycluster&lt;/span&gt;    &lt;span class="nx"&gt;nyc1&lt;/span&gt;      &lt;span class="mf"&gt;1.20&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="kc"&gt;false&lt;/span&gt;           &lt;span class="nx"&gt;running&lt;/span&gt;    &lt;span class="nx"&gt;mycluster&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the command automatically adds cluster credentials and a context to the &lt;code&gt;~/.kube/config file&lt;/code&gt;, so you should be able to access your cluster using kubectl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;namespace&lt;/span&gt;
&lt;span class="nx"&gt;NAME&lt;/span&gt;              &lt;span class="nx"&gt;STATUS&lt;/span&gt;   &lt;span class="nx"&gt;AGE&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt;           &lt;span class="nx"&gt;Active&lt;/span&gt;   &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;
&lt;span class="nx"&gt;kube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lease&lt;/span&gt;   &lt;span class="nx"&gt;Active&lt;/span&gt;   &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;
&lt;span class="nx"&gt;kube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kr"&gt;public&lt;/span&gt;       &lt;span class="nx"&gt;Active&lt;/span&gt;   &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;
&lt;span class="nx"&gt;kube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;       &lt;span class="nx"&gt;Active&lt;/span&gt;   &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Dummy Microservices
&lt;/h2&gt;

&lt;p&gt;To represent backend microservices, I’m going to use a trivial Python Flask application that returns a JSON string:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;foo.py&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;flask&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Flask&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"msg":"Hello from the foo microservice"}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;__main__&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Dockerfile builds a docker image you can deploy:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dockerfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;FROM&lt;/span&gt; &lt;span class="nx"&gt;python&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;alpine&lt;/span&gt;

&lt;span class="nx"&gt;WORKDIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;

&lt;span class="nx"&gt;RUN&lt;/span&gt; &lt;span class="nx"&gt;echo&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Flask==1.1.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt&lt;/span&gt;
&lt;span class="nx"&gt;RUN&lt;/span&gt; &lt;span class="nx"&gt;pip&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="nx"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt&lt;/span&gt;
&lt;span class="nx"&gt;COPY&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;py&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;EXPOSE&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;

&lt;span class="nx"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;python&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo.py&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The files for our “foo” and “bar” services are almost identical, so I’m only going to show the “foo” files here. &lt;/p&gt;

&lt;p&gt;This gist contains files and a script to build &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; microservices docker images and push them to Docker Hub as:&lt;/p&gt;

&lt;p&gt;• digitalronin/foo-microservice:0.1&lt;br&gt;
• digitalronin/bar-microservice:0.1&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: You don’t have to build and push these images. You can just use the ones I’ve already created.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploy Dummy Microservices
&lt;/h2&gt;

&lt;p&gt;You’ll need a manifest that defines a Deployment and a Service for each microservice, both for “foo” and “bar.” The manifest for “foo” (again, I’m only showing the “foo” example here, since the “bar” file is nearly identical) would look like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;foo.yaml&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;
&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Deployment&lt;/span&gt;
&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;deployment&lt;/span&gt;
&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;
  &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;
    &lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;digitalronin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;microservice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;
        &lt;span class="nx"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="nx"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v1&lt;/span&gt;
&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Service&lt;/span&gt;
&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;
  &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;
&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;
    &lt;span class="nx"&gt;targetPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
  &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gist has manifests for both microservices, which you can download and deploy to your cluster like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Access the Services
&lt;/h2&gt;

&lt;p&gt;You can check that the microservices are running correctly using a port forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;forward&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in a different terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:5000/foo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from the foo microservice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ditto for &lt;code&gt;bar&lt;/code&gt;, also using port 5000.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Kong for Kubernetes
&lt;/h2&gt;

&lt;p&gt;Now that you have our two microservices running in our Kubernetes cluster, let’s install Kong.&lt;/p&gt;

&lt;p&gt;There are several options for this, which you will find in the documentation. I’m going to apply the manifest directly, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//bit.ly/k4k8s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last few lines of output should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;
&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;webhook&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;
&lt;span class="nx"&gt;deployment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: You may receive several API deprecation warnings at this point, which you can ignore. Kong’s choice of API versions allows Kong Ingress Controller to support the broadest range of Kubernetes versions possible.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Installing Kong will create a DigitalOcean load balancer. It’s the internet-facing endpoint to which you will make API calls to access our microservices.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: DigitalOcean load balancers incur charges, so please remember to delete your load balancer along with your cluster when you are finished.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Creating the load balancer will take a minute or two. You can monitor its progress like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt;
&lt;span class="nx"&gt;NAME&lt;/span&gt;                      &lt;span class="nx"&gt;TYPE&lt;/span&gt;           &lt;span class="nx"&gt;CLUSTER&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;      &lt;span class="nx"&gt;EXTERNAL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;   &lt;span class="nc"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="nx"&gt;AGE&lt;/span&gt;
&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt;                &lt;span class="nx"&gt;LoadBalancer&lt;/span&gt;   &lt;span class="mf"&gt;10.245&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;14.22&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;     &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32073&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30537&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;TCP&lt;/span&gt;   &lt;span class="mi"&gt;71&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the system creates the load balancer, the &lt;code&gt;EXTERNAL-IP&lt;/code&gt; value will change from &lt;code&gt;&amp;lt;pending&amp;gt;&lt;/code&gt; to a real IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt;
&lt;span class="nx"&gt;NAME&lt;/span&gt;                      &lt;span class="nx"&gt;TYPE&lt;/span&gt;           &lt;span class="nx"&gt;CLUSTER&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;      &lt;span class="nx"&gt;EXTERNAL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;     &lt;span class="nc"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="nx"&gt;AGE&lt;/span&gt;
&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt;                &lt;span class="nx"&gt;LoadBalancer&lt;/span&gt;   &lt;span class="mf"&gt;10.245&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;14.22&lt;/span&gt;    &lt;span class="mf"&gt;167.172&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;7.192&lt;/span&gt;   &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32073&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30537&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;TCP&lt;/span&gt;   &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;m45s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For convenience, let’s export that IP number as an environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;PROXY_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;167.172&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;7.192&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;---&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;own&lt;/span&gt; &lt;span class="nx"&gt;EXTERNAL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can check that Kong is working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="nx"&gt;$PROXY_IP&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no Route matched with those values&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: It’s the correct response because you haven’t yet told Kong what to do with any API calls it receives.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Kong Gateway
&lt;/h2&gt;

&lt;p&gt;You can use Ingress resources like this to configure Kong to route API calls to the microservices:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;foo-ingress.yaml&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;networking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;k8s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;
&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ingress&lt;/span&gt;
&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;
  &lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;

&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;ingressClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;
  &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;
        &lt;span class="nx"&gt;pathType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Prefix&lt;/span&gt;
        &lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;
            &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
              &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gist defines ingresses for both microservices. Download and apply them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, Kong will route calls to &lt;code&gt;/foo&lt;/code&gt; to the foo microservice and &lt;code&gt;/bar&lt;/code&gt; to bar.&lt;/p&gt;

&lt;p&gt;You can check this using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="nx"&gt;$PROXY_IP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from the foo microservice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="nx"&gt;$PROXY_IP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from the bar microservice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Else Can You Do?
&lt;/h2&gt;

&lt;p&gt;In this article, I have:&lt;/p&gt;

&lt;p&gt;• Deployed a Kubernetes cluster on DigitalOcean&lt;br&gt;
• Created Docker images for two dummy microservices, “foo” and “bar”&lt;br&gt;
• Deployed the microservices to the Kubernetes cluster&lt;br&gt;
• Installed the Kong Ingress Controller&lt;br&gt;
• Configured Kong to route API calls to the appropriate backend microservice&lt;/p&gt;

&lt;p&gt;I’ve demonstrated one simple use of Kong, but it’s only a starting point. With Kong for Kubernetes, here are several examples of other things you can do:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By adding an authentication plugin to Kong, you can require your API callers to provide a valid JSON Web Token (JWT) and check each call against an Access Control List (ACL) to ensure callers are entitled to perform the relevant operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certificate management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can enable integration with cert-manager to provision and auto-renew SSL certificates for your API endpoints so that all your API traffic is encrypted as it travels over the public internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;gRPC support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kong natively supports gRPC, so it’s easy to add gRPC support to your API.&lt;/p&gt;

&lt;p&gt;You can do a lot more with Kong, and I’d encourage you to look at the documentation and start to explore some of the other features.&lt;/p&gt;

&lt;p&gt;The API gateway is a crucial part of a microservices architecture, and the Kong Ingress Controller is well suited for this role in a Kubernetes cluster. You can manage it in the same way as any other Kubernetes resource.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;Don’t forget to destroy your Kubernetes cluster when you are finished with it so that you don’t incur unnecessary charges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//bit.ly/k4k8s  # &amp;lt;-- this will destroy the load-balancer&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;doctl&lt;/span&gt; &lt;span class="nx"&gt;kubernetes&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;mycluster&lt;/span&gt;
&lt;span class="nx"&gt;Warning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Are&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;sure&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;Kubernetes&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="nx"&gt;Notice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cluster&lt;/span&gt; &lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removing&lt;/span&gt; &lt;span class="nx"&gt;credentials&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: If you delete the cluster first, the load balancer will be left behind. You can delete any leftover resources via the DigitalOcean web interface.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for walking through this tutorial with us. It was originally published on our blog: &lt;a href="https://bit.ly/316W3zw" rel="noopener noreferrer"&gt;https://bit.ly/316W3zw&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🎥 Using Protobuf with Kafka Streams</title>
      <dc:creator>Viktor Gamov</dc:creator>
      <pubDate>Fri, 19 Jun 2020 16:04:06 +0000</pubDate>
      <link>https://forem.com/gamussa/video-using-protobuf-with-kafka-streams-204l</link>
      <guid>https://forem.com/gamussa/video-using-protobuf-with-kafka-streams-204l</guid>
      <description>&lt;p&gt;In case you missed (you should subscribe &lt;a href="https://gamov.dev/youtube"&gt;https://gamov.dev/youtube&lt;/a&gt; so you won't miss it in future) #LiveStreams episode this week I posted the recording with updated timecodes. &lt;/p&gt;

&lt;p&gt;In this video, you will get an idea of how to use #protobuf with Kafka Streams(+ tests with TopologyTestDriver).&lt;/p&gt;

&lt;p&gt;Also, I'm showing a new &lt;code&gt;kafka-protobuf-console-consumer&lt;/code&gt; command-line tool that ships with Confluent Platform 5.5.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=YN1fdymEH14"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o6Dj1Hxj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://img.youtube.com/vi/YN1fdymEH14/0.jpg" alt="Protobuf with Kafka Streams"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafkastreams</category>
      <category>protobuf</category>
      <category>apachekafka</category>
      <category>streamprocessing</category>
    </item>
    <item>
      <title>5 Kubernetes Tools You Probably Don’t Use (But You Should)</title>
      <dc:creator>Viktor Gamov</dc:creator>
      <pubDate>Mon, 30 Mar 2020 05:06:08 +0000</pubDate>
      <link>https://forem.com/gamussa/5-kubernetes-tools-you-probably-don-t-use-but-you-should-20c5</link>
      <guid>https://forem.com/gamussa/5-kubernetes-tools-you-probably-don-t-use-but-you-should-20c5</guid>
      <description>&lt;p&gt;Table of Contents&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put your prompt to work&lt;/li&gt;
&lt;li&gt;Cluster context and namespaces switching on your fingertips&lt;/li&gt;
&lt;li&gt;Monitoring cluster health and Kubernetes Resources Right From Your Terminal&lt;/li&gt;
&lt;li&gt;Web UI to remote Kubernetes without installation!&lt;/li&gt;
&lt;li&gt;Checking what the &lt;em&gt;Helm&lt;/em&gt; is happening&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--09prL4S0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/k9s_ksql.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--09prL4S0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/k9s_ksql.jpg" alt="k9s ksql"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;br&gt;
In this post, I’m going to talk about few tools that I found very useful during my Kubernetes development and presentations. |&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HgyoBrFsJdg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Earlier this year, I recorded a three-episode series, &lt;a href="https://youtu.be/JiDiC5MI7hw"&gt;«Streaming on Kubernetes:&lt;/a&gt; &lt;a href="https://youtu.be/9HaKP6HBz3s"&gt;It doesn’t have&lt;/a&gt; &lt;a href="https://youtu.be/lzFuEuqOSNM"&gt;to be the hard way.»&lt;/a&gt;There I showed some demos of the Confluent Operator on Kubernetes. Many people reached out after and asked - «What kind of terminal do you use,» «What kind of plugins do you use» and so far and so on. And today, I’m going to be talking about five Kubernetes tools that I use in my demos (of during preparations to it) that you’re probably don’t use but defiantly should.&lt;/p&gt;

&lt;p&gt;So, let’s get to it - it’s going to be fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  Put your prompt to work
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;kube-ps1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github:&lt;/strong&gt; &lt;a href="https://github.com/jonmosco/kube-ps1"&gt;https://github.com/jonmosco/kube-ps1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OK, I do demos.Many demos.OK, not like a lot of demos but still, a large number of demos.And things that I’m usually demoing very technical.So technical some things I demo don’t even have GUI.The only thing that I have to interact with those things is the command line interface, aka terminal.&lt;/p&gt;

&lt;p&gt;As the theatre starts with a coat, a proper terminal starts with a prompt.Because during those technical demos, there are many things going in on the screen.&lt;/p&gt;

&lt;p&gt;So, having an excellent terminal prompt that will allow the audience and yours truly always to know where we are?That’s why I appreciate &lt;code&gt;kube-ps1&lt;/code&gt; that displays information about the current Kubernetes cluster context as part of a terminal prompt.Also, it adds two a helper commands &lt;code&gt;kubeon&lt;/code&gt; and &lt;code&gt;kubeoff&lt;/code&gt; that allow for turning this prompt on and off on demand.&lt;/p&gt;

&lt;p&gt;| | It does work great in &lt;code&gt;bash&lt;/code&gt; and &lt;code&gt;zsh&lt;/code&gt;. |&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RcxevyYC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/kubeon.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RcxevyYC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/kubeon.jpg" alt="kubeon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 1. Current Kubernetes cluster in your command line&lt;/p&gt;

&lt;h2&gt;
  
  
  Cluster context and namespaces switching on your fingertips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;kubectx&lt;/code&gt; and &lt;code&gt;kubens&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Github:&lt;/strong&gt; &lt;a href="https://github.com/ahmetb/kubectx"&gt;https://github.com/ahmetb/kubectx&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, I do create and use many Kubernetes clusters on a daily basis.Some days I may create a few Kubernetes clustersSaying this, I need to switch between those quite often.It may need to type a few commands if you don’t know what full name of a cluster (and I can be a quire long)See yourself!&lt;/p&gt;

&lt;p&gt;kubectx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl config get-contexts (1)
kubectl config current-context (2)
kubectl config use-context &amp;lt;NAME OF CONTEXT&amp;gt; (3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;| &lt;strong&gt;1&lt;/strong&gt; | Get list of all Kubernetes clusters configured in your system |&lt;br&gt;
| &lt;strong&gt;2&lt;/strong&gt; | Get a current cluster context |&lt;br&gt;
| &lt;strong&gt;3&lt;/strong&gt; | Set desired cluster context |&lt;/p&gt;

&lt;p&gt;Not so useful, right?Yet, there is a better way!&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;kubectx.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mAypF5o0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/ahmetb/kubectx/raw/master/img/kubectx-demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mAypF5o0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/ahmetb/kubectx/raw/master/img/kubectx-demo.gif" alt="kubectx demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectx&lt;/code&gt; allows switching between Kubernetes clusters few quickly.It also integrates with command pager utility, and allows you to have some text menu where you can choose a specific cluster!&lt;/p&gt;

&lt;p&gt;As a bonus, there is another tool that comes from the same author called &lt;code&gt;kubens&lt;/code&gt; that I allow to switch namespaces withing the same cluster context.Same with namespace switching - not rocket science, but you need to remember or google those commands all the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring cluster health and Kubernetes Resources Right From Your Terminal
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;k9s&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github:&lt;/strong&gt; &lt;a href="https://github.com/derailed/k9s"&gt;https://github.com/derailed/k9s&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OK, good, now you learned to switch between Kubernetes clusters and namespaces in those clusters.The next tool can be a bit useful because it provides a GUI (terminal UI) tool that allows you to interact with your Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;You can see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Standard Kubernetes resources and well as custom resources and &lt;code&gt;KafkaCluster&lt;/code&gt; or &lt;code&gt;PhysicalStatefulCluster&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can drill down to pods and see logs from the individual containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You watch health and vitals of your Kubernetes cluster and your applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--09prL4S0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/k9s_ksql.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--09prL4S0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/k9s_ksql.jpg" alt="k9s ksql"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, this tool has many customization hooks!&lt;/p&gt;

&lt;h2&gt;
  
  
  Web UI to remote Kubernetes without installation!
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;octant&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github:&lt;/strong&gt; &lt;a href="https://github.com/vmware-tanzu/octant"&gt;https://github.com/vmware-tanzu/octant&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have you ever used &lt;a href="https://github.com/kubernetes/dashboard"&gt;Kubernetes Dashboard&lt;/a&gt;?Yes, you have because it’s a standard monitoring dashboard for Kubernetes.But there is one slight problem - it requires installation on your cluster.If you don’t have enough rights, or your operations folks don’t want to have extra crap installed in your Kubernetes cluster, this may be a challenge to get you GUI.&lt;/p&gt;

&lt;p&gt;Enter Octant. It’s a web-based Kubernetes resource visualizer.&lt;/p&gt;

&lt;p&gt;And it doesn’t require installation on your Kubernetes cluster.Octant runs locally on your machine and talks to Kubernetes via standard API calls.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qL-fP3GX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qL-fP3GX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant.jpg" alt="octant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 2. Killer feature is a resource dependency graph&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gOe3Fx5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_crds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gOe3Fx5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_crds.png" alt="octant crds"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 3. Apart from understanding standard Kubernetes resource, &lt;code&gt;octant&lt;/code&gt; shows some custom resources&lt;/p&gt;

&lt;p&gt;Another very cool feature of octant is «Port Forwarding».It works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Navigate to the resource, e.g. &lt;code&gt;controlcenter&lt;/code&gt; &lt;code&gt;StatefulSet&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll to the container that want to forward ports from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And you can click «Start Port Forward».&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Octant UI will display localhost and port to the pod.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kplnCIB_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kplnCIB_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_c3.png" alt="octant c3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 4. Octant port-forwarding Control Center on localhost&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ks8lY0iU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_port.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ks8lY0iU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/octant_port.png" alt="octant port"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 5. You can get a list of all port forwards&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking what the &lt;em&gt;Helm&lt;/em&gt; is happening
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; Helm Cabin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Github:&lt;/strong&gt; &lt;a href="https://github.com/Nick-Triller/helm-cabin"&gt;https://github.com/Nick-Triller/helm-cabin&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our last small nifty tool for today is Helm Cabin - your dashboard for helm releases.image::helm-cabin.jpg[]&lt;/p&gt;

&lt;p&gt;You will be able to see all your helm releases deployed to given Kubernetes cluster.Once you click on one of the release names, we drill down to some helm release info - NOTES from chart, templates and values, and «effective» chart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0CtSZpV_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/cabin_chart_details.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0CtSZpV_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://gamov.io/images/cabin_chart_details.png" alt="cabin chart details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 6. Chart details&lt;/p&gt;

&lt;p&gt;In my opinion, this is pretty useful tool for housekeeping and audit purposes.&lt;/p&gt;

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

&lt;p&gt;If you have found this video useful or entertaining, hit that like button and consider subscribing to this channel.Stay tuned for the next one.And as always, have a nice day!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>tools</category>
      <category>devops</category>
    </item>
    <item>
      <title>Tips And Tricks That I use in my demos and presentation with Docker</title>
      <dc:creator>Viktor Gamov</dc:creator>
      <pubDate>Wed, 28 Nov 2018 18:00:00 +0000</pubDate>
      <link>https://forem.com/gamussa/tips-and-tricks-that-i-use-in-my-demos-and-presentation-with-docker-omo</link>
      <guid>https://forem.com/gamussa/tips-and-tricks-that-i-use-in-my-demos-and-presentation-with-docker-omo</guid>
      <description>&lt;p&gt;Table of Contents&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete every Docker containers&lt;/li&gt;
&lt;li&gt;
Open shell in running container

&lt;ul&gt;
&lt;li&gt;Extra carriculum matterial: How to do the same in case of Docker Compose?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fgamov.io%2Fimages%2Fme_presenting.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fgamov.io%2Fimages%2Fme_presenting.jpg" alt="me presenting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 1. A very small tip for you!&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;p&gt;The sole purpose of this post is to help me to return here time to time if I forget some of the commands.If this would be useful for anyone - praise me on twitter - &lt;a href="http://twitter.com/gamussa" rel="noopener noreferrer"&gt;http://twitter.com/gamussa&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Let’s start with a small but important thing - how to erase everything Docker and start clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delete every Docker containers
&lt;/h2&gt;

&lt;p&gt;|NOTE:| Don’t do this if you’re on the plane. Downloading new images using the airline’s wifi will be the pain. Proceed with caution. You have been warned. |&lt;/p&gt;

&lt;p&gt;How many time you have found yourself running out of space in your laptop, and you don’t know who’s eating all the space.Usual suspects here are maven or gradle directory jar’s directory and Docker images directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; ~/.m2
2.4G /Users/viktor/.m2 &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;

❯ &lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; ~/.gradle
2.8G /Users/viktor/.gradle &lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;

❯ &lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.raw
8.1G /Users/viktor/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.raw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;| &lt;strong&gt;1&lt;/strong&gt; | Should I nuke it? |&lt;br&gt;
| &lt;strong&gt;2&lt;/strong&gt; | I definitely use Gradle more |&lt;/p&gt;

&lt;p&gt;Must be run first because images are attached to containers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;docker ps &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete every Docker image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker rmi &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;docker images &lt;span class="nt"&gt;-q&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Open shell in running container
&lt;/h2&gt;

&lt;p&gt;If I have a container that already running I can use &lt;code&gt;docker exec&lt;/code&gt; command to connect to it!&lt;/p&gt;

&lt;p&gt;First, get the name of the existing container using &lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;docker exec -it &amp;lt;container name&amp;gt; /bin/bash&lt;/code&gt; to get a bash shell in the container&lt;/p&gt;

&lt;p&gt;Essentially, use &lt;code&gt;docker exec -it &amp;lt;container name&amp;gt; &amp;lt;command&amp;gt;&lt;/code&gt; to execute whatever command you specify in the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra curriculum material: How to do the same in case of Docker Compose?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run &amp;lt;container_name_in_yml_file&amp;gt; &amp;lt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E.g. to get a shell into your Kafka container, you might run &lt;code&gt;docker-compose run kafka1 /bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To run a series of commands, you must wrap them in a single command using a shell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run &amp;lt;name &lt;span class="k"&gt;in &lt;/span&gt;yml&amp;gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;command 1&amp;gt; &amp;amp;&amp;amp; &amp;lt;command 2&amp;gt; &amp;amp;&amp;amp; &amp;lt;command 3&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;docker run&lt;/code&gt; command accepts command-line options to specify volume mounts, environment variables, the working directory, and more.&lt;/p&gt;

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