見異思遷:K8s 部署 Nginx Ingress Controller 之 kubernetes/ingress-nginx

前天才發現,區區一個 nginx ingress controller 居然2個不一樣的實現。一個叫 kubernetes/ingress-nginx ,是由 kubernetes 社區維護的,對應的容器鏡像是 quay.io/kubernetes-ingress-controller/nginx-ingress-controller ,namespace 是 ingress-nginx ;一個叫 nginxinc/kubernetes-ingress ,是由 nginx 公司與社區共同維護的,對應的容器鏡像是 nginx/nginx-ingress ,namespace 是 nginx-ingresshtml

以前咱們用的是 nginxinc/kubernetes-ingress (詳見以前的博文), 不知道有2個不一樣的實現,在排查問題時有時查的是 kubernetes/ingress-nginx 的資料,南轅北轍,當時還納悶明明按照文檔進行了設置,爲何不起做用呢?node

因爲使用 nginxinc/kubernetes-ingress 後遭遇 K8s 中 ASP.NET Core 應用獲取不到客戶端真實 IP 地址 的問題(X-Forwarded-For轉發問題),因而被迫見異思遷試試換成 kubernetes/ingress-nginx 做爲 nginx ingress controller 。nginx

接下來是 kubernetes/ingress-nginx 的部署步驟。git

首先刪除以前的 nginxinc/kubernetes-ingress 部署。github

kubectl delete all --all -n nginx-ingress
kubectl delete namespace nginx-ingress

接着從 github 上籤出 kubernetes/ingress-nginx 倉庫,用其中的 mandatory.yaml 配置文件進行部署。bash

git clone https://github.com/kubernetes/ingress-nginx
cd deploy/static
kubectl apply -f mandatory.yaml

部署完成後,查看已部署的資源:app

$ kubectl get all -n ingress-nginx
NAME                                            READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-controller-6885bc7778-m62kv   1/1     Running   0          37m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-controller   1/1     1            1           37m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-controller-6885bc7778   1         1         1       37m

還少個 service ,咱們這裏用 nodePort 的方式部署 service ,因而選用 deploy/static/provider/baremetal/service-nodeport.yaml 部署文件,在其中添加 nodePort: 31080 指定端口。負載均衡

kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      nodePort: 31080
      port: 80
      targetPort: 80
      protocol: TCP
  # ....

部署 servicecurl

kubectl apply -f service-nodeport.yaml

查看部署結果ide

$ kubectl get svc -n ingress-nginx      
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.151.144   <none>        80:31080/TCP,443:32428/TCP   9

登陸 worker 節點用 curl 命令驗證 nginx 是否正常工做

$ curl -i localhost:31080/healthz
HTTP/1.1 200 OK
Server: nginx/1.17.8

返回 200 ,說明 nginx OK。

注:kubernetes/ingress-nginx 默認實現了健康檢查地址 /healthznginxinc/kubernetes-ingress 沒有實現,須要本身實現(詳見博問)。

登陸 nginx-ingress-controller pod ,查看 nginx 配置。

kubectl exec -it deployment/nginx-ingress-controller -n ingress-nginx /bin/bash

發現 kubernetes/ingress-nginx 中基於 ingress 規則生成的 nginx 配置全都放在 /etc/nginx/nginx.conf 中,而 nginxinc/kubernetes-ingress 是在 /etc/nginx/conf.d/ 目錄中用一個專門的配置文件存放,文件名以 ingress 所在的命名空間名稱開頭。

最後是最關鍵的時刻,驗證 kubernetes/ingress-nginx 是否也存在 X-Forwarded-For 轉發問題。

在 ConfigMap 中添加啓用 use-forwarded-headers 。

data:
  use-forwarded-headers: "true"

kubernetes/ingress-nginx 不負衆望!沒有 X-Forwarded-For 轉發問題,應用中能夠正常獲取到客戶端真實 IP 地址。

對比一下二者處理 X-Forwarded-For 的區別。

1)nginxinc/kubernetes-ingress 生成的 nginx 配置是

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

X-Forwarded-For 的值是 "116.62.124.68, 192.168.107.192"

2)kubernetes/ingress-nginx 生成的 nginx 配置是

proxy_set_header X-Forwarded-For $remote_addr;

X-Forwarded-For 的值是 "116.62.124.68"kubernetes/ingress-nginx 收到的請求是經過阿里雲負載均衡轉發過來的,客戶端真實 IP 地址也是藏在 X-Forwarded-For 中,但它神機妙算,會將 X-Forwarded-For 中的 IP 地址傳給 $remote_addr

若是在 ConfigMap 中添加下面的配置,kubernetes/ingress-nginx 的表現就和 nginxinc/kubernetes-ingress 同樣了。

data: 
  compute-full-forwarded-for: "true"

一次成功的見異思遷,情定 kubernetes/ingress-nginx

相關文章
相關標籤/搜索