I tried having something similar too.
Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: backend-api-v2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: backend-api-v2
    spec:
      containers:
      - image: registry.gitlab.com/<project>/<app>:<TAG>
        imagePullPolicy: Always
        name: backend-api-v2
        env:
        - name: PORT
          value: "8080"
        ports:
          - containerPort: 8080
        livenessProbe:
          httpGet:
            # Path to probe; should be cheap, but representative of typical behavior
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 5
      imagePullSecrets:
        - name: registry.gitlab.com
Service
apiVersion: v1
kind: Service
metadata:
  name: api-svc-v2
  labels:
    app: api-svc-v2
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 31810
    protocol: TCP
    name: http
  selector:
    app: backend-api-v2
Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: api.foo.com
    http:
      paths:
      - path: /v1/*
        backend:
          serviceName: api-svc
          servicePort: 80
      - path: /v2/*
        backend:
          serviceName: api-svc-v2
          servicePort: 80
 the service is using type: NodePort and not LoadBalancer, I have also defined a nodePort but I believe it will create one if you leave it out.