Kubernetes Headless Service resolves to specific interface of a multi-interface Pod

7/29/2019

I have a Deployment with multiple interfaces using CNI-Genie:

apiVersion: "apps/v1"
kind: Deployment
metadata:
  name: my-shiny-app
  labels:
    app: shiny-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: shiny-app
  template:
    metadata:
      labels:
        app: shiny-app
      annotations:
        cni: "weave, flannel"
    spec:
      containers:
<---snip--->

I can see that two interfaces are indeed created in the pod and IP addresses are assigned to it.

$ kubectl describe pod my-shiny-app-65c97dfdb9-crl7q
<---snip--->
Annotations:    cni: weave, flannel
                multi-ip-preferences: {"multi_entry":2,"ips":{"ip1":{"ip":"10.36.0.12","interface":"eth0"},"ip2":{"ip":"10.244.1.53","interface":"eth1"}}}
Status:         Running
IP:             10.36.0.12
<---snip--->

Now I would like to use the two interfaces for different type of traffic. For example, the eth0 interface for HTTP traffic and eth1 will be UDP traffic. My application would bind and listen for the respective kind of traffic on these interfaces.

So far, so good!

Now I would like to use two Headless Services for sending traffic to my application. Like this:

apiVersion: v1
kind: Service
metadata:
  name: shiny-app-http-service
spec:
  selector:
    app: shiny-app
  ports:
  - protocol: TCP
    port: 8080
    name: shiny-app-http
  clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
  name: shiny-app-udp-service
spec:
  selector:
    app: shiny-app
  ports:
  - protocol: UDP
    port: 8805
    name: shiny-app-udp
  clusterIP: None

However, both these services resolve to the IP address of the eth0 interface of the application. Is there any possible mechanism with which a Headless Service can reliably resolve to a specific interface of multi-interface pods?

-- Soumya Kanti
kubernetes

1 Answer

7/30/2019

Deployment definition is correct. Could you show me the output of:

kubectl exec -it my-shiny-app -- ip addr

It will shows if the interfaces were created correctly, each within the subnet of its CNI.

What I am thinking about is creating a service without any selectors:

apiVersion: v1
kind: Service
metadata:
  name: shiny-app-http-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

Because this Service has no selector, the corresponding Endpoint object is not created automatically. You can manually map the Service to the network address and port where it’s running, by adding an Endpoint object manually:

apiVersion: v1
kind: Endpoints
metadata:
  name: shiny-app-http-service
subsets:
  - addresses:
      - ip: 10.36.0.12
    ports:
      - port: 9376

Accessing a Service without a selector works the same as if it had a selector. In the example above, traffic is routed to the single endpoint defined in the YAML: 10.36.0.12:9376 (TCP).

So you can create two services and two endpoints files with two IP addresses, first IP from Weave (10.36.0.12) and second from Flannel (10.244.1.53).

More about services without selectors you can find here.

-- muscat
Source: StackOverflow