更新时间:2024-11-12 GMT+08:00

为ELB Ingress配置HTTPS证书

Ingress支持配置SSL/TLS证书,以HTTPS协议的方式对外提供安全服务。

当前支持在集群中使用以下方式配置Ingress证书:
  • 使用TLS类型的密钥证书:需要将证书导入至Secret中,CCE会将该证书自动配置到ELB侧(证书名以k8s_plb_default开头),由CCE自动创建的证书在ELB侧不可修改或删除。如果您需要修改证书,请在CCE侧更新对应的Secret。
  • 使用ELB服务中的证书:直接使用ELB服务中创建的证书,无需手动配置集群Secret,且可以在ELB侧修改证书。

同一个ELB实例的同一个端口配置HTTPS时,需要选择一样的证书。详情请参见多个Ingress配置同一端口说明

前提条件

使用TLS类型的密钥证书

您可以使用以下方式配置TLS类型的密钥证书。

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 选择左侧导航栏的“服务”,在右侧选择“路由”页签,单击右上角“创建路由”
  3. 设置Ingress参数。

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

    表1 关键参数说明

    参数

    配置说明

    示例

    名称

    自定义Ingress名称。

    ingress-test

    负载均衡器

    选择对接的ELB实例或自动创建ELB实例。

    共享型ELB

    监听器配置

    • 前端协议:为Ingress配置证书需选择“HTTPS”
    • 对外端口:ELB监听器端口,HTTPS协议的端口默认为443。
    • 证书来源:选择“TLS密钥”
    • 服务器证书:支持使用kubernetes.io/tlsIngressTLS两种TLS密钥类型。

      如果您没有可选择的密钥证书,可新建TLS类型的密钥证书,对应参数详情请参见创建密钥

    • 前端协议:“HTTPS”
    • 对外端口:443
    • 证书来源:“TLS密钥”
    • 服务器证书:test

    转发策略配置

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

  4. 配置完成后,单击“确定”
  1. 请参见通过kubectl连接集群,使用kubectl连接集群。
  2. Ingress支持使用kubernetes.io/tlsIngressTLS两种TLS密钥类型,此处以IngressTLS类型为例,详情请参见创建密钥kubernetes.io/tls类型的密钥示例及说明请参见TLS Secret

    执行如下命令,创建名为“ingress-test-secret.yaml”的YAML文件,此处文件名可自定义。

    vi ingress-test-secret.yaml
    YAML文件配置如下:
    apiVersion: v1
    data:
      tls.crt: LS0******tLS0tCg==
      tls.key: LS0tL******0tLS0K
    kind: Secret
    metadata:
      annotations:
        description: test for ingressTLS secrets
      name: ingress-test-secret
      namespace: default
    type: IngressTLS

    此处tls.crt和tls.key为示例,请获取真实的证书和密钥进行替换。tls.crt和tls.key的值为Base64编码后的内容。

  3. 创建密钥。

    kubectl create -f ingress-test-secret.yaml

    回显如下,表明密钥已创建。

    secret/ingress-test-secret created

  4. 查看已创建的密钥。

    kubectl get secrets

    回显如下,表明密钥创建成功。

    NAME                         TYPE                                  DATA      AGE
    ingress-test-secret          IngressTLS                            2         13s

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

    vi ingress-test.yaml

    默认安全策略选择(kubernetes.io/elb.tls-ciphers-policy)仅在1.17.17及以上版本的集群中支持。

    自定义安全策略选择(kubernetes.io/elb.security_policy_id)仅在1.17.17及以上版本的集群中支持。

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

    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",
              "available_zone": [
                  "ap-southeast-1a"
              ],
              "elb_virsubnet_ids":["b4bf8152-6c36-4c3b-9f74-2229f8e640c9"],
              "l7_flavor_name": "L7_flavor.elb.s1.small"
           }'
        kubernetes.io/elb.security_policy_id: 99bec42b-0dd4-4583-98e9-b05ce628d157  #自定义安全策略优先级高于系统默认安全策略
        kubernetes.io/elb.tls-ciphers-policy: tls-1-2
    spec:
      tls: 
      - secretName: ingress-test-secret
      rules: 
      - host: ''
        http: 
          paths: 
          - path: '/'
            backend: 
              serviceName: <your_service_name>  #替换为您的目标服务名称
              servicePort: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
    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",
              "available_zone": [
                  "ap-southeast-1a"
              ],
              "elb_virsubnet_ids":["b4bf8152-6c36-4c3b-9f74-2229f8e640c9"],
              "l7_flavor_name": "L7_flavor.elb.s1.small"
           }'
        kubernetes.io/elb.security_policy_id: 99bec42b-0dd4-4583-98e9-b05ce628d157  #自定义安全策略优先级高于系统默认安全策略
        kubernetes.io/elb.tls-ciphers-policy: tls-1-2
    spec:
      tls: 
      - secretName: ingress-test-secret
      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 
    表2 关键参数说明

    参数

    是否必填

    参数类型

    描述

    kubernetes.io/elb.security_policy_id

    String

    ELB中自定义安全组策略ID,请前往ELB控制台获取。该字段仅在HTTPS协议下生效,且优先级高于默认安全策略。

    自定义安全策略的创建、更新步骤请参见TLS安全策略

    kubernetes.io/elb.tls-ciphers-policy

    String

    默认值为“tls-1-2”,为监听器使用的默认安全策略,仅在HTTPS协议下生效。

    取值范围:

    • tls-1-0
    • tls-1-1
    • tls-1-2
    • tls-1-2-strict

    各安全策略使用的加密套件列表详细参见表3

    tls

    Array of strings

    HTTPS协议时,需添加此字段用于指定密钥证书。

    该字段支持添加多项独立的域名和证书,详见为ELB Ingress配置服务器名称指示(SNI)

    secretName

    String

    HTTPS协议时添加,配置为创建的密钥证书名称。

    表3 tls_ciphers_policy取值说明

    安全策略

    支持的TLS版本类型

    使用的加密套件列表

    tls-1-0

    TLS 1.2

    TLS 1.1

    TLS 1.0

    ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA256:AES256-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-SHA:AES256-SHA

    tls-1-1

    TLS 1.2

    TLS 1.1

    tls-1-2

    TLS 1.2

    tls-1-2-strict

    TLS 1.2

    ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA256:AES256-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384

    TLS-1-0-WITH-1-3(独享型实例)

    TLS 1.3

    TLS 1.2

    TLS 1.1

    TLS 1.0

    ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA256:AES256-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-SHA:AES256-SHA:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256

    TLS-1-2-FS(独享型实例)

    TLS 1.3

    TLS 1.2

    ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384

    TLS-1-2-FS-WITH-1-3(独享型实例)

    TLS 1.3

    TLS 1.2

    ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256

  6. 创建Ingress。

    kubectl create -f ingress-test.yaml

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

    ingress/ingress-test created

  7. 查看已创建的Ingress。

    kubectl get ingress

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

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

  8. 访问工作负载(例如Nginx工作负载),在浏览器中输入安全访问地址https://121.**.**.**:443进行验证。

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

使用ELB服务中的证书

您可以使用以下方式为Ingress配置ELB服务中的证书。

  • 当同时指定ELB证书和IngressTLS证书时,Ingress将使用ELB服务中的证书。
  • CCE不校验ELB服务中的证书是否有效,只校验证书是否存在。
  • 仅v1.19.16-r2、v1.21.5-r0、v1.23.3-r0及以上版本的集群支持使用ELB服务中的证书。
  1. 登录CCE控制台,单击集群名称进入集群。
  2. 选择左侧导航栏的“服务”,在右侧选择“路由”页签,单击右上角“创建路由”
  3. 设置Ingress参数。

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

    表4 关键参数说明

    参数

    配置说明

    示例

    名称

    自定义Ingress名称。

    ingress-test

    负载均衡器

    选择对接的ELB实例或自动创建ELB实例。

    共享型ELB

    监听器配置

    • 前端协议:选择“HTTPS”
    • 对外端口:ELB监听器端口,HTTPS协议的端口默认为443。
    • 证书来源:选择“ELB服务器证书”
    • 服务器证书:使用在ELB服务中创建的证书。

      如果您没有可选择的ELB证书,可前往ELB服务创建,详情请参见创建证书

    • 前端协议:“HTTPS”
    • 对外端口:443
    • 证书来源:“ELB服务器证书”
    • 服务器证书:cert-test

    转发策略配置

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

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

使用ELB服务中的证书,可以通过指定kubernetes.io/elb.tls-certificate-ids注解实现。

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

    vi ingress-test.yaml

    以关联已有ELB为例,YAML文件配置如下:

    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
    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
    表5 关键参数说明

    参数

    参数类型

    描述

    kubernetes.io/elb.tls-certificate-ids

    String

    ELB服务中的证书ID列表,不同ID间使用英文逗号隔开,列表长度大于等于1。列表中的首个ID为服务器证书,其余ID为SNI证书(SNI证书中必须带有域名)。

    如果无法根据客户端请求的域名查找到对应的SNI证书,则默认返回服务器证书。

    获取方法:在CCE控制台,单击顶部的“服务列表 > 网络 > 弹性负载均衡”,并选择“证书管理”。在列表中复制对应证书名称下的ID即可。

  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      *         121.**.**.**     80,443  10s

多个Ingress配置同一端口说明

在同一个集群中,多个Ingress可以使用同一个监听器(即使用同一个负载均衡器的同一个端口)。如果两个Ingress均配置了HTTPS证书,则生效的服务器证书将以最早创建的Ingress配置为准。

从集群版本v1.21.15-r0、v1.23.14-r0、v1.25.9-r0、v1.27.6-r0、v1.28.4-r0、v1.29.1-r0开始,Ingress的YAML中加入了annotation: kubernetes.io/elb.listener-master-ingress,其值指向的Ingress配置的服务器证书,就是当前Ingress实际生效的服务器证书。

例如,两个Ingress配置如下:

Ingress名称

ingress1

ingress2

命名空间

default

default

创建时间

2024/04/01

2024/04/02

协议

https

https

负载均衡器

elb1

elb1

端口

443

443

kubernetes.io/elb.listener-master-ingress

default/ingress1

default/ingress1

这两个Ingress的配置中,都有annotation: kubernetes.io/elb.listener-master-ingress,值为default/ingress1,表示这两个Ingress实际生效的服务器证书,都是命名空间default下ingress1配置的服务器证书。

不同命名空间下的Ingress对接同一个监听器且使用TLS密钥类型证书时,由于命名空间隔离,后创建的Ingress可能出现无法正常显示TLS密钥对应Secret的场景。详情请参见不同命名空间下的Ingress共用监听器时如何同步生效的证书?

当需要修改服务器证书时,需要在default命名空间下ingress1的配置中修改服务器证书,修改后ingress1和ingress2实际生效的证书都同步修改。

您可以通过执行以下命令查询实际生效的证书配置所在的Ingress:

kubectl get ingress -n ${namespace} ${ingress_name}  -oyaml | grep kubernetes.io/elb.listener-master-ingress