
# 为ELB Ingress配置服务器名称指示（SNI）
SNI证书是一种扩展服务器证书，允许同一个IP地址和端口号下对外提供多个访问域名，可以根据客户端请求的不同域名来使用不同的安全证书，确保HTTPS通信的安全性。
在配置SNI时，用户需要设置默认的服务器证书和绑定域名的SNI证书。客户端会在发起SSL握手请求时就提交请求的域名信息，负载均衡收到SSL请求后，会根据域名去查找SNI证书。如果找到域名对应的SNI证书，则返回该证书；如果没有找到域名对应的SNI证书，则返回默认的服务器证书。
当前支持在集群中使用以下方式配置Ingress证书：
- [使用TLS类型的密钥证书配置SNI]：需要将证书导入至Secret中，CCE会将该证书自动配置到ELB侧（证书名以k8s_plb_default开头），由CCE自动创建的证书在ELB侧不可修改或删除。
- [使用ELB服务中的证书配置SNI]：直接使用ELB服务中创建的证书，无需手动配置集群Secret，且可以在ELB侧修改证书。
 
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
独享型ELB最多支持50本SNI证书，共享型ELB最多支持30本SNI证书。
#### 前提条件
- 集群中需提前部署可用的工作负载用于对外提供访问。若您无可用工作负载，可参见[创建无状态负载（Deployment）](https://support.huaweicloud.com/usermanual-cce/cce_10_0047.html)、[创建有状态负载（StatefulSet）](https://support.huaweicloud.com/usermanual-cce/cce_10_0048.html)或[创建守护进程集（DaemonSet）](https://support.huaweicloud.com/usermanual-cce/cce_10_0216.html)部署工作负载。
- 为提供对外访问的工作负载配置Service，ELB Ingress支持的Service类型请参见[ELB Ingress支持的Service类型](https://support.huaweicloud.com/usermanual-cce/cce_10_0094.html#cce_10_0094__section3565202819276)。
- 已准备可信的服务器证书和SNI证书，您可以从证书提供商处获取证书。操作详情请参见[购买SSL证书](https://support.huaweicloud.com/usermanual-ccm/ccm_01_0074.html)。
- 使用TLS类型的密钥证书配置SNI时，需要为证书创建IngressTLS或kubernetes.io/tls类型的密钥。创建密钥的方法请参见[创建密钥](https://support.huaweicloud.com/usermanual-cce/cce_10_0153.html)。
  使用ELB服务中的证书配置SNI时，需要在ELB服务中创建证书。创建证书的方法请参见[创建证书](https://support.huaweicloud.com/usermanual-elb/elb_ug_zs_0004.html)。
  
 
 #### 使用TLS类型的密钥证书配置SNI
您可以使用以下方式使用TLS类型的密钥证书配置SNI。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
- 当使用HTTPS协议时，才支持配置SNI。

- 用于SNI的证书需要指定域名，每个证书只能指定一个域名。支持泛域名证书。
- 安全策略选择（kubernetes.io/elb.tls-ciphers-policy）仅在1.17.11及以上版本的集群中支持。
 
- [通过控制台配置]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
  
  2. 选择左侧导航栏的"服务"，在右侧选择"路由"页签，单击右上角"创建路由"。
  
  3. 设置Ingress参数。 
     ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
     本示例中展示配置SNI证书的关键参数，其余参数可按需配置，详情请参见[通过控制台创建ELB Ingress](https://support.huaweicloud.com/usermanual-cce/cce_10_0251.html)。
     表1关键参数说明 
     | 参数     | 配置说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 示例                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
     |:---|:---|:---|
     | 名称     | 自定义Ingress名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | ingress-test                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
     | 负载均衡器  | 选择对接的ELB实例或自动创建ELB实例。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 共享型ELB                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
     | 监听器配置  | - 前端协议：为Ingress配置证书需选择"HTTPS"。  - 对外端口：ELB监听器端口，HTTPS协议的端口默认为443。  - 证书来源：选择"TLS密钥"。  - 服务器证书：支持使用kubernetes.io/tls和IngressTLS两种TLS密钥类型。 如果您没有可选择的密钥证书，可新建TLS类型的密钥证书，对应参数详情请参见[创建密钥](https://support.huaweicloud.com/usermanual-cce/cce_10_0153.html)。   - SNI：输入域名并选择对应的SNI证书，SNI证书中需要包含域名信息，SNI证书支持使用kubernetes.io/tls和IngressTLS两种TLS密钥类型。                                                                                                                                                            | - 前端协议："HTTPS"  - 对外端口：443  - 证书来源："TLS密钥"  - 服务器证书：test  - SNI： - 域名：example.com  - 证书：example-test     |
     | 转发策略配置 | - 域名：实际访问的域名地址，不配置时可通过IP地址访问Ingress。请确保所填写的域名已注册并备案，一旦配置了域名规则后，必须使用域名访问。  - 路径匹配规则：支持前缀匹配、精确匹配、正则匹配，请按需选择。  - 路径：后端应用对外提供访问的路径，此处添加的访问路径要求后端应用内存在相同的路径，否则转发无法生效。  - 目标服务名称：请选择已有Service，页面列表中的查询结果已自动过滤不符合要求的Service。如果没有满足要求的Service请根据[Ingress支持的Service类型](https://support.huaweicloud.com/usermanual-cce/cce_10_0094.html#cce_10_0094__section1674954315446)新建。  - 目标服务访问端口：可选择目标Service的访问端口。   | - 域名：example.com  - 路径匹配规则：前缀匹配  - 路径：/  - 目标服务名称：nginx  - 目标服务访问端口：80                                                                                                                                                                                     |
        
     图1使用TLS类型的密钥证书配置SNI   
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000001969802462.png "点击放大")
     
     
  
  4. 配置完成后，单击"确定"。
   
- [通过kubectl命令行配置]
  本例中**sni-test-secret**为SNI证书，该证书指定的域名必须与证书中的域名一致。
  1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)，使用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
       annotations: 
         kubernetes.io/elb.class: performance
         kubernetes.io/elb.port: '443'
         kubernetes.io/elb.autocreate: 
           '{
               "type": "public",
               "bandwidth_name": "cce-bandwidth-******",
               "bandwidth_chargemode": "bandwidth",
               "bandwidth_size": 5,
               "bandwidth_sharetype": "PER",
               "eip_type": "5_bgp",    # 弹性公网IP类型
               "available_zone": [
                   "cn-north-4b"
               ],  # ELB所在可用区
               "elb_virsubnet_ids":["b4bf8152-6c36-4c3b-9f74-2229f8e640c9"],  # 子网的网络ID
               "l7_flavor_name": "L7_flavor.elb.s1.small"   #七层负载均衡实例规格名称
            }'
         kubernetes.io/elb.tls-ciphers-policy: tls-1-2
     spec:
       tls: 
       - secretName: ingress-test-secret  #服务器证书名称
       - hosts:
           - example.com  #签发SNI证书时指定域名为example.com
         secretName: sni-test-secret #SNI证书 
       rules: 
       - host: example.com   #域名需要和tls字段中的hosts取值一致
         http: 
           paths: 
           - path: '/'
             backend: 
               service:
                 name: <your_service_name>  #替换为您的目标服务名称
                 port: 
                   number: 80             #替换为您的目标服务端口
             property:
               ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
             pathType: ImplementationSpecific
       ingressClassName: cce
     ```
     **1.21及以下版本集群：**
     ```
     apiVersion: networking.k8s.io/v1beta1
     kind: Ingress 
     metadata: 
       name: ingress-test
       annotations: 
         kubernetes.io/elb.class: performance
         kubernetes.io/ingress.class: cce
         kubernetes.io/elb.port: '443'
         kubernetes.io/elb.autocreate: 
           '{
               "type": "public",
               "bandwidth_name": "cce-bandwidth-******",
               "bandwidth_chargemode": "bandwidth",
               "bandwidth_size": 5,
               "bandwidth_sharetype": "PER",
               "eip_type": "5_bgp",      # 弹性公网IP类型
               "available_zone": [
                   "cn-north-4b"
               ],   # ELB所在可用区
               "elb_virsubnet_ids":["b4bf8152-6c36-4c3b-9f74-2229f8e640c9"],   # 子网的网络ID
               "l7_flavor_name": "L7_flavor.elb.s1.small"    #七层负载均衡实例规格名称
            }'
         kubernetes.io/elb.tls-ciphers-policy: tls-1-2
     spec:
       tls: 
       - secretName: ingress-test-secret #服务器证书名称
       - hosts:
           - example.com  #签发SNI证书时指定域名为example.com
         secretName: sni-test-secret   #SNI证书
       rules: 
       - host: example.com   #域名需要和tls字段中的hosts取值一致
         http: 
           paths: 
           - path: '/'
             backend: 
               serviceName: <your_service_name>  #替换为您的目标服务名称
               servicePort: 80      #替换为您的目标服务端口
             property:
               ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
     ```
     
     
  
  3. 创建Ingress。 
     ```
     kubectl create -f ingress-test.yaml
     ```
     回显类似如下，表示Ingress服务已创建。
     ```
     ingress.networking.k8s.io/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
     ```
     可正常访问则表明证书配置成功。
     
     
   
 #### 使用ELB服务中的证书配置SNI
您可以使用以下方式为Ingress配置ELB服务中的证书。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
- 当同时指定ELB证书和IngressTLS证书时，Ingress将使用ELB服务中的证书。
- CCE不校验ELB服务中的证书是否有效，只校验证书是否存在。
- 仅v1.19.16-r2、v1.21.5-r0、v1.23.3-r0及以上版本的集群支持使用ELB服务中的证书。
 
- [通过控制台配置]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
  
  2. 选择左侧导航栏的"服务"，在右侧选择"路由"页签，单击右上角"创建路由"。
  
  3. 设置Ingress参数。 
     ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
     本示例中展示配置SNI证书的关键参数，其余参数可按需配置，详情请参见[通过控制台创建ELB Ingress](https://support.huaweicloud.com/usermanual-cce/cce_10_0251.html)。
     表2关键参数说明 
     | 参数     | 配置说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 示例                                                                                                                                                                                                                                                                                                                                                                                                                                    |
     |:---|:---|:---|
     | 名称     | 自定义Ingress名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | ingress-test                                                                                                                                                                                                                                                                                                                                                                                                                          |
     | 负载均衡器  | 选择对接的ELB实例或自动创建ELB实例。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 共享型ELB                                                                                                                                                                                                                                                                                                                                                                                                                                |
     | 监听器配置  | - 前端协议：选择"HTTPS"。  - 对外端口：ELB监听器端口，HTTPS协议的端口默认为443。  - 证书来源：选择"ELB服务器证书"。  - 服务器证书：使用在ELB服务中创建的证书。 如果您没有可选择的ELB证书，可前往ELB服务创建，详情请参见[创建证书](https://support.huaweicloud.com/usermanual-elb/elb_ug_szs_0003.html)。   - SNI：选择对应的SNI证书，SNI证书中需要包含域名信息。 如果您没有可选择的证书，可前往ELB服务创建，详情请参见[创建证书](https://support.huaweicloud.com/usermanual-elb/elb_ug_szs_0003.html)。                                                               | - 前端协议："HTTPS"  - 对外端口：443  - 证书来源："ELB服务器证书"  - 服务器证书：cert-test  - SNI：cert-example   |
     | 转发策略配置 | - 域名：实际访问的域名地址，不配置时可通过IP地址访问Ingress。请确保所填写的域名已注册并备案，一旦配置了域名规则后，必须使用域名访问。  - 路径匹配规则：支持前缀匹配、精确匹配、正则匹配，请按需选择。  - 路径：后端应用对外提供访问的路径，此处添加的访问路径要求后端应用内存在相同的路径，否则转发无法生效。  - 目标服务名称：请选择已有Service，页面列表中的查询结果已自动过滤不符合要求的Service。如果没有满足要求的Service请根据[Ingress支持的Service类型](https://support.huaweicloud.com/usermanual-cce/cce_10_0094.html#cce_10_0094__section1674954315446)新建。  - 目标服务访问端口：可选择目标Service的访问端口。   | - 域名：无需填写  - 路径匹配规则：前缀匹配  - 路径：/  - 目标服务名称：nginx  - 目标服务访问端口：80                        |
        
     图2使用ELB服务中的证书配置SNI   
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002006375897.png "点击放大")
     
     
  
  4. 配置完成后，单击"确定"。
   
- [通过kubectl命令行配置]
  您可以通过指定kubernetes.io/elb.tls-certificate-ids注解，在Ingress使用ELB服务中的证书。
  1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)，使用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
       annotations:
         kubernetes.io/elb.port: '443'
         kubernetes.io/elb.id: 0b9a6c4d-bd8b-45cc-bfc8-ff0f9da54e95
         kubernetes.io/elb.class: union
         kubernetes.io/elb.tls-certificate-ids: 058cc023690d48a3867ad69dbe9cd6e5,b98382b1f01c473286653afd1ed9ab63
     spec:
       rules:
         - host: ''
           http:
             paths:
               - path: '/'
                 backend:
                   service:
                     name: <your_service_name>  #替换为您的目标服务名称
                     port: 
                       number: 80             #替换为您的目标服务端口
                 property:
                   ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
                 pathType: ImplementationSpecific
       ingressClassName: cce
     ```
     **1.21及以下版本集群：**
     ```
     apiVersion: networking.k8s.io/v1beta1
     kind: Ingress 
     metadata: 
       name: ingress-test
       annotations: 
         kubernetes.io/ingress.class: cce
         kubernetes.io/elb.port: '443'
         kubernetes.io/elb.id: 0b9a6c4d-bd8b-45cc-bfc8-ff0f9da54e95
         kubernetes.io/elb.class: union
         kubernetes.io/elb.tls-certificate-ids: 058cc023690d48a3867ad69dbe9cd6e5,b98382b1f01c473286653afd1ed9ab63
     spec:
       rules: 
       - host: ''
         http: 
           paths: 
           - path: '/'
             backend: 
               serviceName: <your_service_name>  #替换为您的目标服务名称
               servicePort: 80
             property:
               ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
     ```
     表3关键参数说明 
     | 参数                                    | 参数类型   | 描述                                                                                                                                                                                                                                                                                         |
     |:---|:---|:---|
     | kubernetes.io/elb.tls-certificate-ids | String | ELB服务中的证书ID列表，不同ID间使用英文逗号隔开，列表长度大于等于1。列表中的首个ID为服务器证书，其余ID为SNI证书（SNI证书中必须带有域名）。独享型ELB最多支持50本SNI证书，共享型ELB最多支持30本SNI证书。 如果无法根据客户端请求的域名查找到对应的SNI证书，则默认返回服务器证书。 获取方法：在CCE控制台，单击顶部的"服务列表 \> 网络 \> 弹性负载均衡"，并选择"证书管理"。在列表中复制对应证书名称下的ID即可。 |
        
     
     
  
  3. 创建Ingress。 
     ```
     kubectl create -f ingress-test.yaml
     ```
     回显类似如下，表示Ingress服务已创建。
     ```
     ingress.networking.k8s.io/ingress-test created
     ```
     
     
  
  4. 查看已创建的Ingress。 
     ```
     kubectl get ingress
     ```
     回显如下，表示Ingress服务创建成功。
     ```
     NAME          CLASS    HOSTS     ADDRESS          PORTS   AGE
     ingress-test  cce      *         121.**.**.**     80,443  10s
     ```
     
     
  
  5. 使用HTTPS协议访问Ingress，其中${ELB_IP}为Ingress访问的IP。 
     ```
     curl -H "Host:example.com" -k https://${ELB_IP}:443
     ```
     可正常访问则表明证书配置成功。
     
     
   
 #### 多个Ingress配置同一端口时的SNI证书生效说明
在同一个集群中，多个Ingress可以使用同一个监听器（即使用同一个负载均衡器的同一个端口），各Ingress配置的SNI证书会自动聚合，同时生效。
例如，两个Ingress配置如下，其中ingress1为首路由（关于首路由概念请参见[如何确认监听器配置生效的Ingress](https://support.huaweicloud.com/cce_faq/cce_faq_00460.html)）：
|                 Ingress名称                 |      ingress1       |      ingress2       |
|---|---|---|
| **kubernetes.io/elb.tls-certificate-ids** | cert-id-A,cert-id-B | cert-id-C,cert-id-D |
   
kubernetes.io/elb.tls-certificate-ids参数中的首个ID为服务器证书，其余ID为SNI证书。
多个Ingress使用同一个监听器时：
- 服务器证书仅取第一个Ingress（ingress1）中配置的cert-id-A，其余Ingress中的服务器证书（如ingress2中的cert-id-C）会被忽略。
- SNI证书则会自动聚合所有Ingress中的配置，生效cert-id-B和cert-id-D。
 
