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

nic*_*asl 4 wildcard-subdomain kubernetes lets-encrypt kubernetes-ingress cert-manager

我已经使用 cert-manager 和letsencrypt 将我的 Kubernetes 配置为对我的所有应用程序使用一个通配符 SSL 证书,现在的问题是我无法配置子域重定向,因为 Ingress 有点“僵硬”。这是我试图实现这一目标的方法:

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"
Run Code Online (Sandbox Code Playgroud)

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

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

nic*_*asl 8

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

At this point, any requests to your domain, will be redirected to "some-default-service" with SSL(cert-manager will issue for a new cert as soon as you create the fallback ingress. This can take a while once cert-manager dns01 issuer is not mature yet), great!!!

But, what if you need to redirect some specific subdomain to another service? No problem (since they're running on the same namespace), all you have to do is to create a new ingress to your subdomain, pointing it to your existing 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
Run Code Online (Sandbox Code Playgroud)

Easy peasy lemon squeezy!!! Now your somesubdomain.mydomain.com overrides your fallback rule and sends the user to another app. The only thing you should notice here is that the secret is valid only for "some-namespace" namespace, if you need to use this cert in another namespace, you could:

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

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

干杯