Connect two pods to the same external access point

2/18/2022

I have two pods (deployments) running on minikube. Each pod has the same port exposed (say 8081), but use different images. Now I want to configure so that I can access either of the pods using the same external URL, in a load balanced way. So what I tried to do is put same matching label in both pods and map them to same service and then expose through NodePort. Example:

#pod1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep1
  labels:
    apps: dep1
    tier: cloud
spec:
  template:
    metadata:
      name: dep1-pod
      labels:
        app: deployment1
    spec:
        containers:
        - name: cont1
          image: cont1
          ports:
            - containerPort: 8081
  selector:
    matchLabels:
      app:deployment1

Now second pod

#pod2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep2
  labels:
    apps: dep2
    tier: cloud
spec:
  template:
    metadata:
      name: dep2-pod
      labels:
        app: deployment1
    spec:
        containers:
        - name: cont2
          image: cont2
          ports:
            - containerPort: 8081
  selector:
    matchLabels:
      app:deployment1

Now the service:

#service.yaml
apiVersion: v1
kind: Service
metadata:
  name: service1
spec:
  type: NodePort
  ports:
    - port: 8081
      targetPort: 8081
      nodePort: 30169
  selector:
    app: deployment1

Now this does not work as intended as it refuses to connect to my IP:30169. However, I can connect if only one of the pods are deployed. Now I know I can achieve this functionality using replicas and just one image, but in this case, I want to do this using 2 images. Any help is much appreciated.

-- Arnab Ghosh
kubernetes
kubernetes-pod
kubernetes-service
load-balancing
minikube

1 Answer

2/21/2022

You can use Ingress to achieve it.

  • Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
  • An Ingress may be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name-based virtual hosting.
  • An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
  • An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.

In your situation Ingress will forward traffic to your services using the same URL. It depends which path you type: URL for first Pod and URL/v2 for second Pod. Of course you can change /v2 to something else.

On the beginning you need enable Ingress on minikube. You can do it using a command below. You can red more about it here

minikube addons enable ingress

Next step you need create a Ingress using a yaml file. Here is an example how to do it step by step.

Yaml file of Ingress looks as below. As you can see in this configuration, you can access to one Pod using URL and it will forward traffic to first service attached to the first Pod. For the second Pod using URL/v2 it will forward traffic to second service on attached to the second Pod.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: hello-world.info
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 8080
	      - path: /v2
	        pathType: Prefix
	        backend:
	          service:
	            name: web2
	            port:
	              number: 8080
-- RadekW
Source: StackOverflow