用于配置Nginx Ingress的注解(Annotations)
CCE的Nginx Ingress插件使用社区模板与镜像,Nginx Ingress默认的其他参数无法满足业务需求时,也可通过添加注解Annotation(注解)的方式自定义参数,例如默认后端、超时时间、请求body体大小等。
本文介绍在创建Nginx类型的Ingress时常用的Annotation。
- 注解的键值只能是字符串,其他类型(如布尔值或数值)必须使用引号,例如"true"、"false"、"100"。
- Nginx Ingress支持社区的原生注解,详情请参考Annotations。
- Ingress类型
- 配置重定向规则
- 配置URL重写规则
- 对接HTTPS协议的后端服务
- 创建一致性哈希负载均衡规则
- 自定义超时时长
- 自定义Body体大小
- HTTPS双向认证
- 域名正则化
- 灰度发布
- 相关文档
Ingress类型
参数 |
类型 |
描述 |
支持的集群版本 |
---|---|---|---|
kubernetes.io/ingress.class |
String |
通过API接口创建Ingress时必须增加该参数。 v1.23及以上集群使用ingressClassName参数代替,详情请参见通过Kubectl命令行创建Nginx Ingress。 |
仅v1.21及以下集群 |
上述注解的使用方法详情请参见通过Kubectl命令行创建Nginx Ingress。
配置重定向规则
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/permanent-redirect |
String |
将访问请求永久重定向至某个目标网址(状态码为301)。 |
nginx.ingress.kubernetes.io/permanent-redirect-code |
String |
修改永久重定向的返回状态码为指定值。 |
nginx.ingress.kubernetes.io/temporal-redirect |
String |
将访问请求临时重定向至某个目标网址(状态码为302)。 |
nginx.ingress.kubernetes.io/ssl-redirect |
String |
是否只能通过SSL访问(当Ingress包含证书时默认为true),将HTTP请求重定向至HTTPS。 |
nginx.ingress.kubernetes.io/force-ssl-redirect |
String |
是否强制重定向到HTTPS,即使Ingress未启用TLS,通过HTTP访问时,请求将会被强制重定向(状态码为308)到HTTPS。 |
具体使用场景和说明请参见为Nginx Ingress配置重定向规则。
配置URL重写规则
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/rewrite-target |
String |
重定向流量的目标URI。 |
具体使用场景和说明请参见为Nginx Ingress配置URL重写规则。
对接HTTPS协议的后端服务
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/backend-protocol |
String |
参数值为'HTTPS',表示使用HTTPS协议转发请求到后端业务容器。 |
具体使用场景和说明请参见为Nginx Ingress配置HTTPS协议的后端服务。
创建一致性哈希负载均衡规则
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/upstream-hash-by |
String |
为后端启用一致性哈希进行负载均衡,参数值支持nginx参数、文本值或任意组合,例如:
|
具体使用场景和说明请参见为Nginx Ingress配置一致性哈希负载均衡。
自定义超时时长
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/proxy-connect-timeout |
String |
自定义连接超时时长,设置超时值时无需填写单位,默认单位为秒。 例如: nginx.ingress.kubernetes.io/proxy-connect-timeout: '120' |
自定义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认证来保证连接的安全性。
- 请参见通过kubectl连接集群,使用kubectl连接集群。
- 执行以下命令,创建自签名的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' -----
- 执行以下命令,创建Server端证书。
- 执行以下命令,生成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' -----
- 执行以下命令,使用根证书签发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
- 执行以下命令,生成Server端证书的请求文件。
- 执行以下命令,生成Client端证书。
- 执行以下命令,生成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' -----
- 执行以下命令,使用根证书签发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
- 执行以下命令,生成Client端证书的请求文件。
- 执行ls命令,查看创建的证书。
预期输出:
ca.crt ca.key client.crt client.csr client.key server.crt server.csr server.key
- 执行以下命令,生成CA证书的Secret。
kubectl create secret generic ca-secret --from-file=ca.crt=ca.crt
预期输出:
secret/ca-secret created
- 执行以下命令,生成Server端证书的Secret。
kubectl create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key
预期输出:
secret/tls-secret created
- 创建名为“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密钥证书
- 1.23及以上版本集群
- 执行以下命令,创建Ingress。
kubectl create -f ingress-test.yaml
预期输出:
ingress.networking.k8s.io/ingress-test created
- 执行以下命令,查看Ingress的IP地址。
kubectl get ingress
预期输出:
NAME CLASS HOSTS ADDRESS PORTS AGE nginx-test nginx foo.bar.com 10.3.xx.xx 80, 443 27m
- 执行以下命令,将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
- 结果验证。
- 客户端不传证书访问
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”注解实现域名配置正则表达式。
- 请参见通过kubectl连接集群,使用kubectl连接集群。
- 创建名为“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 #替换为您的目标服务端口
- 1.23及以上版本集群
- 执行以下命令,创建Ingress。
kubectl create -f ingress-test.yaml
预期输出:
ingress.networking.k8s.io/ingress-test created
- 查看Nginx Ingress Controller的配置。
- 执行以下命令,查看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
- 执行以下命令,查看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
- 执行以下命令,查看Nginx Ingress Controller服务的Pod
- 执行以下命令,获取Ingress对应的IP。
kubectl get ingress
预期输出:
NAME CLASS HOSTS ADDRESS PORTS AGE nginx-test nginx foo.bar.com 10.3.xx.xx 80 14m
- 执行以下命令,测试不同规则下的服务访问。
- 执行以下命令,通过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/
预期可正常访问网页。
- 执行以下命令,通过Host: foo.bar.com访问服务。
灰度发布
灰度发布功能可以通过设置注解来实现,为了启用灰度发布功能,需要设置注解nginx.ingress.kubernetes.io/canary: "true",通过不同注解可以实现不同的灰度发布功能:
参数 |
类型 |
描述 |
---|---|---|
nginx.ingress.kubernetes.io/canary-weight |
String |
设置请求到指定服务的百分比(值为0~100的整数)。 |
nginx.ingress.kubernetes.io/canary-by-header |
String |
基于Request Header的流量切分,如果请求头中包含指定的header名称,并且值为“always”,就将该请求转发给Canary Ingress定义的对应后端服务。如果值为“never”则不转发,可用于回滚到旧版本。如果为其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。 |
nginx.ingress.kubernetes.io/canary-by-header-value |
String |
必须与canary-by-header一起使用,可自定义请求头的取值,包含但不限于“always”或“never”。当请求头的值命中指定的自定义值时,请求将会转发给Canary Ingress定义的对应后端服务,如果是其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。 |
nginx.ingress.kubernetes.io/canary-by-header-pattern |
String |
与canary-by-header-value类似,唯一区别是该annotation用正则表达式匹配请求头的值,而不是某一个固定值。如果该annotation与canary-by-header-value同时存在,该annotation将被忽略。 |
nginx.ingress.kubernetes.io/canary-by-cookie |
String |
基于Cookie的流量切分,当配置的cookie值为always时,请求流量将被分配到灰度服务入口;当配置的cookie值为never时,请求流量将不会分配到灰度服务入口。 |
- 以上注解规则会按优先级进行评估,优先级为:canary-by-header -> canary-by-cookie -> canary-weight。
- 当Ingress被标记为Canary Ingress时,除了nginx.ingress.kubernetes.io/load-balance和nginx.ingress.kubernetes.io/upstream-hash-by外,所有其他非Canary的注解都将被忽略。
更多信息,请参见通过Nginx Ingress实现灰度发布和蓝绿发布。
以下为部分注解配置示例:
- 基于权重灰度:配置灰度服务的权重为20%。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20" ...
- 基于Header灰度:请求Header为cce:always时将访问灰度服务;请求Header为cce:never时将不访问灰度服务;其他Header将根据灰度权重将流量分配给灰度服务。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "50" nginx.ingress.kubernetes.io/canary-by-header: "cce" ...
- 基于Header灰度(自定义header值):当请求Header为cce:test时将访问灰度服务;其他Header将根据灰度权重将流量分配给灰度服务。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20" nginx.ingress.kubernetes.io/canary-by-header: "cce" nginx.ingress.kubernetes.io/canary-by-header-value: "test" ...
- 基于Cookie灰度:当Header不匹配时,请求的Cookie为region=always时将访问灰度服务。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20" nginx.ingress.kubernetes.io/canary-by-header: "cce" nginx.ingress.kubernetes.io/canary-by-header-value: "test" nginx.ingress.kubernetes.io/canary-by-cookie: "region" ...