Managing GitFlow Environments Using K8s— Network Edition
Kubernetes has become an extremely valuable platform for managing environments. Those who are experienced with “GitFlow” environment management can use it to simplify much of the process to get there. Kubernetes can solve many difficulties, such as creating, deleting and managing resources, creating resources per development need, and more.
In the past, it was extremely difficult to manage Dev/Stage/Prod environments. Much of the challenge had to do with provisioning and initiating the environment against resources that require management, such as load balancers and app-to-infra connection, and to connect microservices to each other. With Kubernetes, the old back-and-forth between developers and IT/DevOps becomes redundant, as much of the process is automated.
Using Kubernetes to Simplify the Process
To manage an environment using Kubernetes, it is necessary to use objects which enable the mission to be part of the engine. In the example, below, we will be using the Namespace, Service, and ConfigMap (as a helper) objects.
Service
On Kubernetes, a Service is an abstract way to expose an application running on a set of Pods as a network service. For this example, let’s say we have service A, called “my-rest” (a RESTful web service), and service B, called “some-service.” We will call “my-rest” Service’s route “/get-customer-permissions,” meaning “some-service” Pods can curl the following URL: http://my-rest/get-customer-permissions. Within a Kubernetes environment, it is possible to use an unsecured call within the namespace scope.
Namespace
The Kubernetes Namespace is a logic scope that collects most of the objects. In addition, we can use the name of the namespace as part of an FQDN continuing with the Service address mentioned above, we will be able to use the following URL: http://<NAMESPACE_NAME>.my-rest/get-customer-permissions).
For example, say you have three services on the same developed branch, and you use the branch name for namespace-creation, as a part of the CI/CD process. In this instance, we already enabled a dynamic environment creation per developed branch, across the deployed services, to be created within the Namespace scope.
ConfigMap
The ConfigMap is often used as a helper for configuration challenges. For dynamic environment management, we will create a ConfigMap containing the external DNS info, and mount it into Kubernetes Pod, as a file or an environment variable, and retrieve that info from the app layer in a more manageable way.
Putting it all Together
In the context of environment-management, we now understand that we can deploy multiple services into a namespace using their particular branch names. Also, we now know that the namespace and the service objects can be DNS-resolved. Furthermore, we can use the ConfigMap object to simplify our challenges and to obtain resource information we saved as a part of the CI/CD process.
Bonus: Creating a Feature-Branched Environment
Consider this situation: We’ve created and deployed the microservices mentioned above, but now we want to change one of our microservices into a separate branch/namespace. Let’s say that the microservice was deployed under the namespace “develop”. We want to change a single microservice, but we don’t want to duplicate and redeploy unchanged microservices on other namespaces — we want to reuse them transparently and efficiently, without wasting resources such as CPU, memory or storage.
With Kubernetes, we can do so easily, using an attribute called ExternalName. We can use this attribute to copy all microservice’s service objects from the source namespace. For this instance, we could use a kubectl client to get the source service object, modify it on the fly, and apply it to the new namespace.
Next, we would modify and add the ExternalName key to a point on the source FQDN of the copied Service. This will serve as a continuance to the “my-rest” and “some-service” services defined above. ExternalName will get the following values, respectively: “my-rest.develop.svc.cluster.local”, “some-service.develop.svc.cluster.local”.
Now, all Service objects fallback to the “fb-test” namespace, which was copied from the “develop” namespace. The flexibility offered by Kubernetes means that If you want to change one of those services again, you can simply create an “fb-test” branch and deploy it. Using the “helm — force” command to replace existing objects, the new branch will also override the copied service objects with all actual service parameters.
As you can see, creating an efficient feature-branched environment with a subset of microservices is much simpler with Kubernetes.