由于证书管理器HTTP01 ACME挑战,Istio Gateway和Kubernetes Ingress在同一主机名上



我部署了一个Istio Service Mesh,并使用其网关控制器进行入口。我设置了证书管理器,它将ssl证书传递到网关。使用自签名证书,这种设置可以很好地工作,但在使用letsencrypt时,我在证书管理器的自动临时入口和istio网关之间存在冲突。

以下是httpbin:的最终设置

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
annotations:
meta.helm.sh/release-name: httpbin-ingress
meta.helm.sh/release-namespace: httpbin
creationTimestamp: "2022-10-13T08:07:33Z"
generation: 1
labels:
app.kubernetes.io/managed-by: Helm
name: httpbin-ingress
namespace: istio-ingress
resourceVersion: "5243"
uid: d4087649-2609-40c0-8d4a-55b9a420fda9
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- httpbin.example.com
port:
name: http
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- httpbin.example.com
port:
name: https
number: 443
protocol: HTTPS
tls:
credentialName: httpbin-ssl-certificate-secret
mode: SIMPLE
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
meta.helm.sh/release-name: httpbin-ingress
meta.helm.sh/release-namespace: httpbin
creationTimestamp: "2022-10-13T08:07:33Z"
generation: 1
labels:
app.kubernetes.io/managed-by: Helm
name: httpbin-ingress
namespace: istio-ingress
resourceVersion: "5246"
uid: ef5b6397-2c7a-408c-b142-4528e8f28a20
spec:
gateways:
- httpbin-ingress
hosts:
- httpbin.example.com
http:
- match:
- uri:
prefix: /outpost.goauthentik.io
route:
- destination:
host: authentik.authentik.svc.cluster.local
port:
number: 80
- match:
- uri:
regex: ^/[^.]+.*
- uri:
exact: /
route:
- destination:
host: httpbin.httpbin.svc.cluster.local
port:
number: 14001
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: istio
nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0,::/0
creationTimestamp: "2022-10-13T08:07:38Z"
generateName: cm-acme-http-solver-
generation: 1
labels:
acme.cert-manager.io/http-domain: "1703151793"
acme.cert-manager.io/http-token: "1233129203"
acme.cert-manager.io/http01-solver: "true"
name: cm-acme-http-solver-gtgxg
namespace: istio-ingress
ownerReferences:
- apiVersion: acme.cert-manager.io/v1
blockOwnerDeletion: true
controller: true
kind: Challenge
name: httpbin-ssl-certificate-ct48l-1136457683-1300359052
uid: dd19a50c-5944-46b8-ae09-8345bef9c114
resourceVersion: "5308"
uid: 5d5578a5-3371-4705-9a8c-e031be5f4d7c
spec:
rules:
- host: httpbin.example.com
http:
paths:
- backend:
service:
name: cm-acme-http-solver-rkr2g
port:
number: 8089
path: /.well-known/acme-challenge/YKCZwQz6T9HezJtPwzev-esq-Q4WaLHoUC_CafmPJUk
pathType: ImplementationSpecific
status:
loadBalancer: {}

我面临的问题如下。使用此设置:

  • curl --resolve httpbin.example.com:443:127.0.0.1 https://httpbin.example.com/ -k起作用
  • curl --resolve httpbin.example.com:443:127.0.0.1 https://httpbin.example.com/.well-known/acme-challenge/YKCZwQz6T9HezJtPwzev-esq-Q4WaLHoUC_CafmPJUk -Ik给出http代码404
  • 如果我删除网关httpbin-ingress,则curl --resolve httpbin.example.com:80:127.0.0.1 http://httpbin.example.com/.well-known/acme-challenge/YKCZwQz6T9HezJtPwzev-esq-Q4WaLHoUC_CafmPJUk -Ik以http代码200按预期工作

证书管理器的证书资源用进行注释

cert-manager.io/issue-temporary-certificate: "true"

这是有效的(网关是用自签名证书设置的,直到letsencrypt成功(,所以我使用httpsRedirect: true这一事实不应该是罪魁祸首。

我的问题是:是否有可能让网关就位让证书管理器成功应对HTTP01挑战?我的想法是,在获得"/"的网关前向流量时,一定有我忽略的地方。知名/"到证书管理器的入口。

我看了这个问题,使用网关+VirtualService+http01+SDS,但我找不到我的配置有什么不同。我尝试将80端口上的网关协议从HTTP更改为HTTP2,并将curl--http1.1一起更改为.已知路径,但这并没有解决问题。

对我来说,最终的解决方案是:

  • 将CCD_ 8主机添加到每个网关的端口80上的服务器
  • 放弃使用内置的CCD_ 9功能
  • 并为http到https编写一个稍微更手动的重定向规则,该规则只匹配非ACME路径

除非主机名包括*,否则似乎不能为同一端口和主机名拥有多个Istio网关。如果我错了,有人纠正我。

我现在的配置是:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
annotations:
meta.helm.sh/release-name: httpbin-ingress
meta.helm.sh/release-namespace: httpbin
creationTimestamp: "2022-10-13T13:24:27Z"
generation: 1
labels:
app.kubernetes.io/managed-by: Helm
name: httpbin-ingress
namespace: istio-ingress
resourceVersion: "54782"
uid: d36977db-20a2-4d43-a137-ba4cbfeccf8d
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
- httpbin.example.com
port:
name: http
number: 80
protocol: HTTP
- hosts:
- httpbin.example.com
port:
name: https
number: 443
protocol: HTTPS
tls:
credentialName: httpbin-ssl-certificate-secret
mode: SIMPLE
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
meta.helm.sh/release-name: httpbin-ingress
meta.helm.sh/release-namespace: httpbin
creationTimestamp: "2022-10-13T13:24:27Z"
generation: 1
labels:
app.kubernetes.io/managed-by: Helm
name: httpbin-ingress
namespace: istio-ingress
resourceVersion: "54783"
uid: 3a1d988c-c287-49a8-942a-9aaf41a4b2b5
spec:
gateways:
- httpbin-ingress
hosts:
- httpbin.example.com
http:
- match:
- headers:
x-forwarded-proto:
exact: https
uri:
prefix: /outpost.goauthentik.io
route:
- destination:
host: authentik.authentik.svc.cluster.local
port:
number: 80
- match:
- headers:
x-forwarded-proto:
exact: https
uri:
regex: ^/[^.]+.*
- headers:
x-forwarded-proto:
exact: https
uri:
exact: /
route:
- destination:
host: httpbin.httpbin.svc.cluster.local
port:
number: 14001
- match:
- headers:
x-forwarded-proto:
exact: http
uri:
regex: ^/[^.]+.*
- headers:
x-forwarded-proto:
exact: http
uri:
exact: /
- headers:
x-forwarded-proto:
exact: http
uri:
exact: /
redirect:
scheme: https

并且没有必要从证书管理器转发生成的入口,因为这并没有改变!

正如你所看到的,我对VirtualService进行了大量的阐述,其中每个匹配现在都显式地验证协议(http与https(,匹配http的行只适用于与ACME挑战不匹配的路径(/.aknowledge…(

如果您的服务使用以句点开头的路径,那么您将不得不向匹配添加更多规则,以避免匹配ACME,但允许使用.-路径。

PS如果有人知道一个更智能的RE2正则表达式,它可以放在一行中,请告诉我!

相关内容

  • 没有找到相关文章

最新更新