网站数据概况

0最近活跃访客

18今日访问人数

488今日访问量

11昨日访问人数

849昨日访问量

1,337本月访问量

1,337总访问量


公告

微信 👇

QR Code

全网最美博客-teek(知识库&博客二合一) --正在持续迭代,欢迎大家尝鲜及提出新需求,共同打造一个完美的作品。

Skip to content
1

Ingress-nginx

Ingress-nginx

image-20230307212336426

目录

[toc]

原文链接

https:NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEingress-nginx-controllerLoadBalancer10.97.111.207172.29.9.6180:30970/TCP,443:32364/TCP23h[root@master1 ~]#kubectl get cm -ningress-nginxNAMEDATAAGEingress-nginx-controller123hkube-root-ca.crt123h[root@master1 ~]#kubectl get cm ingress-nginx-controller -ningress-nginx -oyamlapiVersion:v1data:allow-snippet-annotations:"true"kind:ConfigMapmetadata:annotations:kubectl.kubernetes.io/last-applied-configuration:|{"apiVersion":"v1","data":{"allow-snippet-annotations":"true"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"controller","app.kubernetes.io/instance":"ingress-nginx","app.kubernetes.io/name":"ingress-nginx","app.kubernetes.io/part-of":"ingress-nginx","app.kubernetes.io/version":"1.5.1"},"name":"ingress-nginx-controller","namespace":"ingress-nginx"}} creationTimestamp:"2023-03-06T22:59:36Z"labels:app.kubernetes.io/component:controllerapp.kubernetes.io/instance:ingress-nginxapp.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginxapp.kubernetes.io/version:1.5.1name:ingress-nginx-controllernamespace:ingress-nginxresourceVersion:"177720"uid:7692a932-ce9a-40d0-8df2-988e4eb0aa31[root@master1 ~]#

1、Basic Auth

1.在 Ingress 对象上配置Basic Auth

==💘 实战:在 Ingress 对象上配置Basic Auth-2023.3.12(测试成功)==

image-20230312222814393

  • 实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:v1.5.5
  • 实验软件

链接:https:apiVersion:apps/v1kind:Deploymentmetadata:name:nginxspec:selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:- name:nginximage:nginxports:- containerPort:80---apiVersion:v1kind:Servicemetadata:name:nginxspec:ports:- port:80protocol:TCPname:httpselector:app:nginx

部署并观察:

我们可以看到出现了 401 认证失败错误。

可以看到已经认证成功了。

浏览器测试效果:是ok的,符合预期。

image-20230312222449174

image-20230312222453622

⚠️ 注意:nginx.ingress.kubernetes.io/auth-realm:"Authentication Required - foo"参数的含义

这里以密码写错为例举例:

image-20230312222956281

image-20230312222926735

测试结束。😘

2.使用外部的 Basic Auth 认证信息

==💘 实战:使用外部的 Basic Auth 认证信息-2023.3.12(测试成功)==

image-20230312231033548

  • 实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:v1.5.5
  • 实验软件

链接:https:apiVersion:apps/v1kind:Deploymentmetadata:name:nginxspec:selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:- name:nginximage:nginxports:- containerPort:80---apiVersion:v1kind:Servicemetadata:name:nginxspec:ports:- port:80protocol:TCPname:httpselector:app:nginx

部署并观察:

我们可以看到出现了 401 认证失败错误。

可以看到已经认证成功了。

浏览器测试效果:是ok的,符合预期。

image-20230312230547046

image-20230312230551580

测试结束。😘

当然除了 Basic Auth 这一种简单的认证方式之外,ingress-nginx还支持一些其他高级的认证,比如我们可以使用 GitHub OAuth 来认证 Kubernetes 的 Dashboard

2、URL Rewrite

可能平常用的最多的是这个功能。

ingress-nginx很多高级的用法可以通过 Ingress 对象的 annotation进行配置,比如常用的 URL Rewrite 功能。**很多时候我们会将 **ingress-nginx当成网关使用,比如对访问的服务加上 /app这样的前缀,在 nginx的配置里面我们知道有一个 proxy_pass指令可以实现:

bash
location/app/{proxy_passhttp:}

可能要加上/app,或者/gateway,/api,特别是在我们微服务里,我们很多时候要把我们的微服务提供的一些接口给它聚合在某一个子路径下面去,比如果/api.或者/api/v1下面,当然这些功能我们可以直接在网关层ingress这里实现这样的功能。

proxy_pass后面加了 /remote这个路径,此时会将匹配到该规则路径中的 /app/remote替换掉,相当于截掉路径中的 /app。同样的在 Kubernetes 中使用 ingress-nginx又该如何来实现呢?我们可以使用 rewrite-target的注解**来实现这个需求。比如现在我们想要通过 rewrite.172.29.9.60.nip.io/gateway/来访问到 Nginx 服务,则我们需要对访问的 URL 路径做一个 Rewrite,**在 PATH 中添加一个 gateway 的前缀。

关于 Rewrite 的操作在 ingress-nginx 官方文档中也给出对应的说明:

==💘 实战:Ingress-nginx之URL Rewrite-2023.3.13(测试成功)==

image-20230313072513167

  • 实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:v1.5.5
  • 实验软件

链接:https:apiVersion:apps/v1kind:Deploymentmetadata:name:nginxspec:selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:- name:nginximage:nginxports:- containerPort:80---apiVersion:v1kind:Servicemetadata:name:nginxspec:ports:- port:80protocol:TCPname:httpselector:app:nginx

部署并观察:

以下3个小测试都是基于这个实战的哦。😘

1.rewrite-target

  • 首先先按我们的想法来测试下
yaml
# ingress-nginx-url-rewrite.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-nginx-url-rewritenamespace:defaultspec:ingressClassName:nginx# 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)rules:- host:rewrite.172.29.9.60.nip.io# 将域名映射到 nginx 服务,注意,这里的ip是ingress-controller svc的EXTERNAL-IP,rewrite.172.29.9.60.nip.io/gateway -->nginxhttp:paths:- path:/gatewaypathType:Prefixbackend:service:# 将所有请求发送到 nginx 服务的 80 端口name:nginxport:number:80
  • 部署并测试:
bash
[root@master1 url-rewirte]#kubectl apply -f ingress-nginx-url-rewrite.yamlingress.networking.k8s.io/ingress-nginx-url-rewritecreated[root@master1 url-rewirte]#kubectl get ingressNAMECLASSHOSTSADDRESSPORTSAGEingress-nginx-url-rewritenginxrewrite.172.29.9.60.nip.io172.29.9.608019s#测试[root@master1 url-rewirte]#curl -v rewrite.172.29.9.60.nip.io*About to connect() to rewrite.172.29.9.60.nip.io port 80 (#0)*Trying172.29.9.60...*Connected to rewrite.172.29.9.60.nip.io (172.29.9.60) port 80 (#0)>GET/HTTP/1.1>User-Agent:curl/7.29.0>Host:rewrite.172.29.9.60.nip.io>Accept:*/*><HTTP/1.1 404 Not Found<Date:Sun,12 Mar 2023 22:16:34 GMT<Content-Type:text/html<Content-Length:146<Connection:keep-alive<<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx</center></body></html>*Connection #0 to host rewrite.172.29.9.60.nip.io left intact[root@master1 url-rewirte]#curl -v rewrite.172.29.9.60.nip.io/gateway*About to connect() to rewrite.172.29.9.60.nip.io port 80 (#0)*Trying172.29.9.60...*Connected to rewrite.172.29.9.60.nip.io (172.29.9.60) port 80 (#0)>GET/gatewayHTTP/1.1>User-Agent:curl/7.29.0>Host:rewrite.172.29.9.60.nip.io>Accept:*/*><HTTP/1.1 404 Not Found<Date:Sun,12 Mar 2023 22:16:48 GMT<Content-Type:text/html<Content-Length:153<Connection:keep-alive<<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.21.5</center></body></html>*Connection #0 to host rewrite.172.29.9.60.nip.io left intact

可以看到2种方式都是无法访问的。

  • 我们再次改写yaml
yaml
# ingress-nginx-url-rewrite.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-nginx-url-rewritenamespace:defaultannotations:nginx.ingress.kubernetes.io/rewrite-target:/$2spec:ingressClassName:nginx# 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)rules:- host:rewrite.172.29.9.60.nip.io# 将域名映射到 nginx 服务,注意,这里的ip是ingress-controller svc的EXTERNAL-IP,rewrite.172.29.9.60.nip.io/gateway -->nginx#包括如下几种情况#rewrite.172.29.9.60.nip.io/gateway/ rewrite.172.29.9.60.nip.io/gateway rewrite.172.29.9.60.nip.io/gateway/xxxhttp:paths:- path:/gateway(/|$)(.*)pathType:Prefixbackend:service:# 将所有请求发送到 nginx 服务的 80 端口name:nginxport:number:80

特别注意这里的正则表达式。

分为以下这3种情况:

rewrite.172.29.9.60.nip.io/gateway/ rewrite.172.29.9.60.nip.io/gateway rewrite.172.29.9.60.nip.io/gateway/xxx

$表示结尾

image-20230313063914251

  • 更新后,我们可以预见到直接访问域名肯定是不行了,因为我们没有匹配 / 的 path 路径:
bash
[root@master1 url-rewirte]#curl rewrite.172.29.9.60.nip.io<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx</center></body></html>
  • 但是我们带上 gateway 的前缀再去访问就正常了:
bash
[root@master1 url-rewirte]#curl rewrite.172.29.9.60.nip.io/gateway<!DOCTYPEhtml><html><head><title>Welcome to nginx!</title><style>html{color-scheme:lightdark;}body{width:35em;margin:0auto;font-family:Tahoma,Verdana,Arial,sans-serif;}</style></head><body><h1>Welcome to nginx!</h1><p>If you see this page,the nginx web server is successfully installed andworking.Furtherconfigurationisrequired.</p><p>For online documentation and support please refer to<a href="http:Commercialsupportisavailableat<a href="http:<p><em>Thank you forusing nginx.</em></p></body></html>[root@master1 url-rewirte]#curl rewrite.172.29.9.60.nip.io/gateway/<!DOCTYPEhtml><html><head><title>Welcome to nginx!</title><style>html{color-scheme:lightdark;}body{width:35em;margin:0auto;font-family:Tahoma,Verdana,Arial,sans-serif;}</style></head><body><h1>Welcome to nginx!</h1><p>If you see this page,the nginx web server is successfully installed andworking.Furtherconfigurationisrequired.</p><p>For online documentation and support please refer to<a href="http:Commercialsupportisavailableat<a href="http:<p><em>Thank you forusing nginx.</em></p></body></html>[root@master1 url-rewirte]#

我们可以看到已经可以访问到了,这是因为我们在 path 中通过正则表达式 /gateway(/|$)(.*)将匹配的路径设置成了 rewrite-target 的目标路径了,所以我们访问 rewrite.172.29.9.60.nip.io/gateway 的时候实际上相当于访问的就是后端服务的 / 路径。

2.app-root

解决我们访问主域名出现 404 的问题。

要解决我们访问主域名出现 404 的问题,我们可以给应用设置一个 app-root的注解,这样当我们访问主域名的时候会自动跳转到我们指定的 app-root目录下面,如下所示:

image-20230313070217099

  • 这里在rewrite.yaml配置文件上进行更改:
yaml
# ingress-nginx-url-rewrite.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-nginx-url-rewritenamespace:defaultannotations:nginx.ingress.kubernetes.io/rewrite-target:/$2nginx.ingress.kubernetes.io/app-root:/gateway/#注意。spec:ingressClassName:nginx# 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)rules:- host:rewrite.172.29.9.60.nip.io# 将域名映射到 nginx 服务,注意,这里的ip是ingress-controller svc的EXTERNAL-IP,rewrite.172.29.9.60.nip.io/gateway -->nginx#包括如下几种情况#rewrite.172.29.9.60.nip.io/gateway/ rewrite.172.29.9.60.nip.io/gateway rewrite.172.29.9.60.nip.io/gateway/xxxhttp:paths:- path:/gateway(/|$)(.*)pathType:Prefixbackend:service:# 将所有请求发送到 nginx 服务的 80 端口name:nginxport:number:80
  • 这个时候我们更新应用后访问主域名 rewrite.172.29.9.60.nip.io就会自动跳转到rewrite.172.29.9.60.nip.io/gateway/ 路径下面去了。
bash
#部署[root@master1 url-rewirte]#kubectl apply -f ingress-nginx-url-rewrite.yamlingress.networking.k8s.io/ingress-nginx-url-rewriteconfigured[root@master1 url-rewirte]#kubectl get ingressNAMECLASSHOSTSADDRESSPORTSAGEingress-nginx-url-rewritenginxrewrite.172.29.9.60.nip.io172.29.9.608037m#测试[root@master1 url-rewirte]#curl -v rewrite.172.29.9.60.nip.io*About to connect() to rewrite.172.29.9.60.nip.io port 80 (#0)*Trying172.29.9.60...*Connected to rewrite.172.29.9.60.nip.io (172.29.9.60) port 80 (#0)>GET/HTTP/1.1>User-Agent:curl/7.29.0>Host:rewrite.172.29.9.60.nip.io>Accept:*/*><HTTP/1.1 302 Moved Temporarily #可以看到,这里出现了302<Date:Sun,12 Mar 2023 22:53:54 GMT<Content-Type:text/html<Content-Length:138<Connection:keep-alive<Location:http:<<html><head><title>302 Found</title></head><body><center><h1>302 Found</h1></center><hr><center>nginx</center></body></html>*Connection #0 to host rewrite.172.29.9.60.nip.io left intact[root@master1 url-rewirte]#curl rewrite.172.29.9.60.nip.io<html><head><title>302 Found</title></head><body><center><h1>302 Found</h1></center><hr><center>nginx</center></body></html>

⚠️ 注意:这里通过命令行测试好像无法明确看到现象,这里在web浏览器里测试下。

打开一个无痕浏览器,输入rewrite.172.29.9.60.nip.io

image-20230313070128420

image-20230313070140032

这个时候我们更新应用后访问主域名 rewrite.172.29.9.60.nip.io就会自动跳转到rewrite.172.29.9.60.nip.io/gateway/ 路径下面去了。符合预期,

3.configuration-snippet

(希望我们的应用在最后添加一个 /这样的 slash)

  • 但是还有一个问题是我们的 path 路径其实也匹配了 /app这样的路径,可能我们更加希望我们的应用在最后添加一个 /这样的 slash,同样我们可以通过 configuration-snippet配置来完成,如下 Ingress 对象:

这个是和搜索引擎seo有关。

yaml
# ingress-nginx-url-rewrite.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingress-nginx-url-rewritenamespace:defaultannotations:nginx.ingress.kubernetes.io/rewrite-target:/$2nginx.ingress.kubernetes.io/app-root:/gateway/#注意。nginx.ingress.kubernetes.io/configuration-snippet:|rewrite ^(/gateway)$ $1/ redirect;spec:ingressClassName:nginx# 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)rules:- host:rewrite.172.29.9.60.nip.io# 将域名映射到 nginx 服务,注意,这里的ip是ingress-controller svc的EXTERNAL-IP,rewrite.172.29.9.60.nip.io/gateway -->nginx#包括如下几种情况#rewrite.172.29.9.60.nip.io/gateway/ rewrite.172.29.9.60.nip.io/gateway rewrite.172.29.9.60.nip.io/gateway/xxxhttp:paths:- path:/gateway(/|$)(.*)pathType:Prefixbackend:service:# 将所有请求发送到 nginx 服务的 80 端口name:nginxport:number:80
  • 更新后我们的应用就都会以 / 这样的 slash 结尾了,这样就完成了我们的需求,如果你原本对 nginx 的配置就非常熟悉的话应该可以很快就能理解这种配置方式了。
bash
#部署[root@master1 url-rewirte]#kubectl apply -f ingress-nginx-url-rewrite.yamlingress.networking.k8s.io/ingress-nginx-url-rewriteconfigured[root@master1 url-rewirte]#kubectl get ingressNAMECLASSHOSTSADDRESSPORTSAGEhingress-nginx-url-rewritenginxrewrite.172.29.9.60.nip.io172.29.9.608062m#测试[root@master1 url-rewirte]#curl -v rewrite.172.29.9.60.nip.io/gateway*About to connect() to rewrite.172.29.9.60.nip.io port 80 (#0)*Trying172.29.9.60...*Connected to rewrite.172.29.9.60.nip.io (172.29.9.60) port 80 (#0)>GET/gatewayHTTP/1.1>User-Agent:curl/7.29.0>Host:rewrite.172.29.9.60.nip.io>Accept:*/*><HTTP/1.1 302 Moved Temporarily<Date:Sun,12 Mar 2023 23:19:18 GMT<Content-Type:text/html<Content-Length:138<Location:http:<Connection:keep-alive<<html><head><title>302 Found</title></head><body><center><h1>302 Found</h1></center><hr><center>nginx</center></body></html>*Connection #0 to host rewrite.172.29.9.60.nip.io left intact[root@master1 url-rewirte]#curl -v rewrite.172.29.9.60.nip.io/gateway/*About to connect() to rewrite.172.29.9.60.nip.io port 80 (#0)*Trying172.29.9.60...*Connected to rewrite.172.29.9.60.nip.io (172.29.9.60) port 80 (#0)>GET/gateway/HTTP/1.1>User-Agent:curl/7.29.0>Host:rewrite.172.29.9.60.nip.io>Accept:*/*><HTTP/1.1 200 OK<Date:Sun,12 Mar 2023 23:19:22 GMT<Content-Type:text/html<Content-Length:615<Connection:keep-alive<Last-Modified:Tue,28 Dec 2021 15:28:38 GMT<ETag:"61cb2d26-267"<Accept-Ranges:bytes<<!DOCTYPEhtml><html><head><title>Welcome to nginx!</title><style>html{color-scheme:lightdark;}body{width:35em;margin:0auto;font-family:Tahoma,Verdana,Arial,sans-serif;}</style></head><body><h1>Welcome to nginx!</h1><p>If you see this page,the nginx web server is successfully installed andworking.Furtherconfigurationisrequired.</p><p>For online documentation and support please refer to<a href="http:Commercialsupportisavailableat<a href="http:<p><em>Thank you forusing nginx.</em></p></body></html>*Connection #0 to host rewrite.172.29.9.60.nip.io left intact[root@master1 url-rewirte]#

image-20230313072025006

image-20230313072036152

符合预期,测试结束。😘

3、灰度发布

在日常工作中我们经常需要对服务进行版本更新升级,所以我们经常会使用到滚动升级、蓝绿发布、灰度发布等不同的发布操作。而 ingress-nginx支持通过 Annotations 配置来实现不同场景下的灰度发布和测试,可以满足金丝雀发布、蓝绿部署与 A/B 测试等业务场景。

ingress-nginx 的 Annotations支持以下 4 种 Canary(金丝雀) 规则:

我不知道我们线上会不会真正用这个ingress-nginx的annotations去做一个灰度,毕竟anotations它的这个配置方式其实不是特别云原生。一般来说,如果可以把他翻译成我们的CRD之类的,可能我们写起来就会方便一点的,目前来说,它是通过我们这个annotations方式来配置的。

  • nginx.ingress.kubernetes.io/canary-by-header:基于 Request Header 的流量切分,适用于灰度发布以及 A/B 测试。当 Request Header 设置为 always 时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never 时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。
  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (canary-by-header) 一起使用。
  • nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求,权重为 100 意味着所有请求都将被发送到 Canary 入口。
  • nginx.ingress.kubernetes.io/canary-by-cookie:基于 cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always 时,它将被路由到 Canary 入口;当 cookie 值设置为 never 时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。

需要注意的是金丝雀规则按优先顺序进行排序:canary-by-header >canary-by-cookie >canary-weight

总的来说可以把以上的四个 annotation 规则划分为以下两类:

  • 基于权重的 Canary 规则

  • 基于用户请求的 Canary 规则

下面我们通过一个示例应用来对灰度发布功能进行说明。

==💘 实战:Ingress-nginx之灰度发布-2023.3.14(测试成功)==

image-20230314064055405

  • 步骤划分:
bash
第1步:部署Production应用第2步:创建Canary版本第3步:Annotation规则配置1.基于权重2.基于RequestHeader3.基于Cookie
  • 实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:v1.5.5
  • 实验软件

链接:https:NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEingress-nginx-controllerLoadBalancer10.108.58.246172.29.9.6080:32439/TCP,443:31347/TCP2d15hingress-nginx-controller-admissionClusterIP10.101.184.28<none>443/TCP2d15h

第1步:部署 Production 应用

⚠️ 注意:这里的镜像也可以是如下官方的

# arm架构使用该镜像:mirrorgooglecontainers/echoserver-arm:1.8

image:mirrorgooglecontainers/echoserver:1.10

这个镜像作用是打印pod的一些信息的。