文档首页> 云容器引擎 CCE> 用户指南> 旧版UI> 网络管理> Ingress> 通过Kubectl命令行添加Nginx Ingress
更新时间:2022-05-11 GMT+08:00
分享

通过Kubectl命令行添加Nginx Ingress

操作场景

本节以Nginx工作负载为例,说明kubectl命令添加Nginx Ingress的方法。

前提条件

添加Nginx Ingress

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

    vi ingress-test.yaml

    • 1.15及以上集群版本中的“apiVersion”为: “networking.k8s.io/v1beta1”
    • 1.13及以下集群版本中的“apiVersion”为: “extensions/v1beta1”

    以HTTP协议访问为例,YAML文件配置如下:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress-test
      namespace: default
      annotations:
        kubernetes.io/ingress.class: nginx
        kubernetes.io/elb.port: '80' 
    spec:
      rules:
        - host: ''
          http:
            paths:
              - path: '/'
                backend:
                  serviceName: <your_service_name>  #替换为您的目标服务名称
                  servicePort: 80
    表1 关键参数说明

    参数

    是否必填

    参数类型

    描述

    kubernetes.io/ingress.class

    String

    nginx:表示使用NginxIngress,未安装nginx-ingress插件时无法使用。

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

    kubernetes.io/elb.port

    Integer

    界面上的对外端口,为注册到负载均衡服务地址上的端口。

  3. 创建Ingress。

    kubectl create -f ingress-test.yaml

    回显如下,表示Ingress服务已创建。

    ingress/ingress-test created

    查看已创建的Ingress。

    kubectl get ingress

    回显如下,表示Ingress服务创建成功,工作负载可访问。

    NAME             HOSTS     ADDRESS          PORTS   AGE
    ingress-test     *         121.**.**.**     80      10s

  4. 访问工作负载(例如Nginx工作负载),在浏览器中输入访问地址“http://121.**.**.**:80”进行验证。

    其中,“121.**.**.**”为统一负载均衡实例的IP地址。

配置HTTPS证书

Ingress支持配置HTTPS证书以提供安全服务,YAML配置示例如下:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress 
metadata: 
  name: ingress-test
  annotations: 
    kubernetes.io/ingress.class: nginx
    kubernetes.io/elb.port: '443'
spec:
  tls: 
  - hosts: 
    - foo.bar.com
    secretName: ingress-test-secret
  rules: 
  - host: ''
    http: 
      paths: 
      - path: '/'
        backend: 
          serviceName: <your_service_name>  #替换为您的目标服务名称
          servicePort: 80

配置URL重写规则

在一些使用场景中后端服务暴露的URL与Ingress规则中指定的路径不同,如果不进行URL重写配置,所有访问都将返回404。Nginx的URL重写可以通过Rewrite方法实现,使用“nginx.ingress.kubernetes.io/rewrite-target”注解可以实现不同路径的重写规则,如下所示:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: 'rewrite.bar.com'
      http:
        paths:
          - path: '/something(/|$)(.*)'
            backend:
              serviceName: <your_service_name>  #替换为您的目标服务名称
              servicePort: 80

只要有一个Ingress使用了rewrite-target,则所有Ingress定义下同一个host下所有path都会正则大小写敏感,包括没有使用rewrite-target的Ingress。

以上示例中,占位符$2表示将第二个括号即(.*)中匹配到的所有字符填写到“nginx.ingress.kubernetes.io/rewrite-target”注解中。

例如,上面的Ingress定义将导致以下重写:
  • rewrite.bar.com/something 重写为 rewrite.bar.com/
  • rewrite.bar.com/something/ 重写为 rewrite.bar.com/
  • rewrite.bar.com/something/new 重写为 rewrite.bar.com/new

nginx-ingress-controller容器中,“/etc/nginx”路径下的nginx.conf文件可查看所有Ingress配置。以上示例中的重写规则将生成一条Rewrite指令,并写入到nginx.conf的location字段中,如下所示:

## start server rewrite.bar.com
        server {
                server_name rewrite.bar.com ;
                ...
                location ~* "^/something(/|$)(.*)" {
                        set $namespace      "default";
                        set $ingress_name   "ingress-test";
                        set $service_name   "<your_service_name>";
                        set $service_port   "80";
                        ...
                        rewrite "(?i)/something(/|$)(.*)" /$2 break;
                        ...
                }
        }
        ## end server rewrite.bar.com
上面的Rewrite指令基本语法结构为:
rewrite regex replacement [flag];
  • regex:匹配URI的正则表达式。在上述例子中,“(?i)/something(/|$)(.*)”即为匹配URI的正则表达式,其中“(?i)”表示不区分大小写。
  • replacement:重写内容。在上述例子中,“/$2”即为重写内容,表示把路径重写为第二个括号“(.*)”中匹配到的所有字符。
  • flag:表示重写形式的标记,包括:
    • last:表示本条规则匹配完成后继续向下匹配。
    • break:表示本条规则匹配完成后停止匹配。
    • redirect:表示临时重定向,返回状态码302。
    • permanent:表示永久重定向,返回状态码301。

对于一些复杂高级的Rewrite需求,可以通过如下注解来实现,其本质也是修改Nginx的配置文件(nginx.conf),可以实现上面提到的“nginx.ingress.kubernetes.io/rewrite-target”注解的功能,但是自定义程度更高,适合更加复杂的Rewrite需求。

  • nginx.ingress.kubernetes.io/server-snippet:在nginx.conf的“server”字段中添加自定义配置。
  • nginx.ingress.kubernetes.io/configuration-snippet:在nginx.conf的“location”字段中添加自定义配置。

通过以上两个注解可以在nginx.conf中的“server”“location”字段中插入Rewrite指令,完成URL的重写,示例如下:

annotations:
     kubernetes.io/ingress.class: "nginx"
     nginx.ingress.kubernetes.io/configuration-snippet: |
        rewrite ^/stylesheets/(.*)$ /something/stylesheets/$1 redirect;  # 添加 /something 前缀
        rewrite ^/images/(.*)$ /something/images/$1 redirect;  # 添加 /something 前缀
如上两条规则在访问URL中添加了“/something”路径,即:
  • 当用户访问rewrite.bar.com/stylesheets/new.css时,重写为rewrite.bar.com/something/stylesheets/new.css
  • 当用户访问rewrite.bar.com/images/new.jpg时,重写为rewrite.bar.com/something/images/new.jpg

创建负载均衡规则

原生的Nginx支持多种负载均衡规则,其中常用的有加权轮询、IP hash等。Nginx Ingress在原生的Nginx能力基础上,支持使用一致性哈希方法进行负载均衡。

Nginx默认支持的IP hash方法使用的是线性的hash空间,根据IP的hash运算值来选取后端的目标服务器。但是这种方法在添加删除节点时,所有IP值都需要重新进行hash运算,然后重新路由,这样的话就会导致大面积的会话丢失或缓存失效,因此Nginx Ingress引入了一致性哈希来解决这一问题。

一致性哈希是一种特殊的哈希算法,通过构建环状的hash空间来替代普通的线性hash空间,在增删节点时仅需要将路由的目标按顺时针原则向下迁移,而其他路由无需改变,可以尽可能地减少重新路由,有效解决动态增删节点带来的负载均衡问题。

通过配置一致性哈希规则,在增加一台服务器时,新的服务器会尽量分担其他所有服务器的压力;同样,在减少一台服务器时,其他所有服务器也可以尽量分担它的资源,可以有效减少集群局部节点的压力,防止由于某一节点宕机带来的集群雪崩效应。

Nginx Ingress可以通过“nginx.ingress.kubernetes.io/upstream-hash-by”注解实现一致性哈希规则的配置,如下所示:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"  #按照请求uri进行hash
spec:
  rules:
    - host: ''
      http:
        paths:
          - path: '/'
            backend:
              serviceName: <your_service_name>  #替换为您的目标服务名称
              servicePort: 80
注解“nginx.ingress.kubernetes.io/upstream-hash-by”的参数值支持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。
分享:

    相关文档

    相关产品

关闭导读