
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://endoze.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://endoze.github.io/" rel="alternate" type="text/html" /><updated>2023-10-16T19:33:37+00:00</updated><id>https://endoze.github.io/feed.xml</id><title type="html">endoze</title><subtitle>Random stuff I've learned and decided to share :)</subtitle><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;https://avatars.githubusercontent.com/u/997161?v=4&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer by day. &lt;br /&gt;Hacker by night.&quot;, &quot;location&quot;=&gt;&quot;The Internet&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/endoze&quot;}]}</name></author><entry><title type="html">Containerizing an App for Kubernetes</title><link href="https://endoze.github.io/2023/10/16/containerizing-an-app-for-kubernetes.html" rel="alternate" type="text/html" title="Containerizing an App for Kubernetes" /><published>2023-10-16T17:21:03+00:00</published><updated>2023-10-16T17:21:03+00:00</updated><id>https://endoze.github.io/2023/10/16/containerizing-an-app-for-kubernetes</id><content type="html" xml:base="https://endoze.github.io/2023/10/16/containerizing-an-app-for-kubernetes.html">&lt;p&gt;Getting started with Kubernetes can be daunting. If you’re setting up your first
cluster, you’ve got your work cut out for you. The choices of log gathering,
metrics collectors, ingress controllers, and even cloud hosts can make the work
to containerize your apps seem less important. But once you get down to it,
containerizing your applications for operation within your cluster is just as
important.&lt;/p&gt;

&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;

&lt;p&gt;You will need to install the &lt;a href=&quot;https://github.com/docker/cli&quot;&gt;docker cli client&lt;/a&gt;,
&lt;a href=&quot;https://github.com/abiosoft/colima&quot;&gt;a container runtime&lt;/a&gt;, and
&lt;a href=&quot;https://github.com/kubernetes/kubectl&quot;&gt;kubectl&lt;/a&gt;. We can use Colima as our
container runtime, however it’s not mandatory to do so. You can subsitute any
other container runtime supported by your machine. It also helps that Colima can
run Kubernetes for us without a lot of setup.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;docker colima kubectl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you do choose to use Colima, you can edit the configuration and start it in
one command as follows:&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;colima start &lt;span class=&quot;nt&quot;&gt;-k&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Open settings in $EDITOR before launch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;first-steps&quot;&gt;First Steps&lt;/h2&gt;

&lt;p&gt;Let’s start with containerizing a simple application to see what it takes.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;app.ru&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bundler/inline&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set up our dependencies on rack and puma&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Rack is a web server interface&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Puma is a rack compliant web server&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gemfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://rubygems.org&quot;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;rack&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;2.2.4&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;puma&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5.6.5&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# We don't have to define a class in order for this app to&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# work with rack. We could have just defined a proc that &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# accepts 1 argument and returns the same array of data.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'200'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Content-Type'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'text/html'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Run our application via puma&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With our app code in hand, we’ll also need a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; to build a container
image to run our app.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;Dockerfile&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-Dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# define our base image to base this one off of&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; ruby:3.1.2-alpine3.16&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# install some dependencies we'll need for our container at runtime&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;apk &lt;span class=&quot;nt&quot;&gt;--update&lt;/span&gt; add &lt;span class=&quot;nt&quot;&gt;--no-cache&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    build-base &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    gem &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;rack:2.2.4 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    gem &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;puma:5.6.5

&lt;span class=&quot;c&quot;&gt;# copy our app.ru file into the filesystem of our image&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; app.ru app.ru&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Mark that we will expose a service on this port&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;EXPOSE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 9292&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# run our application via rackup&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; rackup app.ru&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we need to turn this code into a container image we can use in later steps.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; rack-app &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We need to store our image somewhere that our Kubernetes cluster can pull from.
If you are using a Kubernetes cluster within colima, when we built our docker
image it became available within the cluster as well. If you aren’t using
colima, you’ll need to push the image to somewhere public like Docker Hub. You
can push to Docker Hub with a command like the following (after authenticating
with them).&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker login &lt;span class=&quot;c&quot;&gt;# authenticate with Docker Hub&lt;/span&gt;
docker tag rack-app:latest &amp;lt;docker-hub-username&amp;gt;/rack-app:latest
docker push &amp;lt;docker-hub-username&amp;gt;/rack-app:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So now we have a very simple rack app and a Dockerfile to build a container
image for it. What now? We’ll need some Kubernetes manifest files to describe
the resources we want to create when deploying our app. At the very least we’ll
need deployment and service manifests.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;deploy.yml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apps/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Deployment&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app:latest&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# image repository and tag&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;IfNotPresent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll need to ensure the image repository/tag combination is accessible to your
Kubernetes cluster. If you uploaded your image to Docker Hub, you’ll need to
change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; file to reference the repository and tag you used with
Docker Hub (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;some-username&amp;gt;/rack-app:&amp;lt;some-tag&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;service.yml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# service.yml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Service&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;LoadBalancer&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;targetPort&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;TCP&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s apply these manifests to our Kubernetes cluster with the following
commands:&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; deploy.yml
kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; service.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s check to see if our app is running in our kubernetes cluster using the
following command:&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;it-lives&quot;&gt;It Lives?&lt;/h2&gt;

&lt;p&gt;Now that our app is deployed to our Kubernetes cluster, let’s send a request to
see it working. But first we’ll need to get some information to send that
request.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We should get a list of all the running pods (containers) in the default
namespace. Look for one with a name similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rack-app-78bc8fc8cf-9v7g7&lt;/code&gt;. The
last part of the name is random and unique per pod per deployment of our app.
Now that we have the the name of our running pod, we’ll run the following to
forward a local port into our cluster directly to our pod.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl port-forward &amp;lt;replace-me-with-pod-identifier&amp;gt; 9292:9292
curl https://localhost:9292
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We should get back “Hello World” from our test rack application. Seems like a
success!&lt;/p&gt;

&lt;h2 id=&quot;how-does-kubernetes-know-its-alive&quot;&gt;How does Kubernetes know it’s alive?&lt;/h2&gt;

&lt;p&gt;So now we’ve got to wonder, how does Kubernetes know our pod is running? How
does it know if our pod can accept requests or is even responding correctly to
requests after accepting them?&lt;/p&gt;

&lt;p&gt;The first question is easy enough to answer. Kubernetes knows our pod is running
because the single process we started inside the container &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rackup app.ru&lt;/code&gt; is
still running. If that process were to die, Kubernetes would notice and recreate
our pod for us. This is because we specified in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; file that we
wanted 1 pod running at all times.&lt;/p&gt;

&lt;p&gt;The second and third question is a bit trickier. If our pod’s singular process
were to continue running but wasn’t actually accepting requests Kubernetes
wouldn’t be able to determine that currently. And if it were accepting requests
but wasn’t responding correctly with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;200&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;Hello World&quot;&lt;/code&gt; it also
couldn’t determine that.&lt;/p&gt;

&lt;p&gt;So how do we explain to Kubernetes that our pod is alive and well? What we can
do is add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;liveness&lt;/code&gt; probe to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt;. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;liveness&lt;/code&gt; probe tells
Kubernetes that our pod is running correctly and responding as we’d expect. If
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;liveness&lt;/code&gt; probe fails enough over a short period of time, Kubernetes will
terminate the failing pod and replace it with a new one.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;yaml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;livenessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;periodSeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the case of accepting requests, we can use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readiness&lt;/code&gt; probe for our pod.
This can let us know if the pod is currently accepting requests. This may seem
similar to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;liveness&lt;/code&gt; probe but there is one key difference between the two.
When a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;liveness&lt;/code&gt; probe fails enough, our pod is terminated and replaced. When a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readiness&lt;/code&gt; probe fails enough, Kubernetes will stop sending traffic to the pod
but it will continue running. It could be our pod is connecting to a database
during normal operation and this connection fails. If that happens, we can no
longer accept connections from the outside. Our app can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readiness&lt;/code&gt;
probe to signal to Kubernetes that we currently cannot accept connections.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;yaml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;readinessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s update our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; to include both of these probes:&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;deploy.yml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apps/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Deployment&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app:latest&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;IfNotPresent&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;readinessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;livenessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;periodSeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;deploys&quot;&gt;Deploys&lt;/h2&gt;

&lt;p&gt;Now that we’ve got our app containerized and running in Kubernetes, what about
deploying code updates? We should definitely automate the deployment of our app
so that any code changes can be propogated to our Kubernetes cluster. Looking at
what we have so far, most of our deploy relies on two key pieces. Our image
being stored in a docker registry and our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; Kubernetes manifest.
Let’s create a script to build and push our app’s container image first.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env zsh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# bail out of script if any commands error&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; 

&lt;span class=&quot;c&quot;&gt;# set some variables up for reuse&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;COMMITISH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;git rev-parse HEAD | CUT &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; 1-8&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;BRANCH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;git rev-parse &lt;span class=&quot;nt&quot;&gt;--abbrev-ref&lt;/span&gt; HEAD&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rack-app&quot;&lt;/span&gt;

docker build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BRANCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# on our master branch we tag a deploy version with the COMMITISH&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# in the name&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BRANCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;on master branch&quot;&lt;/span&gt;
  docker tag &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BRANCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:deploy-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$COMMITISH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;docker push &lt;span class=&quot;nt&quot;&gt;--all-tags&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our build script makes a few assumptions about our project. It assumes we are
using git for version control of the project, our default branch is named
master, and we are using a locally accessible registry for Kubernetes. If you
are using a registry like Docker Hub, you’ll need to change the project name to
accomodate for this.&lt;/p&gt;

&lt;p&gt;Next we’ll need a script to deploy our app to Kubernetes.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env zsh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# bail out of script if any commands error&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# set some variables up for reuse&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;COMMITISH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;git rev-parse HEAD | &lt;span class=&quot;nb&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; 1-8&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMMITISH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$COMMITISH&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# apply our Kubernetes manifests&lt;/span&gt;
kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; service.yml
envsubst &amp;lt;deploy.yml | kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last part of our deploy script seems a bit strange so let’s dive into what’s
really happening here. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;envsubst&lt;/code&gt; is a command line tool to substitue
environment variables in shell format strings. Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt;, we are sending the
contents of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; manifest to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;envsubst&lt;/code&gt; command. This replaces
any mention of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$SOME_VAR&lt;/code&gt; with the current environment variable’s value in our
manifest. We can use this to have a static &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; but change which tag of
our container we deploy. We’ll need to modify our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy.yml&lt;/code&gt; to account for
this now.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;deploy.yml&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apps/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Deployment&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rack-app:deploy-$COMMITISH&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# important bit here&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;IfNotPresent&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;readinessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;livenessProbe&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9292&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;periodSeconds&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With both of our scripts at hand, we can now automate our deployment to our
cluster. Since we aren’t running any sort of CI/CD platform locally, you can
instead run the scripts locally after making changes and commiting them to git.
But if you were running this in a more ‘production’ environment, these scripts
could be part of your Continuous Deployment pipeline.&lt;/p&gt;

&lt;div class=&quot;window&quot;&gt;
  &lt;div class=&quot;titlebar&quot;&gt;
    &lt;div class=&quot;buttons&quot;&gt;
      &lt;div class=&quot;close&quot;&gt;
        &lt;a class=&quot;closebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;x&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;minimize&quot;&gt;
        &lt;a class=&quot;minimizebutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;&amp;ndash;&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class=&quot;zoom&quot;&gt;
        &lt;a class=&quot;zoombutton&quot; href=&quot;#&quot;&gt;
          &lt;span&gt;
            &lt;strong&gt;+&lt;/strong&gt;
          &lt;/span&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;zsh&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-zsh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bin/docker-build-image
bin/deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h1&gt;

&lt;p&gt;At this point, we’ve taken our simple rack based app and enabled deploying it to
Kubernetes along with creating a few scripts to help automate the entire
process. If you’d like to download the entire project, you can grab a copy from
GitHub
&lt;a href=&quot;https://github.com/endoze/example-containerization-for-kubernetes&quot;&gt;here&lt;/a&gt;. Next
time we will cover a couple of different applications with different
requirements for operation in a Kubernetes cluster.&lt;/p&gt;</content><author><name>{&quot;name&quot;=&gt;nil, &quot;avatar&quot;=&gt;&quot;https://avatars.githubusercontent.com/u/997161?v=4&quot;, &quot;bio&quot;=&gt;&quot;Software Engineer by day. &lt;br /&gt;Hacker by night.&quot;, &quot;location&quot;=&gt;&quot;The Internet&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;GitHub&quot;, &quot;icon&quot;=&gt;&quot;fab fa-fw fa-github&quot;, &quot;url&quot;=&gt;&quot;https://github.com/endoze&quot;}]}</name></author><category term="Kubernetes" /><category term="ruby" /><category term="docker" /><summary type="html">Getting started with Kubernetes can be daunting. If you’re setting up your first cluster, you’ve got your work cut out for you. The choices of log gathering, metrics collectors, ingress controllers, and even cloud hosts can make the work to containerize your apps seem less important. But once you get down to it, containerizing your applications for operation within your cluster is just as important.</summary></entry></feed>