敢雄 發表於 2020-2-21 12:23:00

见异思迁:K8s 部署 Nginx Ingress Controller 之 kubernetes/ingress-nginx

<p>前天才发现,区区一个 nginx ingress controller 竟然2个不同的实现。一个叫 kubernetes/ingress-nginx ,是由 kubernetes 社区维护的,对应的容器镜像是 <code>quay.io/kubernetes-ingress-controller/nginx-ingress-controller</code> ,namespace 是 <code>ingress-nginx</code> ;一个叫 nginxinc/kubernetes-ingress ,是由 nginx 公司与社区共同维护的,对应的容器镜像是 <code>nginx/nginx-ingress</code> ,namespace 是 <code>nginx-ingress</code> 。</p>
<p>之前我们用的是 <code>nginxinc/kubernetes-ingress</code> (详见之前的博文), 不知道有2个不同的实现,在排查问题时有时查的是<code>kubernetes/ingress-nginx</code> 的资料,南辕北辙,当时还纳闷明明按照文档进行了设置,为什么不起作用呢?</p>
<p>由于使用 <code>nginxinc/kubernetes-ingress</code> 后遭遇 K8s 中 ASP.NET Core 应用获取不到客户端真实 IP 地址 的问题(<code>X-Forwarded-For</code>转发问题),于是被迫见异思迁试试换成 kubernetes/ingress-nginx 作为 nginx ingress controller 。</p>
<p>接下来是 <code>kubernetes/ingress-nginx</code> 的部署步骤。</p>
<p>首先删除之前的 <code>nginxinc/kubernetes-ingress</code> 部署。</p>
<pre><code class="language-bash">kubectl delete all --all -n nginx-ingress
kubectl delete namespace nginx-ingress
</code></pre>
<p>接着从 github 上签出 <code>kubernetes/ingress-nginx</code> 仓库,用其中的 mandatory.yaml 配置文件进行部署。</p>
<pre><code class="language-text">git clone https://github.com/kubernetes/ingress-nginx
cd deploy/static
kubectl apply -f mandatory.yaml
</code></pre>
<p>部署完成后,查看已部署的资源:</p>
<pre><code class="language-bash">$ 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
</code></pre>
<p>还少个 service ,我们这里用 nodePort 的方式部署 service ,于是选用 <code>deploy/static/provider/baremetal/service-nodeport.yaml</code> 部署文件,在其中添加 <code>nodePort: 31080</code> 指定端口。</p>
<pre><code class="language-yaml">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
# ....
</code></pre>
<p>部署 service</p>
<pre><code class="language-bash">kubectl apply -f service-nodeport.yaml
</code></pre>
<p>查看部署结果</p>
<pre><code class="language-bash">$ kubectl get svc -n ingress-nginx      
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.151.144   &lt;none&gt;      80:31080/TCP,443:32428/TCP   9
</code></pre>
<p>登录 worker 节点用 curl 命令验证 nginx 是否正常工作</p>
<pre><code class="language-bash">$ curl -i localhost:31080/healthz
HTTP/1.1 200 OK
Server: nginx/1.17.8
</code></pre>
<p>返回 200 ,说明 nginx OK。</p>
<p>注:<code>kubernetes/ingress-nginx</code> 默认实现了健康检查地址 <code>/healthz</code>,<code>nginxinc/kubernetes-ingress</code> 没有实现,需要自己实现(详见博问)。</p>
<p>登录 nginx-ingress-controller pod ,查看 nginx 配置。</p>
<pre><code class="language-bash">kubectl exec -it deployment/nginx-ingress-controller -n ingress-nginx /bin/bash
</code></pre>
<p>发现 <code>kubernetes/ingress-nginx</code> 中基于 ingress 规则生成的 nginx 配置全都放在 <code>/etc/nginx/nginx.conf</code> 中,而 <code>nginxinc/kubernetes-ingress</code> 是在 <code>/etc/nginx/conf.d/</code> 目录中用一个专门的配置文件存放,文件名以 ingress 所在的命名空间名称开头。</p>
<p>最后是最关键的时刻,验证 <code>kubernetes/ingress-nginx</code> 是否也存在 <code>X-Forwarded-For</code> 转发问题。</p>
<p>在 ConfigMap 中添加启用use-forwarded-headers 。</p>
<pre><code class="language-yaml">data:
use-forwarded-headers: "true"
</code></pre>
<p><code>kubernetes/ingress-nginx</code> 不负众望!没有 <code>X-Forwarded-For</code> 转发问题,应用中可以正常获取到客户端真实 IP 地址。</p>
<p>对比一下两者处理 <code>X-Forwarded-For</code> 的区别。</p>
<p>1)<code>nginxinc/kubernetes-ingress</code> 生成的 nginx 配置是</p>
<pre><code class="language-text">proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
</code></pre>
<p><code>X-Forwarded-For</code> 的值是 <code>"116.62.124.68, 192.168.107.192"</code>。</p>
<p>2)<code>kubernetes/ingress-nginx</code> 生成的 nginx 配置是</p>
<pre><code class="language-text">proxy_set_header X-Forwarded-For $remote_addr;
</code></pre>
<p><code>X-Forwarded-For</code> 的值是 <code>"116.62.124.68"</code>。<code>kubernetes/ingress-nginx</code> 收到的请求是通过阿里云负载均衡转发过来的,客户端真实 IP 地址也是藏在 <code>X-Forwarded-For</code> 中,但它足智多谋,会将 <code>X-Forwarded-For</code> 中的 IP 地址传给 <code>$remote_addr</code> 。</p>
<p>如果在 ConfigMap 中添加下面的配置,<code>kubernetes/ingress-nginx</code> 的表现就和 <code>nginxinc/kubernetes-ingress</code> 一样了。</p>
<pre><code class="language-yaml">data:
compute-full-forwarded-for: "true"
</code></pre>
<p>一次成功的见异思迁,情定 <code>kubernetes/ingress-nginx</code> 。</p><br><br>
来源:https://www.cnblogs.com/dudu/p/12334613.html
頁: [1]
查看完整版本: 见异思迁:K8s 部署 Nginx Ingress Controller 之 kubernetes/ingress-nginx