Kubernetes Tutorial: Your Complete Guide to Deploying an App on AWS with Postman
Tags: aws, kubernetes, postman, tutorial
Published: 2021-01-05 12:35:38

<img class="aligncenter wp-image-9522 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/kubernetes-postman.png" alt="Kubernetes tutorial: Using Postman to deploy an app on AWS" width="1418" height="358" />

<a href="https://kubernetes.io/">Kubernetes</a> is an open source system that is useful for container orchestration. In this tutorial, we are going to use <a href="https://www.postman.com/collection/">Postman Collections</a> to learn Kubernetes and use its API to deploy an app on a Kubernetes cluster hosted on <a href="https://aws.amazon.com/eks/?whats-new-cards.sort-by=item.additionalFields.postDateTime&amp;whats-new-cards.sort-order=desc&amp;eks-blogs.sort-by=item.additionalFields.createdDate&amp;eks-blogs.sort-order=desc">AWS</a>.

This is a hands-on tutorial. Don't fret if you aren’t familiar with Kubernetes and containerization, because we'll go over each of the following:
<ul>
 	<li>Prerequisites</li>
 	<li>Brief overview on containers</li>
 	<li>Kubernetes</li>
 	<li>Creating a Kubernetes cluster</li>
 	<li>Accessing the Kubernetes API from Postman</li>
 	<li>Authorizing Postman Collection</li>
 	<li>Deploy an app</li>
 	<li>Pod</li>
 	<li>Deployment</li>
 	<li>Expose your app</li>
 	<li>Service</li>
 	<li>Clean up</li>
 	<li>What next?</li>
</ul>
<b>Note: </b>We will be creating the Kubernetes cluster on AWS EKS, but you can also follow the tutorial with a cluster hosted on any other cloud providers or locally using Minikube.
<h2>Prerequisites</h2>
Familiarity with <a href="https://blog.postman.com/rest-api-definition/">REST APIs</a> is a prerequisite. In addition you also need to do the following:
<ul>
 	<li>Create an <a href="https://portal.aws.amazon.com/billing/signup?refid=em_127222&amp;redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start">AWS account</a></li>
 	<li><a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html">Install</a> and <a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html">configure</a> AWS ALI to configure credentials</li>
 	<li><a href="https://eksctl.io/introduction/#installation">Install eskctl</a>,a command utility to interact and create the cluster on EKS</li>
 	<li><a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/">Install kubectl</a>, a command-line utility to work with Kubernetes clusters</li>
 	<li>Clone Github <a href="https://github.com/meenakshi-dhanani/k8s-postman-tutorial">repository</a> containing .yaml files required in upcoming sections</li>
 	<li>Create your Amazon Cluster IAM role to access the cluster</li>
 	<li>Setting up Amazon EKS cluster VPC</li>
</ul>
Here is a  helpful  <a href="https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html">Amazon EKS guide</a> that has all of the prerequisites mentioned above and instructions to install them.

Explore this blog post in an interactive format by using our companion template. Just import the <a href="https://documenter.getpostman.com/view/13059338/TVmLCyNi"><b>Deploy with Amazon EKS and Kubernetes API</b></a> collection by clicking on <b>Run in Postman</b> to follow this tutorial.


[![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/b64f762a9c9375e6640b#?env%5BAWS%5D=W3sia2V5Ijoia3ViZS1hcGktc2VydmVyIiwidmFsdWUiOiI8QVBJIFNlcnZlciBFbmRwb2ludD4iLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImF1dGgtdG9rZW4iLCJ2YWx1ZSI6IjxCZWFyZXIgVG9rZW4+IiwiZW5hYmxlZCI6dHJ1ZX1d)


<img class="wp-image-9523 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image20.png" alt="Deploy with Amazon EKS and Kubernetes API Template " width="1798" height="1354" /> <a href="https://documenter.getpostman.com/view/13059338/TVmLCyNi">Deploy with Amazon EKS and Kubernetes API Template </a>
<h2>A brief overview of containers</h2>
Are you familiar with the “<i>But it works on my machine”</i> problem? A lot of times your application doesn’t perform as it does in your local environment. It may be because the production environment has different versions of the libraries, a different operating system, different system dependencies, etc. Containers provide you with a sustainable environment because your application now runs in a box (container) that includes all dependencies required by your app to run and is isolated from other applications running in other containers. They are preferred over virtual machines (VMs) since they use operating system-level virtualization and are lighter than VMs. <a href="https://www.docker.com/products/container-runtime">Docker</a> can be used as the container runtime.

<img class="wp-image-9524 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image5.png" alt="Benefits of containerization" width="1468" height="1016" /> Benefits of containerization
<h2>Enter Kubernetes</h2>
Each app/service now runs in a container, so there can be a separation of concerns. Services don’t need to be intertwined with each other, and a microservices architecture works best with containerization. We have established why the world is moving towards containers, but who is going to manage these containers and how do you roll out a release? How do you run health checks against your services and get them back up if they are failing? Kubernetes automates all of this for you. You can easily scale up and scale down your services with Kubernetes.

<img class="wp-image-9525 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image18.png" alt="Container orchestration in Kubernetes" width="1228" height="746" /> Container orchestration in Kubernetes

You can use Kubernetes anywhere for on-premise deployments or even hybrid clouds. For instance, you can have your cluster on GCE, AWS, Azure, or any cloud provider. For this Kubernetes tutorial, let's create a cluster on AWS.

Read more about the benefits of containerization and container orchestration with Kubernetes <a href="https://cloud.google.com/containers">here</a>. This is a really enthralling space, especially for folks interested in DevOps.
<h2>Creating a Kubernetes cluster</h2>
Assuming you have followed the steps in the prerequisites section, you should have eksctl installed. Follow the steps below to create a Kubernetes cluster.

1. Run the following command to check if eksctl can successfully access the AWS account and list any existing clusters:
<pre>eksctl get cluster --region us-east-1</pre>
In case this command fails, you may want to make sure your credentials are set up correctly, as mentioned <a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html">here</a>.

2. Next, create a cluster and assign some resources to it. The <a href="https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/cluster.yaml">cluster.yaml</a> is present in the Github project we cloned, as mentioned in the prerequisites. You can customize the configuration for the cluster based on the resources you want to assign to your cluster. You could choose a different region, maybe add more nodes, or also a different instance type. For this tutorial, we do not need as much CPU or memory.
```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata: 
  name: playground 
  region: us-east-1

nodeGroups: 
  - name: ng-1 
    instanceType: t2.small 
    desiredCapacity: 2
```
<b>A word of caution</b>: The pricing for larger instances and more number of nodes would be more.

Use the  following command to create the cluster:
<pre>eksctl create cluster -f cluster.yaml</pre>
It may take a while for the cluster to be ready. Once this command succeeds, assuming you have kubectl installed, the configuration for kubectl to access the cluster would be stored at:
<pre>~/.kube/config</pre>
3. Try fetching the nodes on the cluster using kubectl. You should be able to see the two nodes if you used the cluster configuration as mentioned above.
<pre>kubectl get nodes</pre>
<h2>Accessing the Kubernetes API from Postman</h2>
Next, we require a service account to communicate with the Kubernetes API. The service account is authorized to perform certain actions, including creating deployments and listing services by attaching it to a cluster role.

1. Run the following command to create a service account:
<pre>kubectl create serviceaccount postman</pre>
2. Create a role definition for the service account. This role definition specifies all actions that are permitted on the resources mentioned. The <a href="https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/role.yaml">role.yaml</a> is present in the GitHub project we cloned,  as mentioned in the prerequisites. We will look at what these resources mean and learn how to create them in the next steps.
```
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: postman-role
rules:
- apiGroups: ["apps", ""] # "" indicates the core API group
  resources: ["pods", "services", "deployments"]
  verbs: ["get", "watch", "list", "create", "update", "delete"]
```
Run the following command to create the role:
<pre>kubectl apply -f role.yaml</pre>
3. Assign the role to the service account by creating a role-binding:
<pre>kubectl create rolebinding postman:postman-role --clusterrole postman-role --serviceaccount default:postman</pre>
For every service account created, there is a secret token. Finally, we must extract the following from the token created for the service account:
<ul>
 	<li style="list-style-type: none;">
<ul>
 	<li style="list-style-type: none;">
<ul>
 	<li>API server URL</li>
 	<li>Bearer Token</li>
 	<li>CA Certificate</li>
</ul>
</li>
</ul>
</li>
</ul>
4. Run the following command to reveal the secret e.g., postman-token-9lxcc:
<pre>kubectl describe serviceaccount postman</pre>
5. Next, we must describe the secret:
<pre>kubectl get secret &lt;secret-token&gt; -o json</pre>
6. Execute the command below to reveal the ca.crt certificate and the token, that is inside a data object. We need to decode these to base64 and use them. This can be simplified using <a href="https://stedolan.github.io/jq/download/">jq</a> command-line utility:
<pre># Extract the token from the Secret and decode
TOKEN=$(kubectl get secret &lt;secret-token&gt; -o json | jq -Mr '.data.token' | base64 -d)</pre>
<pre># Extract, decode and write the ca.crt to a file
kubectl get secret &lt;secret-token&gt; -o json | jq -Mr '.data["ca.crt"]' | base64 -d &gt; ca.crt</pre>
7. You must get the API server URL from Amazon EKS. If you log in to your Amazon account and see the cluster details for the playground cluster we created, you should find an <b>API server endpoint</b>, which is the URL for the API server that we are going to be hitting via Postman.

<img class="wp-image-9526 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image14.png" alt="API server endpoint of Kubernetes cluster on Amazon EKS" width="1999" height="814" /> API server endpoint of Kubernetes cluster on Amazon EKS
<h2>Authorizing the Postman Collection</h2>
1. Assuming the collection is already imported as part of the prerequisites, select the <strong>Manage Environments</strong> button on the top right, and edit the following:

<img class="wp-image-9527 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image15.png" alt="Environment variables for AWS environment" width="1438" height="1106" /> Environment variables for AWS environment

2. Paste the API Server Endpoint into the <i>CURRENT VALUE</i> for kube-api-server and the token into auth-token <i>CURRENT VALUE</i>. Click on <b>Update</b>.

<b>Pro Tip:</b> The current value is never shared while sharing the Postman Collection. Also, since these variables have sensitive information, it is best to add them to the environment variables. We could use the same collection and run it on different environments (i.e., GCP, Minikube).

3. Next, add Authorization to the collection. Adding Authorization at the collection level will ensure all the requests within the collection will be authorized with the same token/credentials.

4. Click on <b>Edit Collection</b> and under <b>Authorization</b>, select <b>OAuth2.0</b>. We can use the auth-token variable as the Access Token. This token will be passed in the Request Headers for each request.

<img class="wp-image-9528 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image23.png" alt="Adding authorization to a collection" width="1608" height="1416" /> Adding authorization to a collection

5. Almost there! The last step to get our collection ready is adding the CA Certificate. Simply click on <strong>Settings</strong> for Postman, and under <strong>Certificates</strong>, turn on the CA Certificates toggle to upload the ca.crt file we created. Alternatively, you can disable certificate verification, but that is not recommended.

<img class="wp-image-9529 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image13.png" alt="Adding CA Certificates to access Kubernetes APIs" width="1440" height="1040" /> Adding CA Certificates to access Kubernetes APIs
<h2>Deploy an app</h2>
We are all set to deploy. First, we need something very important. Not surprisingly, it is an app. Let's take a look at the app.

Enter <a href="https://github.com/thecasualcoder/dobby">Dobby</a>. Dobby is an open source project, and it's extremely simple to call different APIs on it and manipulate responses.

We spoke about containerization earlier: a container simply means an app is running in a sandbox. The container is created from an image. If there are any code changes in the app, we recreate the image to reflect the app’s latest changes and rerun the container.

We can find the publicly available image for Dobby <a href="https://hub.docker.com/r/thecasualcoder/dobby">here</a>. We must use the image in the request.

The <b>Deploy an App </b>folder in the collection contains requests to create and list Kubernetes objects that will help deploy our app on AWS. Let’s take a quick look at these objects.
<h3><b>Creating a Kubernetes pod</b></h3>
In Kubernetes, pods are a group of containers and also the smallest deployable unit. The pod will define the configuration that is required to create the app container.

<img class="wp-image-9530 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image4.png" alt="Containers in a Kubernetes pod" width="638" height="506" /> Containers in a Kubernetes pod

We must create a pod for Dobby. You should find the configuration as json in the request body. We have created a collection variable called <i>project-name</i>, this variable is going to be used throughout the collection while creating resources, so it made perfect sense to extract it. You can rename the variable if you want.

1. Click on <b>Body</b> to find the request body as shown in here:

<img class="wp-image-9531 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image24.png" alt="Creating a Pod POST Request" width="1589" height="824" /> Creating a Pod POST Request

You will find fields for metadata name, the name of the pod, and labels. We'll discuss how labels are useful in the subsequent requests. If you scroll below to the spec you will also find the image that we are using for the containers, and the port the app is supposed to run on.

2. Press <b>Send</b>. There will be a lot of details in the response body.

3. Click on <b>Visualize, </b>and if the response is successful, congratulations are in order! Keep going.

<img class="wp-image-9532 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image2.png" alt="Visualization of successful creation of a pod" width="1999" height="480" /> Visualization of successful creation of a pod

4. <b>Send </b>the GET request that lists all pods created. Again, click on the <b>Visualize</b> button:

<img class="wp-image-9534 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image22.png" alt="Visualization to list pods created" width="1999" height="722" /> Visualization to list pods created

5. Head over to the Clean Up folder, and run the <b>Delete Pod</b> request:

<img class="wp-image-9536 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image16.png" alt="Deleting a pod request" width="1884" height="1440" /> Deleting a pod request

6. Again, click on <b>Visualize </b>to see the response as a prettier message:

<img class="wp-image-9537 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image21.png" alt="Visualization of successful deletion of a pod" width="1999" height="498" /> Visualization of successful deletion of a pod
<h3><b>Deployment</b></h3>
In the previous section, we created a pod and deleted it. That means our app is no longer running. In a real-world scenario, though, we would want to have multiple instances of our app running so that the requests could be load-balanced across them. These instances (pods) could be running on different nodes/machines. We want to ensure that at least a minimum amount of instances are running. Deployments can help us manage it all.

<img class="wp-image-9538 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image9.png" alt="Kubernetes deployment" width="898" height="786" /> Kubernetes deployment

1. Click on <b>Body</b> to review the request body. The body contains the configuration for the deployment:

<img class="wp-image-9539 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image8.png" alt="Creating a Deployment POST Request" width="1654" height="902" /> Creating a Deployment POST Request

Components of the body:
<ul>
 	<li><b>Replicas</b>: Refer to the number of pods that should be running for a deployment. We are assigning the pods that get created via this deployment a label of <b>-pod</b>.</li>
 	<li><b>Labels</b>: Pods are matched to the respective deployments by these labels.</li>
</ul>
The body also contains a definition for a readiness probe and a liveness probe:
<ul>
 	<li><b>Readiness Probe</b>: Containers are assigned traffic in Kubernetes based on the readiness probe. This can be used when the container is not ready to serve traffic due to other services it depends on, or if it is loading any data/configuration.</li>
 	<li><b>Liveness Probe</b>: Containers restart based on the liveness probe. So to check if the Dobby app is up, the /health endpoint will be hit. If it returns a 500 then the containers are restarted.</li>
</ul>
2. Press <b>Send </b>to create a deployment and look into the <b>Visualization</b> tab for the next steps:

<img class="wp-image-9540 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image12.png" alt="Visualization of successful deployment creation" width="1999" height="449" /> Visualization of successful deployment creation

3. <b>Send </b>the GET request that lists all pods created. See results in the <b>Visualization</b> tab:

<img class="wp-image-9541 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image6.png" alt="Visualization listing pods created via deployment" width="1999" height="695" /> Visualization listing pods created via deployment
<h2>Expose your app</h2>
In the previous section, we were able to successfully create a deployment. So how do we access it now? The pods created have IP addresses, but what if we want to access one app from another?

Let's take a look at Kubernetes’ service.
<h3><b>Service</b></h3>
We have two apps—frontend and backend. There are separate pods for the frontend and for the backend. We need to expose the pods of the backend so that the frontend app can access it and use the APIs. We usually configure the IP address or URL for the backend into the frontend. However, if the IP address changes for the backend, those changes would have to be reflected in the frontend app as well. With services, we can avoid these changes.

<img class="wp-image-9542 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image1.png" alt="Kubernetes Service" width="1554" height="854" /> Kubernetes Service

1. Review the request body by clicking <b>Body</b>:

<img class="wp-image-9543 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image7.png" alt="Creating a Service POST Request" width="1656" height="675" /> Creating a Service POST Request

Components of the body:
<ul>
 	<li><b>Selectors</b>: The selectors help the service map to the pods that have the matching label.</li>
 	<li><b>Exposing</b>: Services can be exposed <i>within</i> the cluster for other services (frontend) to access the pods, or<i> outside</i> the cluster for the public to access the service. By default, the service would be of ClusterIP type (this would expose the service inside the cluster). We want to expose this externally, so we chose the <i>LoadBalancer</i> type.</li>
</ul>
2.<b> Send </b>and view the<b> Visualization </b>tab:

<img class="wp-image-9544 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image11.png" alt="Visualization of successful creation of service" width="1999" height="436" /> Visualization of successful creation of service

3. Run the list of service requests to find the IP address of the service. Here’s what you should see under <b>Visualize </b>for the List Services request:

<img class="wp-image-9545 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image17.png" alt="Visualization listing services" width="1999" height="781" /> Visualization listing services

The following snippet in the <b>Tests</b> tab will save the external IP for the service to the collection:
<pre>const service = pm.response.json().items.filter((item) =&gt; item.metadata.name === 
pm.variables.get("project-name")+"-service")[0]pm.collection
Variables.set("service-ip", 
service.status.loadBalancer.ingress[0].hostname)
pm.collectionVariables.set("service-port", service.spec.ports[0].port)</pre>
Now we need to access an endpoint on the Dobby app to check if the app is running. Note: It might take a while before the service starts serving requests. Once the service is ready, click on the <strong>Say Hello to Dobby</strong> request. If you hover over the <i>service-ip </i>and <i>service-port</i> variables, you should see their value that was set by the tests in the previous request:

<img class="wp-image-9596 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-17-at-6.12.19-PM.png" alt="Dobby health check request" width="2004" height="830" /> Dobby health check request

Upon pressing <b>Send</b>, under <b>Visualize </b>you should see the message we have been working so hard for:

<img class="wp-image-9548 size-full" src="https://blog.postman.com/wp-content/uploads/2020/12/image3.png" alt="Visualization message when Dobby is healthy " width="1999" height="558" /> Visualization message when Dobby is healthy
<h2>Clean up</h2>
You will find a Clean Up folder in the collection. It contains all the requests to delete the Kubernetes resources—services, deployments, and pods we created throughout this tutorial.

At the end of the tutorial make sure you delete your cluster, unless you wish to keep it:
<pre>eksctl delete cluster -f cluster.yaml</pre>
<h2>What next?</h2>
Hopefully this tutorial helped you get started with Kubernetes. And there’s so much more to explore. Here are some additional things you can try with this Kubernetes collection:
<ul>
 	<li><b>Creating oth</b><b>er Kub</b><b>ernetes objects: </b>In this tutorial, we discussed a few Kubernetes objects, including service accounts, pods, deployments, and services. Next, you could explore other kubernetes objects like namespaces and ConfigMaps.</li>
 	<li><b>Automate workflows in Postman: </b>You could use the collection runner in Postman to execute common workflows. A workflow in Postman is ordering the requests in a collection to accomplish a task eg. running health checks for all services. Take a look at our blog post about <a href="https://blog.postman.com/looping-through-a-data-file-in-the-postman-collection-runner/#:~:text=Postman's%20Collection%20Runner%20lets%20you,Test%20for%20hundreds%20of%20scenarios">looping through a data file in the postman collection runner</a> and <a href="https://learning.postman.com/docs/running-collections/building-workflows/">building workflows in Postman</a>.</li>
 	<li><b>Automate deployments in CI/CD: </b>In case you want to automate deployments, consider using <a href="https://learning.postman.com/docs/running-collections/using-newman-cli/command-line-integration-with-newman/">Newman</a>—command line runner for Postman collections. If you prefer kubectl, you could use that instead.</li>
 	<li><b>Experiment with Dobby APIs to learn more: </b>The Dobby app has APIs such as
/control/health/sick, which will make the app return an internal server error. You can run these and observe their effect on the liveness and readiness probes to learn more.</li>
 	<li><b>Fork collection and raise PR: </b>Additionally, you could also <a href="https://learning.postman.com/docs/collaborating-in-postman/version-control-for-collections/#forking-a-collection">fork the collection</a> and raise a <a href="https://learning.postman.com/docs/collaborating-in-postman/version-control-for-collections/#creating-pull-requests">pull request</a> with your changes.</li>
</ul>
<i>Technical review by Kevin Swiber, lead solutions engineer at Postman.</i>

<b>What do you think about this topic? Tell us in a comment below. You can also give product feedback through our </b><a href="https://community.postman.com/"><b>Community forum</b></a><b> and </b><a href="https://github.com/postmanlabs/postman-app-support/issues"><b>GitHub repository</b></a><b>.