0

In k8s, I want my server to listen on podIP rather than 127.0.0.1 or 0.0.0.0. But the podIP is dynamically allocated, so I want to do something like:

ip := getIPFromNic("eth0")
net.Listen(ip)

But I don't know how to ensure the nic in pod is called eth0 rather than en0 or others. Should I do something in Dockerfile or should I do something in deployment.yaml?

I tried to search on google, but didn't find any related resources about the nic in docker. Most of the blogs are talking about the veth and docker bridge

PHPBird
  • 11
  • 2
  • Why would binding to that specific IP matter? You can control visibility via container networking. – tadman Apr 18 '23 at 02:44
  • k8s network policy requires specific CNI plugin. – PHPBird Apr 18 '23 at 03:22
  • Yeah, but that's just how it's done. If you care about visibility, you use one that can do that. If you don't care, you don't care. That being said, I'm not sure binding to a very specific IP provides any advantages at all. It's not like this will spill over to other interfaces other than the loopback one. – tadman Apr 18 '23 at 03:26
  • 1
    You will probably have exactly two interfaces, so picking the one that's not the loopback interface will give you the address you want. As @tadman suggests, iterating through the interfaces and binding separately to all of them will be very similar to just binding to 0.0.0.0. Your fragment looks like Go; does [How do I get the local IP address in Go?](https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go) find the address you want? – David Maze Apr 18 '23 at 10:37

3 Answers3

1
  1. Your pods ip address is present in: /proc/1/task/1/net/fib_trie file

mine is like:

 cat /proc/1/task/1/net/fib_trie
Main:
  +-- 0.0.0.0/1 2 0 2
     +-- 0.0.0.0/4 2 0 2
        |-- 0.0.0.0
           /0 universe UNICAST
        +-- 10.0.0.0/24 2 0 2
           |-- 10.0.0.45
              /32 host LOCAL
           |-- 10.0.0.184
              /32 link UNICAST
     +-- 127.0.0.0/8 2 0 2
        +-- 127.0.0.0/31 1 0 0
           |-- 127.0.0.0
              /32 link BROADCAST
              /8 host LOCAL
           |-- 127.0.0.1
              /32 host LOCAL
        |-- 127.255.255.255
           /32 link BROADCAST

and 10.0.0.45 is my pod ip address


  1. also if you have enough privileges, you can use kubernetes rest api to access pod information:

curl -s -H "Authorization: Bearer $YOUR_TOKEN" https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods/$(hostname)/ | grep "podIP" | awk '{print $2}' | tr -d '",'

unfortunately default privileges of cat /var/run/secrets/kubernetes.io/serviceaccount/token is not enough for this request.

Aref Riant
  • 582
  • 3
  • 14
0

You can get the pod ip from Kubernetes rather than trying to look it up from the interface (or files in /proc).

You can expose information about a Pod as environment variables; the documentation includes this example; look in particular at how MY_POD_IP is set:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

You can an example of this in use in the node_exporter manifests from the kube-prometheus project.

larsks
  • 277,717
  • 41
  • 399
  • 399
0

After digging into this problem, I found that the network interface name is controlled by the kubelet, it's a cluster wide configuration that can't be changed by the users. By default, the nic name is eth0, and if you're not sure, you can check any pod in the cluster to confirm that.

In practice, it's recommended to use downward api to pass the PodIP as an env var to the pod, thus you can get the PodIP easily. But my case is a little special, the application's config file(mounted as a configmap) need a listen addr, which must be either an ip address or a nic name. That's why I need a fixed value.

PHPBird
  • 11
  • 2