通过Ingress或AlbConfig为HTTPS监听配置证书

当您选择使用HTTPS协议的监听时,您需要为监听配置SSL/TLS证书以确保与客户端的加密连接。本文介绍ALB Ingress支持的多种配置证书的方法。

前提条件

重要

由于缺乏可靠的CA认证,自签名证书在浏览器和客户端中默认不受信任,通常会导致客户访问时收到安全警告。本文中生成的自签名证书仅作为示例,请勿在面向公众的生产环境中使用。

证书管理方式对比

ALB Ingress支持三种配置证书的方式:自动发现证书、Secret证书和AlbConfig指定证书。三种配置方式的区别如下。

说明

ALB Ingress不影响长链接。

对比项

自动发现证书

Secret证书

AlbConfig指定证书

关联资源

Ingress

Ingress

AlbConfig

存储方式

阿里云数字证书中心

集群内的Secret资源

阿里云数字证书中心

适用场景

适用于已在阿里云数字证书中心已购买证书或上传证书,并希望在Ingress级别进行证书管理的场景。

适用于集群内部管理的证书,例如使用cert-manager类的管理工具时,ALB实例证书会随着证书Secret的更新而更新。

适用于已在阿里云数字证书中心已购买证书或上传证书,并希望在ALB实例级别进行证书管理的场景。

优先级(仅供参考)

跨命名空间使用

支持

不支持,仅支持在Secret资源所处的命名空间使用。

支持

更新证书方式

在数字证书中心上传新证书或续费证书后,更新Ingress资源。

更新Ingress关联的Secret资源。

在数字证书中心上传新证书或续费证书后,更新AlbConfig资源。

证书管理方式兼容性说明

在ALB Ingress中,如果您同时使用了多种证书配置方式时,证书的管理方式和兼容性如下所示。

证书配置

说明

在Ingress资源中同时定义了自动发现证书和Secret证书

  • 如果自动发现证书和Secret证书属于同一域名,那么Secret证书具有更高的优先级。

  • 如果自动发现证书和Secret证书属于不同的域名,那么ALB Ingress Controller会为每个域名分别选择相应的证书。

在Ingress资源中同时定义了自动发现证书和AlbConfig指定证书,并且它们关联的Listener相同

  • 如果在AlbConfig中指定了证书,则同监听下不会使用自动发现证书。

  • 如果未在AlbConfig中指定证书,则会尝试执行自动发现证书流程。

在Ingress资源中同时定义了Secret证书和在AlbConfig指定证书

AlbConfig指定证书和Secret证书是可以完全兼容的,并且可以同时使用。

创建前置资源

您需要Deployment、Service、AlbConfig、IngressClass、Ingress这5种资源才能使ALB Ingress工作,您可以使用以下的示例快速创建这5种资源。

  1. 创建https-quickstart.yaml文件,并将以下内容拷贝到该文件中。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: https-deploy
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: https-deploy
      template:
        metadata:
          labels:
            app: https-deploy
        spec:
          containers:
            - image: registry.cn-hangzhou.aliyuncs.com/alb-sample/cafe:v1
              imagePullPolicy: IfNotPresent
              name: https-deploy
              ports:
                - containerPort: 8080
                  protocol: TCP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: https-svc
      namespace: default
    spec:
      ports:
        - name: port1
          port: 443
          protocol: TCP
          targetPort: 8080
      selector:
        app: https-deploy
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      name: https-ingressclass
    spec:
      controller: ingress.k8s.alibabacloud/alb
      parameters:
        apiGroup: alibabacloud.com
        kind: AlbConfig
        name: alb-demo # 修改为您的AlbConfig资源的名称
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: https-ingress
      namespace: default
    spec:
      ingressClassName: https-ingressclass
      rules:
      - host: demo.alb.ingress.top # demo.alb.ingress.top可以替换为您的域名
        http:
          paths:
          - backend:
              service:
                name: https-svc
                port:
                  number: 443
            path: /
            pathType: Prefix
  2. 执行以下命令创建服务。

    kubectl apply -f https-quickstart.yaml

(可选)生成自签名证书

如果您还未获取证书,您可以执行以下命令,通过OpenSSL创建自签名证书。

openssl genrsa -out albtop-key.pem 4096
openssl req -subj "/CN=demo.alb.ingress.top" -sha256  -new -key albtop-key.pem -out albtop.csr  # demo.alb.ingress.top可以替换为您的域名
echo subjectAltName = DNS:demo.alb.ingress.top > extfile.cnf  # demo.alb.ingress.top可以替换为您的域名
openssl x509 -req -days 3650 -sha256 -in albtop.csr -signkey albtop-key.pem -out albtop-cert.pem -extfile extfile.cnf
说明

命令中的demo.alb.ingress.top是自签名证书所关联的域名。如果您拥有域名,请您进行替换。如果您未拥有域名,可以不进行替换,不影响本文后续步骤。

使用自动发现证书

说明

同一个ALB支持的扩展证书上限为25个,包含同域名的证书总数不能超过该阈值。

  1. 将自签名证书上传至阿里云数字证书中心。具体操作,请参见上传和共享SSL证书

  2. 更新Ingress配置。

    1. 执行以下命令更新Ingress配置。

      kubectl edit ingress https-ingress
    2. 在https-quickstart.yaml的Ingress部分中添加tls字段,填入证书关联的域名并保存退出。

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: https-ingress
        namespace: default
      spec:
        ingressClassName: alb
        rules:
        - host: demo.alb.ingress.top # demo.alb.ingress.top可以替换为您的域名
          http:
            #...
        tls:
        - hosts:
          - demo.alb.ingress.top # 需要和“host“字段中的域名保持一致,同时是证书关联的域名
  3. 执行以下命令,验证证书是否配置成功。

    curl https://demo.alb.ingress.top/tea

    预期输出:

    {"hello":"tee"}

    返回以上结果,说明证书配置成功。

使用Secret证书

以下以自签名证书为例,介绍如何配置Secret证书。

说明

同一证书支持创建不同的Secret,ALB也支持关联多个证书,但同一ALB支持的扩展证书上限为25个。

  1. 执行以下命令,使用OpenSSL创建自签名证书。

    openssl genrsa -out albtop-key.pem 4096
    openssl req -subj "/CN=demo.alb.ingress.top" -sha256  -new -key albtop-key.pem -out albtop.csr
    echo subjectAltName = DNS:demo.alb.ingress.top > extfile.cnf
    openssl x509 -req -days 3650 -sha256 -in albtop.csr -signkey albtop-key.pem -out albtop-cert.pem -extfile extfile.cnf
  2. Base64编码步骤1中的albtop-key.pem和albtop-cert.pem。

    echo -n `cat albtop-key.pem` | base64
    echo -n `cat albtop-cert.pem`  | base64
  3. 创建Secret。

    1. 创建secret.yaml,代码示例如下。

      apiVersion: v1
      kind: Secret
      metadata:
        name: secret-tls
      type: kubernetes.io/tls
      data:
        # the data is abbreviated in this example
        tls.crt: |
          {base64 albtop-cert.pem} # Base64编码后的albtop-cert.pem。
        tls.key: |
          {base64 albtop-key.pem}  # Base64编码后的albtop-key.pem。
    2. 执行以下命令,创建Secret。

      kubectl apply -f secret.yaml
  4. 创建Ingress、Service和应用。

    1. 创建demo.yaml,代码示例如下。

      在Ingress的YAML中添加证书对应的域名。

      tls:
        - hosts:
          - demo.alb.ingress.top
          secretName: secret-tls

      展开查看示例代码

      apiVersion: v1
      kind: Service
      metadata:
        name: demo-service-https
        namespace: default
      spec:
        ports:
          - name: port1
            port: 443
            protocol: TCP
            targetPort: 8080
        selector:
          app: demo-cafe
        sessionAffinity: None
        type: ClusterIP
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: demo-cafe
        namespace: default
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: demo-cafe
        template:
          metadata:
            labels:
              app: demo-cafe
          spec:
            containers:
              - image: registry.cn-hangzhou.aliyuncs.com/alb-sample/cafe:v1
                imagePullPolicy: IfNotPresent
                name: demo-cafe
                ports:
                  - containerPort: 8080
                    protocol: TCP
      ---
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: demo-https
        namespace: default
      spec:
        ingressClassName: alb
        rules:
        - host: demo.alb.ingress.top
          http:
            paths:
            - backend:
                service:
                  name: demo-service-https
                  port:
                    number: 443
              path: /
              pathType: Prefix
        tls:
        - hosts:
          - demo.alb.ingress.top
          secretName: secret-tls
    2. 执行以下命令,创建Ingress、Service和应用。

      kubectl apply -f demo.yaml
  5. 执行以下命令,验证证书是否配置成功。

    curl https://demo.alb.ingress.top/tea

    预期输出:

    {"hello":"tee"}

    返回以上结果,说明证书配置成功。

使用AlbConfig指定证书

以下以自签名证书为例,介绍如何使用AlbConfig指定证书。

说明

如果监听配置了证书ID,那么相同监听下的域名不会再使用Secret证书和自动发现证书。

  1. 执行以下命令,通过OpenSSL创建自签名证书。

    openssl genrsa -out albtop-key.pem 4096
    openssl req -subj "/CN=demo.alb.ingress.top" -sha256  -new -key albtop-key.pem -out albtop.csr
    echo subjectAltName = DNS:demo.alb.ingress.top > extfile.cnf
    openssl x509 -req -days 3650 -sha256 -in albtop.csr -signkey albtop-key.pem -out albtop-cert.pem -extfile extfile.cnf
  2. 上传自签名证书至阿里云数字证书中心。具体操作,请参见上传和共享SSL证书

  3. 获取证书ID。

    1. 登录数字证书管理服务控制台

    2. 在控制台左侧导航栏,单击SSL 证书

    3. SSL证书页面,单击上传证书页签,在目标证书操作列下选择图标 > 详情

      证书详情面板中获取证书ID。

  4. 关联证书至AlbConfig。

    未创建AlbConfig场景

    1. 创建albconfig.yaml,代码示例如下。

      apiVersion: alibabacloud.com/v1
      kind: AlbConfig
      metadata:
        name: alb-demo
      spec:
        config:
          #...
        listeners:
        - caEnabled: false
          certificates:
          - CertificateId: 756****-cn-hangzhou # 证书ID
            IsDefault: true
          port: 443
          protocol: HTTPS
        #...

      参数

      说明

      caEnabled

      是否开启TLS握手过程中有效证书的身份验证。本示例配置false,表示不需要客户端的身份验证。

      CertificateId

      证书ID。本示例配置为756****-cn-hangzhouCertificateId格式示例及说明如下:

      • 中国地域:756****-cn-hangzhou-cn-hangzhou为固定内容,不受地域影响,配置时您只需替换756****即可。

      • 海外地域:756****-ap-southeast-1-ap-southeast-1为固定内容,不受地域影响,配置时您只需替换756****即可。

      IsDefault

      是否为默认证书。本文配置为true,表示是默认证书。

      protocol

      支持监听的协议类型。本文配置为HTTPS,表示支持HTTPS协议的监听。

    2. 执行以下命令,创建AlbConfig。

      kubectl apply -f albconfig.yaml

    已创建AlbConfig场景

    通过kubectl edit命令进行增量更新。

    1. 执行以下命令,查看AlbConfig名称。

      kubectl -n kube-system get AlbConfig

      预期输出:

      NAME AGE
      alb-demo 87m
    2. 执行以下命令,更新对应AlbConfig。

      kubectl -n kube-system edit AlbConfig alb-demo
        #...
        spec:
          config:
            #...
          listeners:
          - caEnabled: false
            certificates:
            - CertificateId: 756****-cn-hangzhou # 证书ID
              IsDefault: true
            port: 443
            protocol: HTTPS
            #...

    更多关于更新AlbConfig的信息,请参见更新AlbConfig

  5. 创建Ingress、Service和应用。

    1. 创建demo.yaml,代码示例如下

      说明

      本例Ingress中的tls字段只作为挂载到443监听标识,并不是自动发现证书的配置。

      展开查看示例代码

      apiVersion: v1
      kind: Service
      metadata:
        name: demo-service-https
        namespace: default
      spec:
        ports:
          - name: port1
            port: 443
            protocol: TCP
            targetPort: 8080
        selector:
          app: demo-cafe
        sessionAffinity: None
        type: ClusterIP
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: demo-cafe
        namespace: default
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: demo-cafe
        template:
          metadata:
            labels:
              app: demo-cafe
          spec:
            containers:
              - image: registry.cn-hangzhou.aliyuncs.com/alb-sample/cafe:v1
                imagePullPolicy: IfNotPresent
                name: demo-cafe
                ports:
                  - containerPort: 8080
                    protocol: TCP
      ---
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: demo-https
        namespace: default
      spec:
        ingressClassName: alb
        rules:
        - host: demo.alb.ingress.top
          http:
            paths:
            - backend:
                service:
                  name: demo-service-https
                  port:
                    number: 443
              path: /
              pathType: Prefix
        tls:
        - hosts:
          - demo.alb.ingress.top
    2. 执行以下命令,创建Ingress、Service和应用。

      kubectl apply -f demo.yaml
  6. 执行以下命令,验证证书是否配置成功。

    curl https://demo.alb.ingress.top/tea

    预期输出:

    {"hello":"tee"}

(可选)释放资源

执行以下命令,您可以释放在本文中创建的资源。

kubectl delete deployment https-deploy
kubectl delete service https-svc
kubectl delete ingressclass https-ingressclass
kubectl delete ingress https-ingress
rm https-quickstart.yaml