简体   繁体   中英

How to get client IP address when the python code is running inside a kubernetes pod?

import uvicorn

app = FastAPI()


@app.get("/items/{item_id}")

def read_root(item_id: str, request: Request):

    client_host = request.client.host
    f= open("ipadress.txt","a+")
    f.write(client_host+"\n")
    f.close()

    return {"client_host": client_host, "item_id": item_id}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", forwarded_allow_ips="*")

The above is the python code which is hosted using uvicorn. When I run the code inside a docker container, it returns the correct client IP. But, when I host the same code on Kube.netes cluster using minikube the IP address which is returned is the localhost IP (127.0.0.1)

The docker command used to run the above code image is docker run -it -p 8080:8000 <image-name> I have exposed port 8080 to reach to the service from Virtual Machine

The kube.netes command used to expose the service is kubectl port-forward --address 0.0.0.0 services/sample-deploy 8080:80

The service.yaml for kube.netes is

apiVersion: v1
kind: Service
metadata:
  name: sample-deploy
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: sample-deploy

I also tried to access the service using LoadBalancer where the service can be accessed using an External IP yet I am not able to get the real client IP address. I think the IP address is masked in the kube.netes cluster.

When you do a port-forward you create a tunnel from your local machine to the container. So, the connection is seen in the container as if it is coming from the local machine (hence the 127.0.0.1 ). Port forwarding is usually just used for debugging purposes.

The typical way to access your application would be via a service of type LoadBalancer or via the Kube.netes ingress concept. In both cases you should get the correct client IP address. For the ingress the client IP is usually provided via a HTTP header (by the ingress load balancer/reverse proxy). Most ingress controllers use X-Forwarded-For . This header is usually picked up by the web app frameworks when checking for the client IP.

In the service YAML file, the externalTrafficPolicy should be set to Local so that the IP address is retained. The externalTrafficPolicy can be used only with NodePort or LoadBalancer types.

apiVersion: v1
kind: Service
metadata:
  name: sample-deploy
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
  - port: 80
  selector:
    app: sample-deploy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM