Trong quá trình vận hành hệ thống kubernetes mình gặp phải vấn đề lấy real IP của client (lấy ip của client gửi request đến cụm). Cụm k8s (kubernetes xin phép gọi tắt cho gọn) của mình đang sử dụng version v1.13.11 và dùng nginx-ingress version v0.26.1.

Dưới đây là flow tổng quát case đầu tiên mình gặp phải.

Domain abc.com trỏ vào public ip của một con nginx làm reverse proxy. Con này là 1 con server không nằm trên cụm k8s, tất cả request đến con proxy đều được forward về service của nginx-ingress. Vấn đề là làm sao trong các pod từ 1 đến 3 mình có thể lấy đc ip của User khi họ request vào domain abc.com. Mình sẽ chạy thử một ví dụ để mô tả trường hợp trên.

Tạo một deployment demo:

kubectl create deployment source-ip-app --image=k8s.gcr.io/echoserver:1.4

Tạo service của deployment:

kubectl expose deployment source-ip-app --port 8080

Kiểm tra trạng thái deployment và service:

kubectl get pod
Output:
NAME                             READY   STATUS    RESTARTS   AGE
source-ip-app-5bf59f5b75-fnqxn   1/1     Running   0          2m56s
kubectl get svc
Output
NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes                ClusterIP   10.10.0.1      <none>        443/TCP   130d
source-ip-app             ClusterIP   10.10.28.159   <none>        80/TCP    2m32s

Tạo ingress:

kubectl create -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.allow-http: "true"
    kubernetes.io/ingress.class: nginx
  name: source-ip-app
spec:
  rules:
  - host: abc.hocdevops.com
    http:
      paths:
      - backend:
          serviceName: source-ip-app
          servicePort: 8080
        path: /
EOF

Check lại xem domain work chưa:

curl -I -v http://abc.hocdevops.com
Output:
CLIENT VALUES:
client_address=10.9.1.174
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://abc.hocdevops.com:8080/

SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001

HEADERS RECEIVED:
accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding=gzip, deflate, br
accept-language=en-GB,en;q=0.9,vi-VN;q=0.8,vi;q=0.7,en-US;q=0.6
cache-control=max-age=0
cookie=lastSignedIn=google; sessions=%7B%7D; SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1
dnt=1
host=test.goquo.io
http-x-forwarded-for=38.xxx.xxx.xxx
http-x-forwarded-proto=https
sec-fetch-mode=navigate
sec-fetch-site=none
sec-fetch-user=?1
upgrade-insecure-requests=1
user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
x-forwarded-for=53.xxx.xxx.xxx
x-forwarded-host=abc.hocdevops.com
x-forwarded-port=80
x-forwarded-proto=http
x-forwarded-ssl=on
x-original-forwarded-for=38.xxx.xxx.xxx
x-real-ip=53.xxx.xxx.xxx
x-request-id=319da13ab129ab790cdcb9b49a723ef3
x-scheme=http
BODY:
-no body in request-

Logic của code là sẽ lấy Real IP qua header x-real-ip Chúng ta có thể thấy x-real-ip là ip của prõy không phải là ip của user. Để xử lý issue này chúng ta sửa configmap của nginx ingress 1 chút:

kubectl edit cm nginx-configuration -n ingress-nginx
# Thêm đoạn config sau vào cuối file
data:
  compute-full-forwarded-for: "true"
  use-forwarded-headers: "true"

Kiểm tra lại lần nữa xem đã được chưa này:

curl -I -v http://abc.hocdevops.com
Output:
CLIENT VALUES:
client_address=10.9.1.174
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://abc.hocdevops.com:8080/

SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001

HEADERS RECEIVED:
accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding=gzip, deflate, br
accept-language=en-GB,en;q=0.9,vi-VN;q=0.8,vi;q=0.7,en-US;q=0.6
cache-control=max-age=0
cookie=lastSignedIn=google; sessions=%7B%7D; SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1
dnt=1
host=test.goquo.io
http-x-forwarded-for=38.xxx.xxx.xxx
http-x-forwarded-proto=https
sec-fetch-mode=navigate
sec-fetch-site=none
sec-fetch-user=?1
upgrade-insecure-requests=1
user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
x-forwarded-for=38.xxx.xxx.xxx,53.xxx.xxx.xxx
x-forwarded-host=abc.hocdevops.com
x-forwarded-port=80
x-forwarded-proto=http
x-forwarded-ssl=on
x-original-forwarded-for=38.xxx.xxx.xxx
x-real-ip=38.xxx.xxx.xxx
x-request-id=319da13ab129ab790cdcb9b49a723ef3
x-scheme=http
BODY:
-no body in request-

Có thể thấy chúng ta đã lấy được Real IP của User dựa vào header x-real-ip.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments