<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Nimbus</title><link>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/</link><description>Recent content in Posts on Nimbus</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 15 Mar 2023 11:00:00 -0700</lastBuildDate><atom:link href="https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Building an Observability Stack with Prometheus and Grafana</title><link>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-3/</link><pubDate>Wed, 15 Mar 2023 11:00:00 -0700</pubDate><guid>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-3/</guid><description>&lt;p&gt;Most teams don&amp;rsquo;t have a metrics problem — they have a &lt;em&gt;too many
dashboards nobody looks at&lt;/em&gt; problem. This is the minimal setup we use to
go from &amp;ldquo;no visibility&amp;rdquo; to &amp;ldquo;useful alerts and three dashboards people
actually open during an incident.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;







&lt;span class="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-medium bg-sky-50 text-sky-700 dark:bg-sky-900/30 dark:text-sky-300"&gt;Prometheus v2.51&lt;/span&gt;

 
 
 
 
 
 
 
 
 &lt;a href="https://grafana.com" target="_blank" rel="noopener" class="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-medium bg-purple-50 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300 hover:opacity-80 transition-opacity"&gt;Grafana v10.4&lt;/a&gt;
 
&lt;/p&gt;
&lt;p&gt;&lt;img src="bryce-canyon.jpg" alt="Bryce Canyon National Park"&gt;&lt;/p&gt;</description></item><item><title>Terraform State Management: Lessons from Production</title><link>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-2/</link><pubDate>Wed, 15 Feb 2023 10:00:00 -0700</pubDate><guid>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-2/</guid><description>&lt;p&gt;Local Terraform state works fine for a weekend project. It falls apart the
moment a second engineer runs &lt;code&gt;terraform apply&lt;/code&gt; against the same
infrastructure. Here&amp;rsquo;s the setup we settled on after a state file conflict
took down a staging environment for an afternoon.&lt;/p&gt;







&lt;div class="alert alert-warning"&gt;
 &lt;div class="flex items-start"&gt;
 &lt;div class="flex-shrink-0"&gt;
 &lt;svg class="h-5 w-5 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 15.5c-.77.833.192 2.5 1.732 2.5z" /&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="ml-3 flex-1"&gt;
 
 &lt;h4 class="text-sm font-semibold mb-1"&gt;State files contain secrets&lt;/h4&gt;
 
 &lt;div class="text-sm"&gt;
 Terraform state can include plaintext values for anything marked &lt;code&gt;sensitive&lt;/code&gt;
in your provider — database passwords, API keys, TLS private keys. Treat
your state backend&amp;rsquo;s access controls with the same care as a secrets
manager, not like a build artifact.
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="move-to-a-remote-backend"&gt;Move to a remote backend&lt;/h2&gt;
&lt;p&gt;A local &lt;code&gt;terraform.tfstate&lt;/code&gt; file has no locking and no history. The fix is
a remote backend with state locking built in:&lt;/p&gt;</description></item><item><title>Deploying with Kubernetes: A Practical Guide</title><link>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-1/</link><pubDate>Sun, 15 Jan 2023 09:00:00 -0700</pubDate><guid>https://k-s-pavan-kumar.github.io/hugo-nimbus/blog/post-1/</guid><description>&lt;p&gt;Getting a service running reliably on Kubernetes comes down to a handful of
building blocks: a container image, a Deployment, and a Service to expose it.
This walkthrough covers the essentials.&lt;/p&gt;







&lt;div class="alert alert-info"&gt;
 &lt;div class="flex items-start"&gt;
 &lt;div class="flex-shrink-0"&gt;
 &lt;svg class="h-5 w-5 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="ml-3 flex-1"&gt;
 
 &lt;h4 class="text-sm font-semibold mb-1"&gt;Before you start&lt;/h4&gt;
 
 &lt;div class="text-sm"&gt;
 You&amp;rsquo;ll need &lt;code&gt;kubectl&lt;/code&gt; configured against a cluster (Minikube, kind, or a
managed cluster all work fine for this walkthrough).
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="1-build-and-tag-the-image"&gt;1. Build and tag the image&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker build -t registry.example.com/api:1.4.0 .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker push registry.example.com/api:1.4.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="2-define-the-deployment"&gt;2. Define the Deployment&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;registry.example.com/api:1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;httpGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/healthz&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="3-roll-it-out"&gt;3. Roll it out&lt;/h2&gt;





&lt;div class="terminal-container bg-gray-900 rounded-lg overflow-hidden shadow-lg my-6"&gt;
 
 &lt;div class="terminal-header bg-gray-800 px-4 py-2 flex items-center space-x-2"&gt;
 &lt;div class="flex space-x-2"&gt;
 &lt;div class="w-3 h-3 bg-red-500 rounded-full"&gt;&lt;/div&gt;
 &lt;div class="w-3 h-3 bg-yellow-500 rounded-full"&gt;&lt;/div&gt;
 &lt;div class="w-3 h-3 bg-green-500 rounded-full"&gt;&lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="flex-1 text-center"&gt;
 &lt;span class="text-gray-400 text-sm font-mono"&gt;bash&lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 
 
 &lt;div class="terminal-content p-4 font-mono text-sm"&gt;
 &lt;div class="terminal-prompt text-green-400 mb-2"&gt;
 &lt;span class="text-blue-400"&gt;dev@k8s-master&lt;/span&gt;:&lt;span class="text-purple-400"&gt;~/api&lt;/span&gt;$ 
 &lt;/div&gt;
 &lt;div class="terminal-output text-gray-100"&gt;
 kubectl apply -f deployment.yaml
deployment.apps/api created
kubectl rollout status deployment/api
deployment &amp;ldquo;api&amp;rdquo; successfully rolled out
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;







&lt;div class="alert alert-warning"&gt;
 &lt;div class="flex items-start"&gt;
 &lt;div class="flex-shrink-0"&gt;
 &lt;svg class="h-5 w-5 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 15.5c-.77.833.192 2.5 1.732 2.5z" /&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="ml-3 flex-1"&gt;
 
 &lt;h4 class="text-sm font-semibold mb-1"&gt;Watch your readiness probes&lt;/h4&gt;
 
 &lt;div class="text-sm"&gt;
 A missing or too-strict readiness probe is the most common cause of a rollout
that &amp;ldquo;succeeds&amp;rdquo; but serves traffic to pods that aren&amp;rsquo;t actually ready.
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;

&lt;div class="my-6 rounded-lg border border-gray-200 dark:border-neutral-800 bg-white dark:bg-neutral-900 overflow-x-auto"&gt;
 
 &lt;div class="px-4 py-2 border-b border-gray-200 dark:border-neutral-800 text-sm font-medium text-gray-700 dark:text-gray-300"&gt;
 Request flow
 &lt;/div&gt;
 
 &lt;div class="mermaid p-4"&gt;

graph LR
 A[Client] --&gt; B[Ingress]
 B --&gt; C[Service]
 C --&gt; D[Pod 1]
 C --&gt; E[Pod 2]
 C --&gt; F[Pod 3]

 &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s the core loop: build, define, apply, verify. From here you&amp;rsquo;d typically
add a HorizontalPodAutoscaler and wire this into CI so every merge to &lt;code&gt;main&lt;/code&gt;
triggers a new rollout automatically.&lt;/p&gt;</description></item></channel></rss>