How to make k8s microservice hostname generic with respect to namespace

1/26/2020

Currently our k8s project has following use case were the namespaces are hardcoded into the values.yaml and application source codes

(apps) namespace - NS1                 

> micro-service-A1

> micro-service-A2

> micro-service-A3

(database) namespace - DB1

> mongo-service

(messaging) namespace - MB1

> kafka-zk-service

We want to run multiple sets of above services(apps, database, messaging) in unique namespaces defined by each Engineer(Developer) such that each developer can safely bring down/play-around changing the complete set belonging to him without worrying impact on other Developers' namespace.

# Developer1 (set)


(apps) namespace - Dev1   

> micro-service-A1

> micro-service-A2

> micro-service-A3

(database) namespace - Dev1_DB

> mongo-service

(messaging) namespace - Dev1_MB

> kafka-zk-service

# Developer2 (set)


(apps) namespace - Dev2                

> micro-service-A1

> micro-service-A2

> micro-service-A3

(database) namespace - Dev2_DB

> mongo-service

(messaging) namespace - Dev2_MB                     

> kafka-zk-service

What should be the configuration of the yamls & application source code such that dynamic deployment is feasible in any namespace of developers choice?

-- Bhavani Prasad
kubernetes

2 Answers

1/26/2020

You can use --namespace flag to pass the namespace while applying the config instead of hard coding it in the config file.

kubectl apply -f service.yml --namespace=test

kubectl apply -f service.yml --namespace=prod

In this way, you can use the same config file to create the service resource in different namespaces.

-- Devesh mehta
Source: StackOverflow

1/26/2020

Externalize configuration

It is good to externalize your configuration so that you can use a different configuration without building a new image.

Use a ConfigMap for configuration with address e.g. to other services or databases. See DNS for Services and Pods for adressing.

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  SERVICE_A: service-a.a-namespace.svc.cluster.local
  SERVICE_B: service-b.b-namespace.svc.cluster.local
  DB: db.local

Use the values from your ConfigMap as environment variables in your app by mapping it in your Pod or Deployment in the PodTemplate

  containers:
    - name: app-container
      image: k8s.gcr.io/app-image
      env:
        - name: SERVICE_A_ADDRESS
          valueFrom:
            configMapKeyRef:
              name: config
              key: SERVICE_A
        - name: SERVICE_B_ADDRESS
          valueFrom:
            configMapKeyRef:
              name: config
              key: SERVICE_B

Service with External Name

If you want to move a service to a new namespace but keep the addressing, you can leave a Service with External Name

kind: Service
apiVersion: v1
metadata:
  name: service-a
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: service-c.namespace-c.svc.cluster.local
  ports:
  - port: 80
-- Jonas
Source: StackOverflow