Skip to content
Learn APIs with Kevin

Automating Kubernetes Deployments with Postman


5 min read

Kubernetes is the most widely used container-based orchestration platform today. Practitioners are often segmented by specialty:

  • Application Developer
  • Administrator
  • Security Specialist

According to the currently in-progress Kubernetes Usage Report 2021, one relevant discovery is that Kubernetes deployments do not live in isolation. Most organizations are running a combination of bare metal, VMs, and Kubernetes.

Due to the persistent need to manage heterogeneous infrastructure, Kubernetes specialists are often tasked with other job responsibilities. How do we wrangle the dissonance in application deployments, administration, security, and orchestration? The reality is that we're saddled with the necessity of integration.

APIs all the way down

Today, the communication and interaction possibilities are endless:

  • B2B partner services
  • Data migration
  • Legacy system reuse

APIs are not just glue code. They enable value chain optimizations through platform ecosystems. (blah blah blah) APIs are the raw materials we piece together to make this magic happen. This is what's driving so much adoption of quirky mashup delights. It's not just shiny object obsession, though if we're honest with ourselves, our little raccoon paws have a wandering mind of their own. 🦝

Here's what we're going to accomplish:

  1. Get a Kubernetes cluster up and running
  2. Build a server to fetch local Kubernetes resource files
  3. Run a proxy to the Kubernetes API Server
  4. Use Postman to deploy our application

Get ready!

Pulling the strings of Kubernetes

Okay, okay, okay... Let's get to it. Here's our inventory:

Here's what we're looking to accomplish:

A diagram showing Postman fetching resources from a local kube-resource-server and submitting them to Kubernetes via the proxy server.
Overview

Kubernetes is an API-driven container orchestration platform. Most people are familiar with using the kubectl CLI to send commands to their cluster. Fun fact: kubectl is just using APIs under the hood. Don't believe me? Tack -v=8 to the tail end of any kubectl command, and let the HTTP wash over us. 🌊

Now that we know we can make API calls to pull the strings of Kubernetes, let's see what we can do in Postman. Here's a public workspace to follow along!

An image showing a collection in Postman that contains requests to deploy to Kubernetes.
Kubernetes Deployment collection in Postman

Let's step through what's going on here.

0. Pre-requisites

First and foremost, we'll need a Kubernetes cluster. Cloud providers offer managed options that are relatively quick and easy to get up and running. For this walkthrough, we'll be using Amazon Elastic Kubernetes Service (Amazon EKS). One of the easiest ways to get an Amazon EKS cluster up and running is to use the Amazon EKS Quickstart CloudFormation template.

Once our cluster is up and running, we'll need to create an SSH tunnel to our bastion host. Using default security options with the Amazon EKS Quickstart template, only the bastion host has access to kube-apiserver. This prevents outside access to our precious Pods. However, we'd like to use kubectl on our own workstations so we can test our integrations. Scott Lowe has an easy-to-follow blog post on how to do this: Using kubectl via an SSH Tunnel.

Before we get started with local testing, there are a couple of servers we need to run. If the Postman collection is going to deploy Kubernetes resources, it needs a way to access those resources. Furthermore, we need a way of accessing the Kubernetes API. These will require setup for both local testing and testing in our CI/CD pipeline.

Proxying kube-apiserver

In Kubernetes, kube-apiserver validates and configures data for the cluster. It's exposed via a REST API and is the front door by which we'll enter. The kubectl CLI has a built-in way to run a local proxy, and we'll utilize the default URL http://localhost:8001 for our local testing. When we run our Postman collection in our CI/CD workflow, we'll be accessing the API from a Pod where we'll use a different URL, https://kubernetes.default.svc. Don't worry. These URLs can be set as variables in Postman and changed depending on our execution environment.

Local kube-resource-server

We're going to run a local server in our CI/CD pipeline that's going to conveniently serve the Kubernetes resources over HTTP! One benefit of this is that we can actually use this server when testing our collection run in Postman. Here's a quick implementation in Node.js. After initializing a new Node.js application, be sure to install a couple of dependencies.

After we have our new Node.js application and our dependencies, let's write a basic HTTP server that will aggregate Kubernetes resource YAML files and return them as JSON. Our Postman collection will use these JSON representations to deploy to Kubernetes.

Now let's start this server before we begin testing.

Remember the URL for the kube-resource-server (default: http://localhost:3001). We'll need it later. This one stays the same whether running locally or in our CI/CD workflow.

While we're at it, let's run that Kubernetes proxy, too.

Next, we'll walk through each part of the Postman collection. Then we'll work on actually running it!

1. Initialize

This step is only necessary when running in the Postman Collection Runner. With Postman, we want to enable both a real-time developer experience and a way to automate collection runs via the command line. To do that, we'll use Newman. For now, let's see if we can make some API calls!

An image showing a collection in Postman that contains requests to deploy to Kubernetes with the Initialize folder highlighted.
Kubernetes Deployment collection - Initialize

This step resets all collection variables that are required for the collection run. When running in Newman, we'll skip this step by only running the Run folder from this collection.

2. Fetch resources from the filesystem

Finally, we get to use our nifty little Node.js server! If it isn't already running from the instructions earlier, go ahead and fire it up now.

An image showing a collection in Postman that contains requests to deploy to Kubernetes with the Request to fetch local Kubernetes resources highlighted.
Kubernetes Deployment collection - Fetch Application Resources

In order for this to be successful, we need to add a couple of Kubernetes YAML files to our ci/kubernetes directory.

The deployment...

And the service...

3. Deploy using the Kubernetes API

Once we've got everything in place, we're ready to hit the Kubernetes API and deploy our application! The Kubernetes API can be fairly complex at times. Luckily, we already have these requests ready in Postman, and we can re-use them across all of our projects.

An image showing a collection in Postman that contains requests to deploy to Kubernetes with the deployment requests highlighted.
Kubernetes Deployment collection - Deploy to Kubernetes

Apps, roll out

Now that we have an understanding of the collection workflow, let's take a look at the variables that make this all work.

Variables

Required to access the Kubernetes server and the resource server that will run in the CI/CD pipeline.

  • kubeBaseUrl - The URL for Kubernetes. If you're testing locally, you should have kube proxy running, and the URL should be http://localhost:8001. If you're running this collection in Kubernetes, the URL should be https://kubernetes.default.svc.
  • kubeNamespace - The default namespace to create/update resources. If the resource has a metadata.namespace field, that takes precedence.
  • resourceBaseUrl - The URL to the service that will run in your CI/CD environment. It can return resources that can be deployed (e.g., deployment and service YAML files stored in your code repository).
  • fieldManager - Kubernetes server-side apply requires field management.
  • forceUpdates - Only needed if resources were previously created/updated by something other than Postman, such as kubectl. More information here: Server-Side Apply.

These can all be overridden in an environment. Here's a snapshot for a local configuration.

Local variables in an environment used to run the Kubernetes Deployment collection.
Local variables used to run the Kubernetes Deployment collection

The big reveal

And finally, cue the drum roll... 🥁

When we run the collection, not only do we see all the API calls being made, we also see test execution happening for each call. The test results we see are verifying the success of our application deployment.

A successful collection run of the Kubernetes Deployment Postman collection.
A successful Collection Run

Now, if everything worked correctly, the service should be accessible via the proxy at http://localhost:8001/api/v1/namespaces/default/services/jsonplaceholder-svc/proxy/posts/.

A JSON output for an example service running in Kubernetes.
Our brand new service running in Kubernetes

We did it! Finally, we have API testing for our integrated deployment environment.

To put a bow on all this, we can actually automate Postman collection runs in our CI/CD pipelines using an open source CLI called Newman. All we need to do is integrate our Git repository with an API version in Postman.

Here's an example of running this same collection from within a Pod in our Kubernetes cluster! There's a lot more to this, but that's a whole 'nother post.

Going beyond

This just scratches the surface of what's possible with API-driven deployments. Here are some ideas for upgrading our workflow:

  • Canary deployments with manual job approval.
  • More complex orchestration with databases and message brokers.
  • Environment promotion with Slack notifications and the CircleCI API.

API-driven automation allows us to use existing tools and infrastructure, leveraging the investments we've already made. This isn't shiny object syndrome. It's perseverance.

Still, it probably wouldn't hurt to just try the next shiny thing... 'Til next time! ✨


Disclaimer: This post mentions Postman. I work there. 🚀

Photograph of Kevin Swiber at sunset with colorful hair.
Hi. My name's Kevin Swiber. I have worked with API-focused startups for the past decade. I teach and learn about software development, distributed systems, leadership, mental health, and developer tools. Reach out to me @kevinswiber if you want to chat more about the topic of this post or anything else in my area of interests!
© 2022 Kevin Swiber. All rights reserved.
Theme by LekoArts