我已经使用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"
问题是Ingress忽略了声明的子域重定向,只是因为它们没有列在"tls:hosts"部分中。如果我真的把它们放在那里,它会尝试使用通配符和同一证书中的其他子域颁发SSL证书,这会导致颁发者拒绝订单,并说显而易见的话:"子域.domain.com和*.domain.com是多余的">
有没有其他方法可以声明这些重定向并强制它们使用我的SSL通配符证书?
好吧,对于任何遇到这种麻烦的人来说,我已经设法解决了它(不是最好的解决方案,但这是一个开始(。为此,我将使用证书管理器和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的"一些默认服务"(证书管理器将在您创建回退入口后立即发布新的证书。一旦证书管理器dns01颁发者尚未成熟,这可能需要一段时间(,太好了!!!
但是,如果您需要将某些特定子域重定向到另一个服务,该怎么办?没问题(因为它们在同一个命名空间上运行(,你所要做的就是创建一个新的子域入口,将其指向你现有的通配符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"复制到"other namespace"。如果您这样做,请记住,证书管理器不会自动为"其他命名空间"续订此证书,因此,每次证书过期时,您都必须再次复制机密
- 重新创建每个命名空间的回退入口,这样每个命名空间都有一个新的证书。这种方法更为冗长,但它是完全自动的
我想就是这样。希望有人能从这些信息中受益。
干杯
因此,这里最好的做法可能是不使用ingress填充程序来管理证书资源。
相反,您可以手动创建一个证书资源,然后引用它在所有入侵中产生的秘密。
目前,我们正在探索解决入侵限制的方法,但到目前为止还没有任何进展!