Create multiple instances of service running in kubernetes

We run Consul in kubernetes cluster, and for the purpose of enabling canary deployments, we need to have 2 different versions of same service running in kubernetes cluster at the same time, so Consul service splitting and routing functionality can be utilized during service upgrades.
The whole idea is to deploy new service version and to test some smaller amount of traffic there before switching whole traffic to newer version.

How to run 2 instances of same service in kubernetes?

This is yml used for my service deployment:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: serviceA

---
apiVersion: v1
kind: Service
metadata:
  name: serviceA
spec:
  selector:
    app: serviceA
  ports:
  - protocol: TCP
    port: 3000
    targetPort: afm

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serviceA-deployment
  labels:
    app: serviceA
spec:
  replicas: 1
  selector:
    matchLabels:
      app: serviceA
  template:
    metadata:
      labels:
        app: serviceA
      annotations:
        'consul.hashicorp.com/connect-inject': 'true'
        'consul.hashicorp.com/transparent-proxy': 'true'
        'consul.hashicorp.com/service-meta-version': 'v1'      
    spec:
      serviceAccountName: serviceA
      containers:
      - name: serviceA
        image: "fleet-mgr:latest"
        ports:
          - containerPort: 3000
            name: afm

I have tried to apply same above template twice in k8s, while just setting different annotations here

 'consul.hashicorp.com/service-meta-version': 'v1'    
 'consul.hashicorp.com/service-meta-version': 'v2'

but could not create 2 instances of service this way.

Hey @tmiroslav !!

Thanks for reaching out! Have you tried only creating a second deployment with the different annotation? It should continue to re-use the same ServiceAccount and the same Service. If that is what you mentioned, I have misunderstood the situation.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: serviceA

---
apiVersion: v1
kind: Service
metadata:
  name: serviceA
spec:
  selector:
    app: serviceA
  ports:
  - protocol: TCP
    port: 3000
    targetPort: afm

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serviceA-deployment
  labels:
    app: serviceA
spec:
  replicas: 1
  selector:
    matchLabels:
      app: serviceA
  template:
    metadata:
      labels:
        app: serviceA
      annotations:
        'consul.hashicorp.com/connect-inject': 'true'
        'consul.hashicorp.com/transparent-proxy': 'true'
        'consul.hashicorp.com/service-meta-version': 'v1'      
    spec:
      serviceAccountName: serviceA
      containers:
      - name: serviceA
        image: "fleet-mgr:latest"
        ports:
          - containerPort: 3000
            name: afm
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serviceA-deployment-v2
  labels:
    app: serviceA
spec:
  replicas: 1
  selector:
    matchLabels:
      app: serviceA
  template:
    metadata:
      labels:
        app: serviceA
      annotations:
        'consul.hashicorp.com/connect-inject': 'true'
        'consul.hashicorp.com/transparent-proxy': 'true'
        'consul.hashicorp.com/service-meta-version': 'v2'      
    spec:
      serviceAccountName: serviceA
      containers:
      - name: serviceA
        image: "fleet-mgr-2:latest"
        ports:
          - containerPort: 3000
            name: afm

The above should lead to Consul registering v1 and v2 versions of the service and you can use the router and splitter to direct traffic to the canary as desired.

If this is what you have already attempted, can you share any error logs you are seeing in the controllers?

Additionally, you will also need a ServiceResolver to help resolve those services.

Hi @ashwin-venkatesh

This works better. I was missing to set the way you did aboveā€¦ Thank you!
Very appreciated!

BR,
Miroslav