描述问题:
有一个带有单个节点的裸金属Kubernetes集群,安装了用于将流量路由到集群的部署MetalLB和Nginx Ingress Controller。
- Kubernetes v1.28.3
- MetalLB v0.13.12
- Nginx Ingress Controller v1.8.0
- 证书管理器v1.13.2
我创建了一个Ingress资源来将请求路由到集群中部署的ArgoCD示例,并安装了用于TLS证书管理的证书管理器Helm chart。
看起来已正确安装了安全问题解决器。
$ kubectl get clusterissuer -o wide
NAME READY STATUS AGE
letsencrypt-production True The ACME account was registered with the ACME server 4d1h
letsencrypt-staging True The ACME account was registered with the ACME server 4d1h
selfsigned True 4d1h
字符串
这是为ArgoCD部署声明的Ingress资源的内容。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
labels:
app.kubernetes.io/component: server
app.kubernetes.io/environment: develop
app.kubernetes.io/instance: argocd
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: argocd-server
app.kubernetes.io/part-of: argocd
app.kubernetes.io/version: v2.8.6
helm.sh/chart: argo-cd-5.50.1
name: argocd-server
namespace: develop
spec:
ingressClassName: nginx
rules:
- host: argocd.mydomain.com
http:
paths:
- backend:
service:
name: argocd-server
port:
number: 443
path: /
pathType: Prefix
tls:
- hosts:
- argocd.mydomain.com
secretName: argocd-secret
型
但是ACME挑战无法完成,并且资源挑战、订单和证书停留在 * 待定 * 状态。
正在等待HTTP-01质询传播:无法执行自检GET请求“http://argocd.mydomain.com/.well-known/acme-challenge/Scy7Eh4E8LvN6yM1rT3y4qcCYKfEVZ6MHJdQNqKJN7M”。
获取“http://argocd.mydomain.com/.well-known/acme-challenge/Scy7Eh4E8LvN6yM1rT3y4qcCYKfEVZ6MHJdQNqKJN7M“:超过上下文截止日期(等待标头时超过客户端. xml)
有趣的事情开始了,如果我在集群外的机器上对该url执行curl命令,它会工作,我会得到响应。但是如果我从节点或集群内的另一个pod执行,我会得到超时。
看起来不是网络中的DNS问题,因为从集群内的节点或容器执行nslookup命令工作正常:
$ nslookup argocd.mydomain.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
argocd.mydomain.com canonical name = mydoamin.com.
Name: mydomain.com
Address: xx.xx.xx.xx
型
从节点执行curl请求,在任何容器之外,使用网络中节点的IP,响应是OK的。
curl http://192.168.1.1/.well-known/acme-challenge/Scy7Eh4E8LvN6yM1rT3y4qcCYKfEVZ6MHJdQNqKJN7M -H "Host: argocd.mydomain.com"
型
但是,将本地IP地址替换为IP地址,我得到了超时。
以下是Ingress Nginx控制器服务的规范:
spec:
allocateLoadBalancerNodePorts: true
clusterIP: 10.96.108.180
clusterIPs:
- 10.96.108.180
externalTrafficPolicy: Local
healthCheckNodePort: 30708
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- appProtocol: http
name: http
nodePort: 31629
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
nodePort: 30634
port: 443
protocol: TCP
targetPort: https
型
- cm-acme-http-solver* 在ingress的同一个命名空间中创建,日志条目如下:
I1113 18:50:06.845744 1 solver.go:87]
cert-manager/acmesolver: got successful challenge request, writing key" host="mydomain.com" path="/.well-known/acme-challenge/1yJeWYLrQ_EP5MjWH_0Ztq8NodV81kaFkPHQ6Kz41CM" base_path="/.well-known/acme-challenge" token="1yJeWYLrQ_EP5MjWH_0Ztq8NodV81kaFkPHQ6Kz41CM
型
可能我放弃了CNI的任何意外行为,替换了weave-net并使用了Calico,我有同样的行为。而且看起来不像DNS问题,因为DNS条目可以在网络中的集群内部或外部解析。如果使用Public IP执行curl命令失败:
curl -v -D- http://public.ip/.well-known/acme-challenge/1yJeWYLrQ_EP5MjWH_0Ztq8NodV81kaFkPHQ6Kz41CM
型
但是用网络中LoadBalancer服务的私有IP替换公共IP可以正常工作。
有谁可以指导或帮助我解决这个问题吗?
1条答案
按热度按时间sr4lhrrt1#
cm-acme-http-solver* 是在ingress的同一名称空间中创建的
正在创建
cm-acme-http-solver
pod并记录成功的质询请求是一个好迹象。这表明cert-manager正在运行并能够响应ACME质询请求。但是,当这些质询请求来自集群外部时,问题似乎在于这些质询请求的路由。从互联网到Kubernetes集群的流量看起来像这样:
字符串
MetalLB LoadBalancer负责将外部流量路由到集群内的正确服务。然后Nginx Ingress Controller将此流量路由到相应的Ingress资源,在本例中为ArgoCD service。
处理ACME质询请求的
cm-acme-http-solver
pod正在记录成功的质询请求,这表明它在群集中正常工作。但是,将外部请求路由到
cm-acme-http-solver
存在一个问题,特别是在使用公共IP时。使用LoadBalancer服务的私有IP成功进行
curl
测试,但使用公共IP失败,表明外部流量路由到群集的方式可能存在问题。这可能是MetalLB的配置问题,或者是您的网络处理路由到群集的流量的方式。由于MetalLB被用作LoadBalancer,因此请确保它被正确配置为处理公共和私有IP地址。MetalLB应将公共IP上的传入流量正确路由到集群内的相应服务。
型
检查Nginx Ingress Controller是否正确配置为处理来自LoadBalancer的流量。这包括确保SSL passthrough按预期工作。
仔细检查是否有任何网络限制(如防火墙规则或网络安全组设置)可能会阻止公共IP上的传入流量。
您可能需要跟踪网络数据包以查看路由失败的位置。
tcpdump
或traceroute
等工具应该会有所帮助。型
此外,请更详细地查看cert-manager挑战和日志,以确认挑战确实到达了群集并得到了正确的响应。
型
在集群中,我将CNI更改为Calico,并将入口更改为HAProxy,行为是相同的,唯一的区别是我可以使用HTTPS从集群中的Pod内的ACME获得响应,但通过HTTP它仍然会给我超时。
你必须验证SSL直通配置。我记得这里有一些与Weave和Calico兼容的问题metallb.universe.tf/installation/network-addons。
随着向HA Proxy, make sure SSL passthrough is configured correctly的转变,HAProxy处理SSL直通的方式与Nginx不同,确保SSL流量正确转发到后端而不会在Ingress级别终止至关重要。
检查HA Proxy configuration以确保其正确设置为处理HTTP和HTTPS流量。此外,检查日志中的任何错误或警告。
型
Calico提供强大的network policy enforcement。验证没有策略无意中阻止或错误路由HTTP流量。检查入口和出口策略。
型