I'm a newbie here, and i am in the process of preparing my development and production environment for a webapp Microservices architecture. I have injected environment variables through my deployment files in order to control the environment by which the app will be running. For example a Microservice running in development mode will work with development databases. So my question is, what do you think is the best practice to control multiple environment deployments. Should i have multiple deployment files, one for each environment for the same Microservice? Or is there a better practice? Thanks
Typically you want that applications running on the dev
environment don't interfere with applications running on the production
environment. Using Kubernetes, you can get this kind of isolation using different namespaces for different environments. That way, objects on the production
namespace are different from objects on the dev
namespace. Another, more expensive approach would be to use different k8s clusters for different environments.
Having this setup, you would deploy your application in the namespace for the specific environment where you want to deploy to, creating the Deployment
object on that namespace. This Deployment
would make use of a ConfigMap
object containing your application environment variables. The variables inside the ConfigMap
will be different on each namespace/environment. That way, your Deployment
object is the same across different environments, which let's you be more confident that what you are testing on dev
is the same that you will use on production
. The Deployment
object is the same, but it uses different variables to run.
Using the example Pod from the documentation
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# Define the environment variable
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
name: special-config
# Specify the key associated with the value
key: special.how
restartPolicy: Never
Saving that content into pod.yaml
, we can create it in our namespaces with kubectl -n my-namespace-development create pod.yaml
, and kubectl -n my-namespace-production create pod.yaml
.
This Pod would use a ConfigMap called special-config
. This configmap can be created like kubectl -n my-namespace-production create configmap special-config --from-literal=special.how=very
in production, and kubectl -n my-namespace-development create configmap special-config --from-literal=special.how=very-dev
.
As you can see, the configmap content is different on each namespace. So the Pod created on the namespace called my-namespace-production
will use the value very
, but the pod created on the namespace my-namespace-development
will use the value very-dev
.
In addition to @fiunchinho answer. Kubernetes documentation provides 3 ways of managing deployments, services, etc:
Imperative commands - a user operates directly on live objects of a cluster, for example
kubectl create deployment <name-of-deployment> --image nginx
kubectl edit deployment <name-of-deployment>
For more information go through this link
Imperative object configuration - the kubectl command specifies the operation, optional flags and at least one file name. The file specified must contain a full definition of the object in YAML or JSON format, for example
kubectl create -f nginx.yaml
kubectl replace -f nginx.yaml
kubectl delete -f nginx.yaml
For more information go through this link
Declarative object configuration - a user operates on object configuration files stored locally, however the user does not define the operations to be taken on the files. Create, update, and delete operations are automatically detected per-object by kubectl
, for example
kubectl apply -f nginx.yaml
kubectl apply -f configs/
For more information go through this link