最近服务器都迁移到腾讯云 TKE 了,就是腾讯云 Kubernetes 服务,然后最近有个需求是获取客户端真实 IP。
我的情况:
服务用 Django 写的,通过 HTTP 请求头获取真实 IP
Django 通过 uwsgi 运行,并通过 Nginx 转发出去
Ingress 使用的 Nginx Ingress,而不是 TKE Ingress
下面说下几个关键配置:
Django 中获取 IP
获取方式如下:
1 2 3 4 5 6 7
def get_client_ip(request): x_forwarded_for = request.META.get ('HTTP_X_FORWARDED_FOR' ) if x_forwarded_for: ip = x_forwarded_for.split(',' )[0] else : ip = request.META.get ('REMOTE_ADDR' ) return ip
uwsgi 配置
uwsgi.ini 配置如下:
1 2 3 4 5 6 7 8
[uwsgi] module = core.wsgimaster = true processes = 1 vacuum = true static-map = /static=/app/app/statichttp = 127.0 .0.1 :8000 log-master = true
Nginx 配置
Nginx 需要转发 uwsgi 出去,并且加上三个关键请求头:
1 2 3 4 5 6 7 8 9 10 11
server { listen 7777 ; server_name localhost; location / { proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header Host $http_host ; proxy_pass http://127.0.0.1:8000; } }
Supervisor 配置
Supervisor 需要启动 Uwsgi 和 Nginx:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[supervisord] nodaemon =true [program:uwsgi] command =uwsgi --ini /app/uwsgi.inistdout_logfile =/dev/stdoutstdout_logfile_maxbytes =0 stderr_logfile =/dev/stderrstderr_logfile_maxbytes =0 [program:nginx] command =/usr/sbin/nginx -g "pid /run/nginx/nginx.pid; daemon off;" stdout_logfile =/dev/stdoutstdout_logfile_maxbytes =0 stderr_logfile =/dev/stderrstderr_logfile_maxbytes =0
Dockerfile 配置
Dockkerfile 里面指定启动的命令为 supervisor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
FROM python:3.7 -alpineENV PYTHONUNBUFFERED 1 WORKDIR /app COPY requirements.txt . RUN apk update && apk add \ libuuid \ gcc \ nginx \ supervisor \ libc-dev \ linux-headers \ postgresql-libs \ postgresql-dev \ && pip install pip -U \ && pip install -r requirements.txt COPY . /app RUN mkdir -p /run/nginx COPY nginx.conf /etc/nginx/conf.d/default.conf COPY supervisord.conf /etc/supervisord.conf CMD ["/usr/bin/supervisord" , "-c" , "/etc/supervisord.conf" ]
TKE 配置
这里参考来源为:https://cloud.tencent.com/document/product/457/48949
最关键的就是:
这里我需要修改 Service 的负载均衡:
修改 externalTrafficPolicy 为 Local 即可:
大功告成,后面 IP 就能成功获取到了。