更新时间:2025-11-04 GMT+08:00
分享

为Nginx Ingress配置服务器名称指示(SNI)

SNI证书是一种扩展服务器证书,允许同一个IP地址和端口号下对外提供多个访问域名,可以根据客户端请求的不同域名来使用不同的安全证书,确保HTTPS通信的安全性。

在配置SNI时,用户需要设置默认的服务器证书和绑定域名的SNI证书。客户端会在发起SSL握手请求时就提交请求的域名信息,负载均衡收到SSL请求后,会根据域名去查找SNI证书。如果找到域名对应的SNI证书,则返回该证书;如果没有找到域名对应的SNI证书,则返回默认的服务器证书。

前提条件

配置SNI

您可以使用以下方式配置SNI。

  • 当使用HTTPS协议时,才支持配置SNI。
  • 用于SNI的证书需要指定域名,每个证书只能指定一个域名。支持泛域名证书。
  1. 登录CCE控制台,单击集群名称进入集群。
  2. 选择左侧导航栏的“服务”,在右侧选择“路由”页签,单击右上角“创建路由”
  3. 设置Ingress参数。

    本示例中展示配置SNI证书的关键参数,其余参数可按需配置,详情请参见通过控制台创建Nginx Ingress

    表1 关键参数说明

    参数

    配置说明

    示例

    名称

    自定义Ingress名称。

    ingress-test

    对接Nginx

    开启后创建的路由将对接NGINX Ingress控制器。

    开启

    控制器名称

    选择集群中安装的NGINX Ingress控制器名称,默认为nginx。您可以根据需求选择安装多个NGINX Ingress控制器,自定义不同的控制器名称。

    nginx

    TLS配置

    • 前端协议:支持HTTP和HTTPS,安装NGINX Ingress控制器插件时预留的监听端口,默认HTTP为80,HTTPS为443。本场景中需要选择HTTPS。
    • 证书来源:使用证书以支持HTTPS数据传输加密认证。
      • 如果您选择“TLS密钥”,需要继续选择“服务器证书”。您需要创建IngressTLS或kubernetes.io/tls类型的密钥证书,创建密钥的方法请参见创建密钥
      • 如果您选择“默认证书”,NGINX Ingress控制器会使用插件默认证书进行加密认证。默认证书可在安装NGINX Ingress控制器插件时进行自定义配置,未配置自定义证书时将使用NGINX Ingress控制器自带证书。
    • SNI:SNI(Server Name Indication)是TLS的扩展协议,在该协议下允许同一个IP地址和端口号下对外提供多个基于TLS的访问域名,且不同的域名可以使用不同的安全证书。开启SNI后,允许客户端在发起TLS握手请求时就提交请求的域名信息。负载均衡收到TLS请求后,会根据请求的域名去查找证书:若找到域名对应的证书,则返回该证书认证鉴权;否则,返回缺省证书(服务器证书)认证鉴权。
    • 前端协议:“HTTPS”
    • 证书来源:“TLS密钥”
    • 服务器证书:test
    • SNI:
      • 域名:example.com
      • 证书:example-test

    转发策略配置

    • 域名:实际访问的域名地址,不配置时可通过IP地址访问Ingress。请确保所填写的域名已注册并备案,一旦配置了域名规则后,必须使用域名访问。
    • 路径匹配规则:选择默认时会使用前缀匹配,您也可以指定前缀匹配精确匹配,请按需选择。
    • 路径:后端应用对外提供访问的路径,此处添加的访问路径要求后端应用内存在相同的路径,否则转发无法生效。
    • 目标服务名称:请选择已有Service,页面列表中的查询结果已自动过滤不符合要求的Service。如果没有满足要求的Service请根据Ingress支持的Service类型新建。
    • 目标服务访问端口:可选择目标Service的访问端口。
    • 域名:example.com
    • 路径匹配规则:默认
    • 路径:/
    • 目标服务名称:nginx
    • 目标服务访问端口:80
    图1 配置SNI

  4. 配置完成后,单击“确定”

本例中example-test为SNI证书,该证书指定的域名必须与证书中的域名一致。

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

    vi ingress-test.yaml

    以自动创建关联ELB为例,YAML文件配置如下:

    1.23及以上版本集群
    apiVersion: networking.k8s.io/v1
    kind: Ingress 
    metadata: 
      name: ingress-test
      namespace: default
    spec:
      tls: 
      - secretName: test  # 必须指定服务器证书,如果不指定则会使用NGINX Ingress控制器中设置的默认证书
      - hosts: 
        - example.com  # SNI证书中指定的域名
        secretName: example-test  #替换为您的SNI密钥证书
      rules:
        - host: example.com
          http:
            paths:
              - path: /
                backend:
                  service:
                    name: <your_service_name>  #替换为您的目标服务名称
                    port:
                      number: <your_service_port>  #替换为您的目标服务端口
                property:
                  ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
                pathType: ImplementationSpecific
      ingressClassName: nginx
    1.21及以下版本集群
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress 
    metadata: 
      name: ingress-test
      annotations: 
        kubernetes.io/ingress.class: nginx
    spec:
      tls: 
      - secretName: test  # 必须指定服务器证书,如果不指定则会使用NGINX Ingress控制器中设置的默认证书
      - hosts: 
        - example.com  # SNI证书中指定的域名
        secretName: example-test   #替换为您的SNI密钥证书
      rules: 
      - host: example.com
        http: 
          paths: 
          - path: '/'
            backend: 
              serviceName: <your_service_name>  #替换为您的目标服务名称
              servicePort: <your_service_port>  #替换为您的目标服务端口

  3. 创建Ingress。

    kubectl create -f ingress-test.yaml

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

    ingress/ingress-test created

  4. 查看已创建的Ingress。

    kubectl get ingress

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

    NAME           CLASS  HOSTS          ADDRESS          PORTS   AGE
    ingress-test   cce    example.com    121.**.**.**     80,443  10s

  5. 使用HTTPS协议访问Ingress,其中${ELB_IP}为Ingress访问的IP。

    curl -H "Host:example.com" -k https://${ELB_IP}:443 

    可正常访问则表明证书配置成功。

相关文档