Deploy Microservices as Managed APIs on Kubernetes in 3 Minutes

Dinusha Dissanayake
API Integration Essentials
5 min readNov 4, 2019

With microservices becoming growing rapidly in today's world, exposing them to the consumers should be managed and easy to be deployed.

This article describes how we can manage and deploy APIs in a Kubernetes cluster under 3 minutes using API Operator for Kubernetes.

Photo by Dan Lohmar on Unsplash

Pre-requisites

  • Kubectl
  • Kubernetes v1.12 or above
    Minimum CPU and Memory for the K8s cluster: 2 vCPU, 8GB of Memory
  • An account in DockerHub or private docker registry
  • Download API controller v3.0.0 for your operating system from the website
  • Download the API Operator distribution from GitHub.
  • Once the download is complete, extract the zip and navigate inside api-k8s-crd-1.0.0 directory

Section 1: Configurations

This is a one time task for a given cluster. This may take up to 5 minutes to configure for the first time.

Once this is configured, it would take less than 3 minutes to deploy APIs in Kubernetes cluster.

*** Clock starts: 0 sec

Configuring API Operator

First, let’s deploy controller artefacts.

kubectl apply -f apim-operator/controller-artifacts/

Output:

namespace/wso2-system created
deployment.apps/apim-operator created
clusterrole.rbac.authorization.k8s.io/apim-operator created
clusterrolebinding.rbac.authorization.k8s.io/apim-operator created
serviceaccount/apim-operator created
customresourcedefinition.apiextensions.k8s.io/apis.wso2.com created
customresourcedefinition.apiextensions.k8s.io/ratelimitings.wso2.com created
customresourcedefinition.apiextensions.k8s.io/securities.wso2.com created
customresourcedefinition.apiextensions.k8s.io/targetendpoints.wso2.com created

*** Clock: 15 sec

Configure Docker-Hub account with API Operator.

  1. Open apim-operator/controller-configs/controller_conf.yaml and go to docker registry section(mentioned below), and update user’s docker registry with Docker-Hub username.
If the Docker-Hub username is admin
dockerRegistry: admin

2. Open apim-operator/controller-configs/docker_secret_template.yaml and navigate to data section.
Enter the base 64 encoded username and password of the Docker-Hub account. If the username and password are admin, then the final configuration would be as follows.

data:
username: YWRtaW4=
password: YWRtaW4=

After configuring the above, apply the configurations using the below command.

kubectl apply -f apim-operator/controller-configs/

configmap/controller-config created
configmap/apim-config created
security.wso2.com/default-security-jwt created
secret/wso2am300-secret created
configmap/docker-secret-mustache created
secret/docker-secret created
configmap/dockerfile-template created
configmap/mgw-conf-mustache created

*** Clock: 1 min

Install the API portal and security token service

The following command will deploy API portal & token service under a namespace called “wso2”.

kubectl apply -f k8s-artifacts/api-portal/Output:
namespace "wso2" created
configmap "apim-conf" created
deployment.apps "wso2apim" created
service "wso2apim" created

You can verify the API portal is running, by running the following command. (Note: It would take around 1 min to up and running API portal.)

kubectl get services -n wso2
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wso2apim NodePort 10.97.8.86 <none> 30838:32004/TCP,30801:32003/TCP,32321:32002/TCP,32001:32001/TCP 16s

*** Clock: 1min 30 sec

To access the devportal, add the host mapping entry to /etc/hosts file.

<Any K8s Node IP>  wso2apim

Once you added the entry, you can access the API portal https://wso2apim:32001/devportal

*** Clock: 2min 30 sec

Configuring API controller to interact with API Operator

Download API controller v3.0.0 for your operating system from the website (if you haven’t downloaded under pre-requisites section)

Extract the API controller distribution and navigate inside the extracted folder using the command-line tool

Add the location of the extracted folder to your system’s $PATH variable to be able to access the executable from anywhere.

You can find available operations using the below command.

apictl --help

By default API controller does not support kubectl command. Set the API Controller’s mode to Kubernetes to be compatible with kubectl commands

apictl set --mode k8s

** Clock: 3 min 30 sec

After about 3min and 30 seconds, we are done with the configuring API Operator.

Section 2: Deploying API

Now let’s deploy the pet store API as a managed API in Kubernetes.

*** Clock starts: 0 sec

Navigate to api-k8s-crds-1.0.0/scenarios/scenario-2 directory.

Already prepared basic Open API definition for pet store can be found in swagger.yaml.

However, if you are doing this for another Open API 3.0 definition, make sure to include the following.

  • The base path of the API should be mentioned in the swagger file with the “x-wso2-basePath”. (In the example Petstore, it have been referred as below).
x-wso2-basePath: /petstore/v1
  • Backend URL should be mentioned under “x-wso2-production-endpoints”. In this APIdefinition, the backend service of the “petstore” service has been mentioned as follows. It can be either globally or resource level. In the scenarios, we have defined it at the resource level.
x-wso2-production-endpoints:
urls:
- https://petstore.swagger.io/v2

Deploying API on the Kubernetes cluster.

apictl add api -n petstore --from-file=swagger.yamlOutput:
creating configmap with swagger definition
configmap/petstore-swagger created
api.wso2.com/petstore created

*** Clock: 30 sec

What happens inside?

kubectl get pods 

Output:
NAME READY STATUS RESTARTS AGE
petstore-kaniko-fxvkt 1/1 Running 0 45s

If the pod name has “kaniko”, then it is the pod related to Kaniko job for building the API image for the given API definition. Wait until the status of this pod becomes completed. (It would take around 50-60 secs in GKE to complete this. For Minikube, it would take nearly 3 minutes)

kubectl get pods 

Output:
NAME READY STATUS RESTARTS AGE
petstore-kaniko-fxvkt 1/1 Completed 0 45s

Once the Kaniko job is completed, t it means the API gateway image has been created successfully. Then, API Operator would create the deployment and service with Horizontal Pod Autoscaler for the deployed API.

*** Clock: 2 min

Let’s verify if the API has been deployed by listing the available pods.

kubectl get pods 

Output:
NAME READY STATUS RESTARTS AGE
petstore-hfdkf-fxvkt 1/1 running 0 20s

If you see READY (1/1), then the API has been deployed successfully.

Execute the following command to make sure the API is accessible.

apictl get servicesOutput:NAME     TYPE       CLUSTER-IP     EXTERNAL-IP       PORT(S)   AGE     petstore LoadBalancer 10.83.14.186 35.188.53.193     9095:32264/TCP,9090:32540/TCP   2m42s

Extract the “External-IP” from above output. This will be used in Section 3.

Now we have deployed API in the Kubernetes cluster under 2min 30 sec.

Section 3: Invoking the API

*** Clock: 2 min 30sec

Here I would only be talking about invoking API from the easiest way using a sample token. But when it comes to production scenario, you need to get access token properly from a JWT token issuer. I will be covering that in my next article.

Feed the sample token to your terminal or HTTP client.

TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlpqUm1ZVE13TlRKak9XVTVNbUl6TWpnek5ESTNZMkl5TW1JeVkyRXpNamRoWmpWaU1qYzBaZz09In0.eyJhdWQiOiJodHRwOlwvXC9vcmcud3NvMi5hcGltZ3RcL2dhdGV3YXkiLCJzdWIiOiJhZG1pbkBjYXJib24uc3VwZXIiLCJhcHBsaWNhdGlvbiI6eyJvd25lciI6ImFkbWluIiwidGllciI6IlVubGltaXRlZCIsIm5hbWUiOiJzYW1wbGUtY3JkLWFwcGxpY2F0aW9uIiwiaWQiOjMsInV1aWQiOm51bGx9LCJzY29wZSI6ImFtX2FwcGxpY2F0aW9uX3Njb3BlIGRlZmF1bHQiLCJpc3MiOiJodHRwczpcL1wvd3NvMmFwaW06MzIwMDFcL29hdXRoMlwvdG9rZW4iLCJ0aWVySW5mbyI6e30sImtleXR5cGUiOiJQUk9EVUNUSU9OIiwic3Vic2NyaWJlZEFQSXMiOltdLCJjb25zdW1lcktleSI6IjNGSWlUM1R3MWZvTGFqUTVsZjVVdHVTTWpsUWEiLCJleHAiOjM3MTk3Mzk4MjYsImlhdCI6MTU3MjI1NjE3OSwianRpIjoiZDI3N2VhZmUtNTZlOS00MTU2LTk3NzUtNDQwNzA3YzFlZWFhIn0.W0N9wmCuW3dxz5nTHAhKQ-CyjysR-fZSEvoS26N9XQ9IOIlacB4R5x9NgXNLLE-EjzR5Si8ou83mbt0NuTwoOdOQVkGqrkdenO11qscpBGCZ-Br4Gnawsn3Yw4a7FHNrfzYnS7BZ_zWHPCLO_JqPNRizkWGIkCxvAg8foP7L1T4AGQofGLodBMtA9-ckuRHjx3T_sFOVGAHXcMVwpdqS_90DeAoT4jLQ3darDqSoE773mAyDIRz6CAvNzzsWQug-i5lH5xVty2kmZKPobSIziAYes-LPuR-sp61EIjwiKxnUlSsxtDCttKYHGZcvKF12y7VF4AqlTYmtwYSGLkXXXw

Now we have a valid sample access token. Let’s invoke the API using the below command.

Format of the command:curl -X GET "https://<external IP of LB service>:9095/petstore/v1/pet/55" -H "accept: application/xml" -H "Authorization:Bearer $TOKEN" -kReplace <external IP of LB service> with the "External-IP" of petstore service.curl -X GET "https://35.188.53.193:9095/petstore/v1/pet/55" -H "accept: application/xml" -H "Authorization:Bearer $TOKEN" -kResponse:<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Pet><category><id>55</id><name>string</name></category><id>55</id><name>SRC_TIME_SIZE</name><photoUrls><photoUrl>string</photoUrl></photoUrls><status>available</status><tags><tag><id>55</id><name>string</name></tag></tags></Pet>

Now you have successfully deployed the API and invoked it under 3 mins.

*** Clock: 3 min

This is the first release of the API Operator for Kubernetes and we are working on continuous improvements to enhance the user experience and fixing any issues encountered when trying out.

Please refer API Operator for Kubernetes docs for more information.

If you have any suggestions, do let us know via GitHub or comment here.

Thanks for reading…!!!

--

--