Ingress-nginx annotations 进阶功能使用(五)

Kubernetes / 2022-12-20

常用ingress配置

access log

  annotations:
     nginx.ingress.kubernetes.io/enable-access-log: "false"

nginx ingress 默认是开启access log的,如果你想关闭,可以通过将 nginx.ingress.kubernetes.io/enable-access-log 设置成false。

默认服务

  annotations:
     nginx.ingress.kubernetes.io/default-backend: 

当客户端请求一个不存在的path的时候,我们不希望返回 404 ,跳转到一个默认的服务上。

允许最大body

  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 8m

这个主要是针对外部请求,防止将流量打满,proxy-body-size 设置最大请求 body,如果超过则会返回 413 请求错误。

限流

  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "5"
    nginx.ingress.kubernetes.io/limit-rpm: "300"
    nginx.ingress.kubernetes.io/limit-connections: "10"

通过 rps 限制每秒请求数,rpm 限制每分钟请求数,connections限制连接数。

跨域访问

  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, X-app123-XPTO"
    nginx.ingress.kubernetes.io/cors-expose-headers: "*, X-CustomResponseHeader"
    nginx.ingress.kubernetes.io/cors-max-age: 600
    nginx.ingress.kubernetes.io/cors-allow-credentials: "false"

我们经常将nginx作为api的网关,支持跨域必不可少。通过 nginx.ingress.kubernetes.io/cors-allow-methods 设置支持跨域请求的方法。

请求超时

  annotations:
    nginx.org/proxy-connect-timeout: "30s"
    nginx.org/proxy-read-timeout: "20s"

nginx.org/proxy-connect-timeout 和nginx.org/proxy-read-timeout 这两个参数分别设置nginx的建立连接以及等待结果的超时时间。

强制https

  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/preserve-trailing-slash: "true"

nginx.ingress.kubernetes.io/force-ssl-redirect: "true"通过这个annotation可以强制 https,如果是http请求,会通过 301 redirect到 https

https

apiVersion: v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"   # 禁用https强制跳转
  generation: 1
  name: test-tls
  namespace: ratel-test1
spec:
  rules:
  - host: test-tls.test.com
    http:
      paths:
      - backend:
          serviceName: ingress-test
          servicePort: 80
        path: /
  tls:
  - hosts:
    - test-tls.test.com
    secretName: ca-cert
设置默认证书:--default-ssl-certificate=default/foo-tls
更改的ingress-controller的启动参数

Redirect域名重定向

    annotations:
      nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com   # 重定向到想去的url

Rewrite前后端分离

apiVersion: v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  generation: 4
  name: ingress-test
  namespace: ratel-test1
spec:
  rules:
  - host: rewrite.test.com
    http:
      paths:
      - backend:
          serviceName: ingress-test
          servicePort: 80
        path: /something(/|$)(.*)   #($1)($2)

黑白名单

黑名单:拒绝某段IP访问

**白名单:**只允许某段IP访问

Annotations:只对指定的ingress生效

ConfigMap:全局生效

黑名单可以使用ConfigMap去配置,白名单建议使用Annotations去配置

白名单配置

annotations:
  nginx.ingress.kubernetes.io/whitelist-source-range 10.0.0.0/24,172.10.0.1

黑名单设置(建议使用ConfigMap)(全局生效)

kubectl edit  cm -n ingress-nginx ingress-nginx-controller -oyaml

---
apiVersion: v1
data:                          # 加上data
  block-cidrs: 192.168.1.201   # 黑名单
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: ingress-nginx
    meta.helm.sh/release-namespace: ingress-nginx
...

kubectl delete po -n ingress-nginx --all

针对某个域名设置黑名单–snippet

# 比如ingress代理了www.test.com这个域名,那么想针对这个域名(www.test.com)设置访问黑名单,就编辑这个ingress即可
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  # 在annotations下面加上这几行配置,有多个IP可以deny多个
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |-    
      deny 192.168.1.101;
      deny 192.168.1.102;
      allow all;
# 然后在deny的主机上访问 www.test.com 就403
[root@k8s-master02 ~]# curl ngdemo.qikqiak.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

匹配请求头设置

annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
        set $agentflag 0;

        if ($http_user_agent ~* "(iPhone)" ){   # 匹配规则设置(设置匹配为iPhone的手机,则重定向到下面的url)
          set $agentflag 1;
        }

        if ( $agentflag = 1 ) {
          return 301 https://www.baidu.com;     # 重定向到指定的url
        }

ingress-nginx基本认证(Basic Auth)

在 Ingress Controller 上面配置基本的 Auth 认证,如 Basic Auth,用 htpasswd 生成一个密码文件来验证身份验证。

[root@k8s-master01 ~]# htpasswd -c auth foo   # 账号foo   密码 123456   
New password:              # 123456
Re-type new password:      # 123456
Adding password for user foo

# 生成一个auth文件

根据上面的 auth 文件创建一个 secret 对象:

kubectl create secret generic basic-auth --from-file=auth

对上面的 my-nginx 应用创建一个具有 Basic Auth 的 Ingress 对象:

  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic    # 认证类型
    nginx.ingress.kubernetes.io/auth-secret: basic-auth   # 包含 user/password 定义的 secret 对象名
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required' # 提示文本

不带用户名和密码进行认证:

➜ curl -v http://k8s.qikqiak.com -H 'Host: foo.bar.com'
...
< HTTP/1.1 401 Unauthorized
< Server: openresty/1.15.8.2
< Date: Sun, 08 Dec 2019 06:44:35 GMT
< Content-Type: text/html
< Content-Length: 185
< Connection: keep-alive
< WWW-Authenticate: Basic realm="Authentication Required"
...

带上用户名和密码进行认证:

➜ curl -v http://k8s.qikqiak.com -H 'Host: foo.bar.com' -u 'foo:foo'
...
< HTTP/1.1 200 OK
< Server: openresty/1.15.8.2
< Date: Sun, 08 Dec 2019 06:46:27 GMT
< Content-Type: text/html
< Content-Length: 612
< Connection: keep-alive
< Vary: Accept-Encoding
< Last-Modified: Tue, 19 Nov 2019 12:50:08 GMT
< ETag: "5dd3e500-264"
< Accept-Ranges: bytes
...