How to assign a static IP to a pod using Kubernetes

1/10/2017

currently kubectl assigns the IP address to a pod and that is shared within the pod by all the containers.

I am trying to assign a static IP address to a pod i.e in the same network range as the one assigned by kubectl, I am using the following deployment file

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: rediscont
    spec:
      containers:
      - name: redisbase
        image: localhost:5000/demo/redis
        ports:
        - containerPort: 6379
          hostIP: 172.17.0.1
          hostPort: 6379

On the dockerhost where its deployed i see the following:

CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                       NAMES
4106d81a2310        localhost:5000/demo/redis            "/bin/bash -c '/root/"   28 seconds ago      Up 27 seconds                                   k8s_redisbase.801f07f1_redis-1139130139-jotvn_default_f1776984-d6fc-11e6-807d-645106058993_1b598062
71b03cf0bb7a        gcr.io/google_containers/pause:2.0   "/pause"                 28 seconds ago      Up 28 seconds       172.17.0.1:6379->6379/tcp   k8s_POD.99e70374_redis-1139130139-jotvn_default_f1776984-d6fc-11e6-807d-645106058993_8c381981

The IP tables-save gives the following output

-A DOCKER -d 172.17.0.1/32 ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

Even with this, from other pods the IP 172.17.0.1 is not accessible. Basically the question is how to assign static IP to a pod so that 172.17.0.3 doesn't get assigned to it

-- Prashant
kubectl
kubernetes

2 Answers

2/9/2019

When you created Deployment with one replica and defined hostIP and hostPort you basically bounded hostIP and hostPort of your host machine with your pod IP and container port, so that traffic is routed from hostIP: port to podIP: port. Created pod (and container inside of it ) was assigned the ip address from the IP range that is available to it. Basically, the IP range depends on the CNI networking plugin used and how it allocates IP range to each node. For instance flannel, by default, provides a /24 subnet to hosts, from which Docker daemon allocates IPs to containers. So hostIP: 172.17.0.1 option in a spec has nothing to do with assigning IP address to a pod.

Basically, the question is how to assign static IP to a pod so that 172.17.0.3 doesn't get assigned to it

As far as I know, all major networking plugins, provide a range of IPs to hosts, so that a pod's IP will be assigned from that range. You can explore different networking plugins and look at how each of them deals with IPAM(IP Address Management), maybe some plugin provides that functionality or offers some tweaks to implement that, but overall its usefulness would be quite limited.

Below is useful info on "hostIP, hostPort" from official K8 docs:

Don’t specify a hostPort for a Pod unless it is absolutely necessary. When you bind a Pod to a hostPort, it limits the number of places the Pod can be scheduled, because each combination must be unique. If you don’t specify the hostIP and protocol explicitly, Kubernetes will use 0.0.0.0 as the default hostIP and TCP as the default protocol.

If you only need access to the port for debugging purposes, you can use the apiserver proxy or kubectl port-forward.

If you explicitly need to expose a Pod’s port on the node, consider using a NodePort Service before resorting to hostPort. Avoid using hostNetwork, for the same reasons as hostPort. Orignal info link to config best practices.

-- Alexz
Source: StackOverflow

2/8/2019

Generally, assigning a Pod a static IP address is an anti-pattern in Kubernetes environments. There are a couple of approaches you may want to explore instead. Using a Service to front-end your Pods (or to front-end even just a single Pod) will give you a stable network identity, and allow you to horizontally scale your workload (if the workload supports it). Alternately, using a StatefulSet may be more appropriate for some workloads, as it will preserve startup order, host name, PersistentVolumes, etc., across Pod restarts.

I know this doesn't necessarily directly answer your question, but hopefully it provides some additional options or information that proves useful.

-- Scott Lowe
Source: StackOverflow