Kubernetes 中具有子域重定向的通配符 SSL 证书

Wildcard SSL certificate with subdomain redirect in Kubernetes

我已经使用 cert-manager 和 letsencrypt 配置我的 Kubernetes 以对我的所有应用程序使用一个通配符 SSL 证书,现在的问题是我无法配置子域重定向,因为 Ingress 有点 "stiff"。以下是我尝试实现此目标的方法:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-wildcard-ingress
  namespace: mynamespace
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    certmanager.k8s.io/acme-challenge-type: dns01
    certmanager.k8s.io/acme-dns01-provider: azuredns
    ingress.kubernetes.io/force-ssl-redirect: "true"
    ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: "domain.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: some-service
          servicePort: 3000          
  - host: somesub.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: some-other-service
          servicePort: 80
  - host: othersub.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: one-more-service
          servicePort: 8080          
  - host: "*.domain.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: default-service-to-all-other-non-mapped-subdomains
          servicePort: 8000          

  tls:
  - secretName: domain-com-tls
    hosts:         
     - "*.domain.com.br"

问题是 Ingress 忽略声明的子域重定向只是因为它们没有在 "tls:hosts" 部分中列出。如果我确实将它们放在那里,它会尝试使用通配符和其他子域以及同一证书中的其他子域来颁发 SSL 证书,这会导致颁发者拒绝订单,说显而易见的:"subdomain.domain.com and *.domain.com are redundant"

有没有其他方法可以声明这些重定向并强制它们使用我的 SSL 通配符证书?

所以最好的做法可能就是不使用 ingress-shim 来管理您的证书资源。

相反,您可以手动创建一个证书资源,然后在您的所有入口中引用它产生的秘密。

我们目前正在探索解决此入口限制的选项,但到目前为止没有任何进展!

好吧,对于遇到这种麻烦的任何人,我已经设法解决了它(不是最好的解决方案,但这是一个开始)。为此,我将使用 cert-manager 和 letsencrypt。

首先,我创建了一个 ClusterIssuer 来使用 letsencrypt 为我的证书颁发:

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:      
  name: letsencrypt-prod-dns
spec:
  acme:
    dns01:
      providers:
      - azuredns:
          clientID: MY_AZURE_CLIENT_ID
          clientSecretSecretRef:
            key: client-secret
            name: azure-secret
          hostedZoneName: mydomain.com
          resourceGroupName: MY_AZURE_RESOURCE_GROUP_NAME
          subscriptionID: MY_AZURE_SUBSCRIPTION_ID
          tenantID: MY_AZURE_TENANT_ID
        name: azuredns
    email: somemail@mydomain.com
    privateKeySecretRef:
      key: ""
      name: letsencrypt-prod-dns
    server: https://acme-v02.api.letsencrypt.org/directory

然后我为我的所有子域创建了一个回退入口(这个将是证书生成器):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    certmanager.k8s.io/acme-challenge-type: dns01
    certmanager.k8s.io/acme-dns01-provider: azuredns
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod-dns
    ingress.kubernetes.io/force-ssl-redirect: "true"
    ingress.kubernetes.io/ssl-redirect: "true"    
    kubernetes.io/ingress.class: nginx    
  name: wildcard-ingress
  namespace: some-namespace  
spec:
  rules:
  - host: '*.mydomain.com'
    http:
      paths:
      - backend:
          serviceName: some-default-service
          servicePort: 80
        path: /      
  tls:
  - hosts:
    - '*.mydomain.com'
    - mydomain.com
    secretName: wildcard-mydomain-com-tls

请注意,我已经在 TLS 部分声明了通配符和绝对路径,因此证书对于没有子域的 URL 也有效。

此时,对您域的任何请求都将通过 SSL 重定向到 "some-default-service"(证书管理器将在您创建回退入口后立即颁发新证书。这可能需要一段时间一旦 cert-manager dns01 issuer 尚未成熟),太棒了!!!

但是,如果您需要将某个特定的子域重定向到另一个服务怎么办?没问题(因为它们在同一个命名空间上 运行),您所要做的就是为您的子域创建一个新的入口,将其指向您现有的 wildcard-mydomain-com-tls cert secret:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/force-ssl-redirect: "false"
    ingress.kubernetes.io/ssl-redirect: "true"
    kubernetes.io/ingress.class: nginx
  name: somesubdomain-ingress
  namespace: some-namespace
spec:
  rules:
  - host: somesubdomain.mydomain.com
    http:
      paths:
      - backend:
          serviceName: some-other-service
          servicePort: 8080
        path: /        
  tls:
  - hosts:
    - somesubdomain.mydomain.com
    secretName: wildcard-mydomain-com-tls

轻松榨柠檬!!!现在你的 somesubdomain.mydomain.com 覆盖你的后备规则并将用户发送到另一个应用程序。在这里你唯一应该注意的是这个秘密只对 "some-namespace" 命名空间有效,如果你需要在另一个命名空间中使用这个证书,你可以:

  1. 将密钥从命名空间 "some-namespace" 复制到 "other-namespace"。如果您这样做,请记住 cert-manager 不会为 "other-namespace" 自动更新此证书,因此,每次您的证书过期时,您都必须再次复制密钥。
  2. 为您拥有的每个命名空间重新创建回退入口,这样您就可以为每个命名空间创建一个新证书。这种方法更加冗长,但它是全自动的。

我想就是这样。希望有人可以从这些信息中受益。

干杯