更新时间:2024-10-14 GMT+08:00

使用Annotation配置Nginx Ingress

CCE的Nginx Ingress插件使用社区模板与镜像,Nginx Ingress默认的其他参数无法满足业务需求时,也可通过添加注解Annotation(注解)的方式自定义参数,例如默认后端、超时时间、请求body体大小等。

本文介绍在创建Nginx类型的Ingress时常用的Annotation。

  • 注解的键值只能是字符串,其他类型(如布尔值或数值)必须使用引号,例如"true"、"false"、"100"。
  • Nginx Ingress支持社区的原生注解,详情请参考Annotations

Ingress类型

表1 Ingress类型注解

参数

类型

描述

支持的集群版本

kubernetes.io/ingress.class

String

  • nginx:表示使用Nginx Ingress。
  • cce:表示使用自研ELB Ingress。

通过API接口创建Ingress时必须增加该参数。

v1.23及以上集群使用ingressClassName参数代替,详情请参见通过Kubectl命令行创建Nginx Ingress

仅v1.21及以下集群

上述注解的使用方法详情请参见通过Kubectl命令行创建Nginx Ingress

对接HTTPS协议的后端服务

表2 对接HTTPS协议的后端服务注解

参数

类型

描述

nginx.ingress.kubernetes.io/backend-protocol

String

参数值为'HTTPS',表示使用HTTPS协议转发请求到后端业务容器。

具体使用场景和说明请参见为Nginx Ingress配置HTTPS协议的后端服务

创建一致性哈希负载均衡规则

表3 一致性哈希负载均衡注解

参数

类型

描述

nginx.ingress.kubernetes.io/upstream-hash-by

String

为后端启用一致性哈希进行负载均衡,参数值支持nginx参数、文本值或任意组合,例如:
  • nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"代表按照请求uri进行hash。
  • nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri$host"代表按照请求uri和域名进行hash。
  • nginx.ingress.kubernetes.io/upstream-hash-by: "${request_uri}-text-value"代表按照请求uri和文本值进行hash。

具体使用场景和说明请参见为Nginx Ingress配置一致性哈希负载均衡

自定义超时时长

表4 自定义超时时长注解

参数

类型

描述

nginx.ingress.kubernetes.io/proxy-connect-timeout

String

自定义连接超时时长,设置超时值时无需填写单位,默认单位为秒。

例如:

nginx.ingress.kubernetes.io/proxy-connect-timeout: '120'

自定义Body体大小

表5 自定义Body体大小注解

参数

类型

描述

nginx.ingress.kubernetes.io/proxy-body-size

String

当请求中的Body体大小超过允许的最大值时,将向客户端返回413错误,您可通过该参数调整Body体的限制大小。该参数值的基本单位为字节,您可以使用k、m、g等参数单位,换算关系如下:

1g=1024m;1m=1024k;1k=1024字节

例如:

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

HTTPS双向认证

Nginx Ingress支持配置服务器与客户端之间的双向HTTPS认证来保证连接的安全性。

  1. 请参见通过kubectl连接集群,使用kubectl连接集群。
  2. 执行以下命令,创建自签名的CA证书。

    openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=Ingress Cert Authority'

    预期输出:

    Generating a RSA private key
    .............++++
    ................................................++++
    writing new private key to 'ca.key'
    -----

  3. 执行以下命令,创建Server端证书。

    1. 执行以下命令,生成Server端证书的请求文件。
      openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=foo.bar.com'

      预期输出:

      Generating a RSA private key
      .....................................................++++
      ..........++++
      writing new private key to 'server.key'
      -----
    2. 执行以下命令,使用根证书签发Server端请求文件,生成Server端证书。
      openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

      预期输出:

      Signature ok
      subject=CN = foo.bar.com
      Getting CA Private Key

  4. 执行以下命令,生成Client端证书。

    1. 执行以下命令,生成Client端证书的请求文件。
      openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Ingress'

      预期输出:

      Generating a RSA private key
      .................................++++
      ................................................++++
      writing new private key to 'client.key'
      -----
    2. 执行以下命令,使用根证书签发Client端请求文件,生成Client端证书。
      openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt

      预期输出:

      Signature ok
      subject=CN = Ingress
      Getting CA Private Key

  5. 执行ls命令,查看创建的证书。

    预期输出:

    ca.crt  ca.key  client.crt  client.csr  client.key  server.crt  server.csr  server.key

  6. 执行以下命令,生成CA证书的Secret。

    kubectl create secret generic ca-secret --from-file=ca.crt=ca.crt

    预期输出:

    secret/ca-secret created

  7. 执行以下命令,生成Server端证书的Secret。

    kubectl create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key

    预期输出:

    secret/tls-secret created

  8. 创建名为“ingress-test.yaml”的YAML文件,此处文件名可自定义。

    vi ingress-test.yaml

    • 1.23及以上版本集群
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
          nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret"   #替换您的CA证书密钥
          nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
          nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
        name: ingress-test
        namespace: default
      spec:
        rules:
        - host: foo.bar.com
          http:
            paths:
            - backend:
                service:
                  name: nginx-test  #替换为您的目标服务名称
                  port: 
                    number: 80  #替换为您的目标服务端口
              path: /
              pathType: ImplementationSpecific
        tls:
        - hosts:
          - foo.bar.com
          secretName: tls-secret   #替换您的TLS证书密钥
        ingressClassName: nginx
    • 1.21及以下版本集群
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress 
      metadata: 
        annotations: 
          kubernetes.io/ingress.class: nginx
          nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
          nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret"   #替换您的CA证书密钥
          nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
          nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
        name: ingress-test
        namespace: default
      spec:
        rules: 
        - host: foo.bar.com
          http: 
            paths: 
            - path: '/'
              backend: 
                serviceName: nginx-test  #替换为您的目标服务名称
                servicePort: 80  #替换为您的目标服务端口
        tls: 
        - hosts: 
          - foo.bar.com
          secretName: tls-secret   #替换为您的TLS密钥证书

  9. 执行以下命令,创建Ingress。

    kubectl create -f ingress-test.yaml

    预期输出:

    ingress.networking.k8s.io/ingress-test created

  10. 执行以下命令,查看Ingress的IP地址。

    kubectl get ingress

    预期输出:

    NAME         CLASS   HOSTS         ADDRESS      PORTS     AGE
    nginx-test   nginx   foo.bar.com   10.3.xx.xx   80, 443   27m

  11. 执行以下命令,将Ingress的IP地址更新到Hosts文件中,替换下面的IP地址为真实获取的Ingress的IP地址

    echo "10.3.xx.xx  foo.bar.com" | sudo tee -a /etc/hosts

    预期输出:

    10.3.xx.xx  foo.bar.com

  12. 结果验证。

    • 客户端不传证书访问
      curl --cacert ./ca.crt  https://foo.bar.com

      预期输出:

      <html>
      <head><title>400 No required SSL certificate was sent</title></head>
      <body>
      <center><h1>400 Bad Request</h1></center>
      <center>No required SSL certificate was sent</center>
      <hr><center>nginx</center>
      </body>
      </html>
    • 客户端传证书访问
      curl --cacert ./ca.crt --cert ./client.crt --key ./client.key https://foo.bar.com

      预期输出:

      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
      <style>
      body {
          width: 35em;
          margin: 0 auto;
          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 and
      working. Further configuration is required.</p>
       
      <p>For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br/>
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.</p>
       
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>

域名正则化

Nginx Ingress支持配置“nginx.ingress.kubernetes.io/server-alias”注解实现域名配置正则表达式。

  1. 请参见通过kubectl连接集群,使用kubectl连接集群。
  2. 创建名为“ingress-test.yaml”的YAML文件,此处文件名可自定义。

    vi ingress-test.yaml

    以正则表达式~^www\.\d+\.example\.com$,abc.example.com为例,表示使用www.{一个或多个数字}.example.com和abc.example.com域名也可正常访问Ingress。

    • 1.23及以上版本集群
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          nginx.ingress.kubernetes.io/server-alias: '~^www\.\d+\.example\.com$,abc.example.com'
        name: ingress-test
        namespace: default
      spec:
        rules:
        - host: foo.bar.com
          http:
            paths:
            - backend:
                service:
                  name: nginx-93244  #替换为您的目标服务名称
                  port: 
                    number: 80  #替换为您的目标服务端口
              path: /
              pathType: ImplementationSpecific
        ingressClassName: nginx
    • 1.21及以下版本集群
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress 
      metadata: 
        annotations: 
          kubernetes.io/ingress.class: nginx
          nginx.ingress.kubernetes.io/ server-alias: '~^www\.\d+\.example\.com$,abc.example.com'
        name: ingress-test
        namespace: default
      spec:
        rules: 
        - host: foo.bar.com
          http: 
            paths: 
            - path: '/'
              backend: 
                serviceName: nginx-test  #替换为您的目标服务名称
                servicePort: 80  #替换为您的目标服务端口

  3. 执行以下命令,创建Ingress。

    kubectl create -f ingress-test.yaml

    预期输出:

    ingress.networking.k8s.io/ingress-test created

  4. 查看Nginx Ingress Controller的配置。

    1. 执行以下命令,查看Nginx Ingress Controller服务的Pod
      kubectl get pods -n kube-system | grep nginx-ingress-controller

      预期输出:

      cceaddon-nginx-ingress-controller-68d7bcc67-dxxxx        1/1     Running   0          18h
      cceaddon-nginx-ingress-controller-68d7bcc67-cxxxx        1/1     Running   0          18h
    2. 执行以下命令,查看Nginx Ingress Controller的配置
      kubectl exec -n kube-system cceaddon-nginx-ingress-controller-68d7bcc67-dxxxx cat /etc/nginx/nginx.conf | grep -C3 "foo.bar.com"

      预期输出:

               ## start server foo.bar.com
               server {
                        server_name foo.bar.com abc.example.com ~^www\.\d+\.example\.com$ ;
                        
                        listen 80  ;
                        listen [::]:80  ;
      --
                        }
                        
               }
               ## end server foo.bar.com

  5. 执行以下命令,获取Ingress对应的IP。

    kubectl get ingress

    预期输出:

    NAME         CLASS   HOSTS         ADDRESS      PORTS   AGE
    nginx-test   nginx   foo.bar.com   10.3.xx.xx   80      14m

  6. 执行以下命令,测试不同规则下的服务访问。

    • 执行以下命令,通过Host: foo.bar.com访问服务。
      curl -H "Host: foo.bar.com" 10.3.xx.xx/

      预期可正常访问网页。

    • 执行以下命令,通过Host: www.123.example.com访问服务
      curl -H "Host: www.123.example.com" 10.3.xx.xx/

      预期可正常访问网页。

    • 执行以下命令,通过Host: www.321.example.com访问服务
      curl -H "Host: www.321.example.com" 10.3.xx.xx/

      预期可正常访问网页。

相关文档

更多关于Nginx Ingress支持的注解参数,请参见Annotations