通过Nginx入口控制器公开Prometheus Web UI的问题

时间:2020-08-03 10:41:52

标签: nginx prometheus kubernetes-ingress azure-aks azure-kubernetes

我不知道我的案件有什么问题。 我在AKS(Azure的k8s)上部署了Prometheus服务器,并希望通过用于以下配置的入口控制器公开Prometheus Web UI。

我也参考这个

https://coreos.com/operators/prometheus/docs/latest/user-guides/exposing-prometheus-and-alertmanager.html

# Prometheus
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
  namespace: monitoring
spec:
  version: v2.13.1
  replicas: 2
  retention: 1d
  serviceAccountName: prometheus
  ...
# Service
apiVersion: v1
kind: Service
metadata:
  name: prometheus-service
  namespace: monitoring
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 9090
  selector:
    app: prometheus
# Ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: nginx
#    nginx.ingress.kubernetes.io/ssl-redirect: "false"
#    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
# Just try another subpath make sure the nginx is work
#      - backend:
#          serviceName: aks-helloworld-one
#          servicePort: 80
#        path: /hello-world-one
      - backend:
          serviceName: prometheus-service
          servicePort: 80
        path: /prometheus

我在测试阶段添加了另一条路径,nginx在aks-helloworld-one上成功运行。 但是,它不适用于Prometheus服务器,总会得到“找不到404页”的信息。 有人知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

我认为问题在于您的重写目标和路径,您可以尝试使用子域而不是路径进行确认吗?我在子网域上使用了以下Prometheus Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/force-ssl-redirect: "true"
    ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: nginx-ingress
  name: prometheus-monitoring
  namespace: monitoring
spec:
  backend:
    serviceName: prometheus
    servicePort: 9090   #As my service is listening on 9090
  rules:
  - host: prometheus-monitoring.DOMAIN
    http:
      paths:
      - backend:
          serviceName: prometheus
          servicePort: 9090   #As my service is listening on 9090
        path: /

下面是我的服务清单

apiVersion: v1
kind: Service
metadata:
  labels:
    app: prometheus
    chart: prometheus-operator-5.11.0
    heritage: Tiller
  name: prometheus
  namespace: monitoring
spec:
  ports:
  - name: web
    port: 9090
    protocol: TCP
    targetPort: 9090
  selector:
    app: prometheus
    prometheus: k8s
  sessionAffinity: None
  type: ClusterIP

答案 1 :(得分:0)

我想我知道问题出在哪里。其实我以前的评论是错误的:

如果在/下可用,则无需在入口中进行任何重写 而且应该可以立即使用。

嗯...实际上不会有一个简单的原因。当您尝试通过入口访问Prometheus UI时,将使用<ingress ip>/prometheus URL。选择/prometheus路径会将您正确地重定向到适当的后端Service

      - backend:
          serviceName: prometheus-service
          servicePort: 80
        path: /prometheus

但是发生问题是因为/prometheus路径(您需要重定向到prometheus-service并最终重定向到Pods之一,由此Service公开)会转发到提供实际内容的目标Pod

您收到404 page not found错误消息,因为到达目标Web服务器的http请求声明的是/prometheus目录的内容,而不是实际从其提供服务的/的目录。

因此,如果您将入口更改为以下形式:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: prometheus-service
          servicePort: 80
        path: /

很可能一切都会按预期运行,您将获得 Prometheus UI 网站,而不是404 Not found

好吧,尽管它可能会起作用,但它仅用于调试目的,因为没有人愿意使用 ingress 只是为了能够在根路径下公开某些内容。

以下入口定义应该可以解决您的问题(是的,在这种情况下,必须进行重写!)

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: prometheus-service
          servicePort: 80
        path: /prometheus(/|$)(.*)
上面使用的

重写将确保原始访问路径/prometheus在到达目标/之前被重写为Pod