Updated on 2024-09-30 GMT+08:00

Configuring SNI for a LoadBalancer Ingress

An SNI certificate is an extended server certificate that allows the same IP address and port number to provide multiple access domain names for external systems. Different security certificates can be used based on the domain names requested by clients to ensure HTTPS communication security.

When configuring SNI, you need to add a certificate associated with a domain name. The client submits the requested domain name information when initiating an SSL handshake request. After receiving the SSL request, the load balancer searches for the certificate based on the domain name. If the certificate is found, the load balancer will return it to the client. If the certificate is not found, the load balancer will return the default server certificate.

You are allowed to use either of the following ways to configure an ingress certificate in a cluster:
  • Configuring SNI Using a TLS Certificate: You need to first import a certificate to a Secret. CCE will then automatically handle the certificate configurations on the ELB console and give a name to the certificate (started with k8s_plb_default). This certificate, which is generated by CCE, cannot be modified or deleted from the ELB console.
  • Configuring SNI Using an ELB Certificate: You are allowed to directly use certificates created on the ELB console. There is no need to manually configure the cluster Secrets, and you can modify the certificates on the ELB console.

Prerequisites

Configuring SNI Using a TLS Certificate

You can configure SNI through a TLS certificate using either the CCE console or kubectl.

  • The SNI option is available only when HTTPS is used.
  • Only one domain name can be specified for each SNI certificate. Wildcard-domain certificates are supported.
  • Security policy (kubernetes.io/elb.tls-ciphers-policy) is supported only in clusters of v1.17.11 or later.
  1. Log in to the CCE console and click the cluster name to access the cluster console.
  2. Choose Services & Ingresses in the navigation pane, click the Ingresses tab, and click Create Ingress in the upper right corner.
  3. Configure ingress parameters.

    This example explains only key parameters for configuring SNI certificates. You can configure other parameters as required. For details, see Creating a LoadBalancer Ingress on the Console.

    Table 1 Key parameters

    Parameter

    Description

    Example

    Name

    Enter an ingress name.

    ingress-test

    Load Balancer

    Select a load balancer to be associated with the ingress or automatically create a load balancer.

    Shared

    Listener

    • External Protocol: Select HTTPS when configuring a certificate for an ingress.
    • External Port: specifies the port of the load balancer listener. The default HTTPS port is 443.
    • Certificate Source: Select TLS secret.
    • Server Certificate: kubernetes.io/tls and IngressTLS are supported.

      If no certificate is available, you can create a TLS certificate. For details about the configuration parameters, see Creating a Secret.

    • SNI: Enter a domain name and select a certificate. The SNI certificate must contain the domain name information. SNI certificates support two TLS secret types: kubernetes.io/tls and IngressTLS.
    • External Protocol: HTTPS
    • External Port: 443
    • Certificate Source: TLS secret
    • Server Certificate: test
    • SNI:
      • Domain Name: example.com
      • Certificate: example-test

    Forwarding Policy

    • Domain Name: Enter an actual domain name to be accessed. If it is left blank, the ingress can be accessed through the IP address. Ensure that the domain name has been registered and licensed. Once a forwarding policy is configured with a domain name specified, you must use the domain name for access.
    • Path Matching Rule: Select Prefix match, Exact match, or RegEx match.
    • Path: Enter the path provided by a backend application for external access. The path added must be valid in the backend application, or the forwarding cannot take effect.
    • Destination Service: Select an existing Service or create a Service. Any Services that do not match the search criteria will be filtered out automatically.
    • Destination Service Port: Select the access port of the destination Service.
    • Domain Name: example.com
    • Path Matching Rule: Prefix match
    • Path: /
    • Destination Service: nginx
    • Destination Service Port: 80
    Figure 1 Configuring an SNI certificate using a TLS certificate

  4. Click OK.

In this example, the sni-test-secret SNI certificate is used as an example. The specified domain name must be the same as that of the SNI certificate.

  1. Use kubectl to access the cluster. For details, see Connecting to a Cluster Using kubectl.
  2. Create a YAML file named ingress-test.yaml. The file name can be customized.

    vi ingress-test.yaml

    An example YAML file of an ingress associated with an automatically created load balancer is as follows:

    For clusters of v1.21 or earlier:
    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.tls-ciphers-policy: tls-1-2
    spec:
      tls: 
      - secretName: ingress-test-secret
      - hosts:
          - example.com  # Domain name specified when a certificate is issued
        secretName: sni-test-secret   #SNI certificate
      rules: 
      - host: example.com   #The domain name must be the same as the value of hosts in the tls field.
        http: 
          paths: 
          - path: '/'
            backend: 
              serviceName: <your_service_name>  # Replace it with the name of your target Service.
              servicePort: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
    For clusters of v1.23 or later:
    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.tls-ciphers-policy: tls-1-2
    spec:
      tls: 
      - secretName: ingress-test-secret 
      - hosts:
          - example.com  # Domain name specified when a certificate is issued
        secretName: sni-test-secret #SNI certificate
      rules: 
      - host: example.com   #The domain name must be the same as the value of hosts in the tls field.
        http: 
          paths: 
          - path: '/'
            backend: 
              service:
                name: <your_service_name>  # Replace it with the name of your target Service.
                port: 
                  number: 80             # Replace 80 with the port number of your target Service.
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
      ingressClassName: cce 

  3. Create an ingress.

    kubectl create -f ingress-test.yaml

    If information similar to the following is displayed, the ingress has been created:

    ingress/ingress-test created

  4. Check the created ingress.

    kubectl get ingress

    If information similar to the following is displayed, the ingress has been created:

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

  5. Use HTTPS to access the ingress. ${ELB_IP} specifies the IP address accessed by the target ingress.

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

    If the ingress can be accessed, the certificate is configured.

Configuring SNI Using an ELB Certificate

You can configure SNI using an ELB certificate for an ingress through either the CCE console or kubectl.

  • If both an ELB certificate and a TLS certificate are specified for the same ingress, the ingress will use the ELB certificate.
  • CCE does not check whether an ELB certificate is valid. It only checks whether the certificate is present.
  • Only ingresses in clusters of v1.19.16-r2, v1.21.5-r0, v1.23.3-r0, or later support ELB certificates.
  1. Log in to the CCE console and click the cluster name to access the cluster console.
  2. Choose Services & Ingresses in the navigation pane, click the Ingresses tab, and click Create Ingress in the upper right corner.
  3. Configure ingress parameters.

    This example explains only key parameters for configuring SNI certificates. You can configure other parameters as required. For details, see Creating a LoadBalancer Ingress on the Console.

    Table 2 Key parameters

    Parameter

    Description

    Example

    Name

    Enter an ingress name.

    ingress-test

    Load Balancer

    Select a load balancer to be associated with the ingress or automatically create a load balancer.

    Shared

    Listener

    • External Protocol: Select HTTPS.
    • External Port: specifies the port of the load balancer listener. The default HTTPS port is 443.
    • Certificate Source: Select ELB server certificate.
    • Server Certificate: Use a certificate created on ELB.

      If no certificate is available, go to the ELB console and create one. For details, see Adding a Certificate.

    • SNI: Select the corresponding SNI certificate, which must contain the domain name information.

      If no certificate is available, go to the ELB console and create one. For details, see Adding a Certificate.

    • External Protocol: HTTPS
    • External Port: 443
    • Certificate Source: ELB server certificate
    • Server Certificate: cert-test
    • SNI: cert-example

    Forwarding Policy

    • Domain Name: Enter an actual domain name to be accessed. If it is left blank, the ingress can be accessed through the IP address. Ensure that the domain name has been registered and licensed. Once a forwarding policy is configured with a domain name specified, you must use the domain name for access.
    • Path Matching Rule: Select Prefix match, Exact match, or RegEx match.
    • Path: Enter the path provided by a backend application for external access. The path added must be valid in the backend application, or the forwarding cannot take effect.
    • Destination Service: Select an existing Service or create a Service. Any Services that do not match the search criteria will be filtered out automatically.
    • Destination Service Port: Select the access port of the destination Service.
    • Domain Name: You do not need to configure this parameter.
    • Path Matching Rule: Prefix match
    • Path: /
    • Destination Service: nginx
    • Destination Service Port: 80
    Figure 2 Configuring SNI using a certificate from the ELB service

  4. Click OK.

To use an ELB certificate for an ingress, you can specify the kubernetes.io/elb.tls-certificate-ids annotation.

  1. Use kubectl to access the cluster. For details, see Connecting to a Cluster Using kubectl.
  2. Create a YAML file named ingress-test.yaml. The file name can be customized.

    vi ingress-test.yaml

    An example YAML file of an ingress associated with an existing load balancer is as follows:

    For clusters of v1.21 or earlier:

    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>  # Replace it with the name of your target Service.
              servicePort: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
    For clusters of v1.23 or later:
    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>  # Replace it with the name of your target Service.
                    port: 
                      number: 80             # Replace 80 with the port number of your target Service.
                property:
                  ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
                pathType: ImplementationSpecific
      ingressClassName: cce
    Table 3 Key parameters

    Parameter

    Type

    Description

    kubernetes.io/elb.tls-certificate-ids

    String

    ELB certificate IDs, which are separated by comma (,). The list length is greater than or equal to 1. The first ID in the list is the server certificate, and the other IDs are SNI certificates in which a domain name must be contained.

    If an SNI certificate cannot be found based on the domain name requested by the client, the server certificate will be returned by default.

    To obtain the certificate, log in to the CCE console, choose Service List > Networking > Elastic Load Balance, and click Certificates in the navigation pane. In the load balancer list, copy the ID under the target certificate name.

  3. Create an ingress.

    kubectl create -f ingress-test.yaml

    If information similar to the following is displayed, the ingress has been created:

    ingress/ingress-test created

  4. Check the created ingress.

    kubectl get ingress

    If information similar to the following is displayed, the ingress has been created:

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

  5. Use HTTPS to access the ingress. ${ELB_IP} specifies the IP address accessed by the target ingress.

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

    If the ingress can be accessed, the certificate is configured.