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?
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.