【问题标题】:How do I access this Kubernetes service via kubectl proxy?如何通过 kubectl 代理访问这个 Kubernetes 服务?
【发布时间】:2017-12-23 15:07:29
【问题描述】:

我想通过kubectl proxy server 访问我的 Grafana Kubernetes 服务,但由于某种原因,即使我可以让它为其他服务工作,它也无法工作。鉴于以下服务定义,为什么http://localhost:8001/api/v1/proxy/namespaces/monitoring/services/grafana 上不可用?

grafana-service.yaml

apiVersion: v1
kind: Service
metadata:
  namespace: monitoring
  name: grafana
  labels:
    app: grafana
spec:
  type: NodePort
  ports:
  - name: web
    port: 3000
    protocol: TCP
    nodePort: 30902
  selector:
    app: grafana

grafana-deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: monitoring
  name: grafana
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:4.1.1
        env:
        - name: GF_AUTH_BASIC_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "true"
        - name: GF_SECURITY_ADMIN_USER
          valueFrom:
            secretKeyRef:
              name: grafana-credentials
              key: user
        - name: GF_SECURITY_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: grafana-credentials
              key: password
        volumeMounts:
        - name: grafana-storage
          mountPath: /var/grafana-storage
        ports:
        - name: web
          containerPort: 3000
        resources:
          requests:
            memory: 100Mi
            cpu: 100m
          limits:
            memory: 200Mi
            cpu: 200m
      - name: grafana-watcher
        image: quay.io/coreos/grafana-watcher:v0.0.5
        args:
          - '--watch-dir=/var/grafana-dashboards'
          - '--grafana-url=http://localhost:3000'
        env:
        - name: GRAFANA_USER
          valueFrom:
            secretKeyRef:
              name: grafana-credentials
              key: user
        - name: GRAFANA_PASSWORD
          valueFrom:
            secretKeyRef:
              name: grafana-credentials
              key: password
        resources:
          requests:
            memory: "16Mi"
            cpu: "50m"
          limits:
            memory: "32Mi"
            cpu: "100m"
        volumeMounts:
        - name: grafana-dashboards
          mountPath: /var/grafana-dashboards
      volumes:
      - name: grafana-storage
        emptyDir: {}
      - name: grafana-dashboards
        configMap:
          name: grafana-dashboards

我在访问上述 URL 时看到的错误是“没有可用于服务“grafana”的端点”,错误代码 503。

【问题讨论】:

    标签: proxy kubernetes kubectl


    【解决方案1】:

    您的部署可能没有标签 app:grafana,或者位于另一个命名空间中。您还可以发布部署定义吗?

    【讨论】:

    • 嘿,抱歉,我回复你的速度太慢了,但我现在发布了部署清单!同时不得不专注于其他事情。
    【解决方案2】:

    有几个因素可能会导致此问题。

    1. 该服务期望找到一个或多个支持端点,它通过标签上的匹配规则发现这些端点。如果标签不对齐,则服务找不到端点,服务执行的网络网关功能将导致 503。

    2. POD 声明的端口和容器内的进程与服务预期的--target-port 不一致。

    其中任何一个都可能产生错误。让我们仔细看看。

    首先,kubectl describe 服务:

    $ kubectl describe svc grafana01-grafana-3000
    Name:           grafana01-grafana-3000
    Namespace:      default
    Labels:         app=grafana01-grafana
                chart=grafana-0.3.7
                component=grafana
                heritage=Tiller
                release=grafana01
    Annotations:        <none>
    Selector:       app=grafana01-grafana,component=grafana,release=grafana01
    Type:           NodePort
    IP:         10.0.0.197
    Port:           <unset> 3000/TCP
    NodePort:       <unset> 30905/TCP
    Endpoints:      10.1.45.69:3000
    Session Affinity:   None
    Events:         <none>
    

    请注意,我的 grafana 服务列出了 1 个端点(可能有多个)。您示例中的上述错误表明您不会在此处列出端点。

    Endpoints:      10.1.45.69:3000
    

    接下来让我们看看选择器。在上面的示例中,您可以看到我的服务上有 3 个选择器标签:

    Selector:       app=grafana01-grafana,component=grafana,release=grafana01
    

    接下来我会kubectl describe我的豆荚:

    $ kubectl describe pod grafana
    Name:       grafana01-grafana-1843344063-vp30d
    Namespace:  default
    Node:       10.10.25.220/10.10.25.220
    Start Time: Fri, 14 Jul 2017 03:25:11 +0000
    Labels:     app=grafana01-grafana
            component=grafana
            pod-template-hash=1843344063
            release=grafana01
    ...
    

    请注意,pod 上的标签正确对齐,因此我的服务会找到 pods,它提供了 endpoints,它们由 service 进行负载平衡。验证链的这一部分在您的环境中没有中断。

    如果您确实发现标签是正确的,您可能仍然存在断开连接,因为在 pod 内的 container 内运行的 grafana 进程运行在与您预期不同的端口上。

    $ kubectl describe pod grafana
    Name:       grafana01-grafana-1843344063-vp30d
    ...
    Containers:
      grafana:
        Container ID:   docker://69f11b7828c01c5c3b395c008d88e8640c5606f4d865107bf4b433628cc36c76
        Image:      grafana/grafana:latest
        Image ID:       docker-pullable://grafana/grafana@sha256:11690015c430f2b08955e28c0e8ce7ce1c5883edfc521b68f3fb288e85578d26
        Port:       3000/TCP
        State:      Running
          Started:      Fri, 14 Jul 2017 03:25:26 +0000
    

    如果由于某种原因,您在容器下的 port 列出了不同的值,则该服务有效地针对无效端点进行负载平衡。

    例如,如果它列出了端口 80: 端口:80/TCP 或者是一个空值 端口:

    然后,即使您的标签选择器是正确的,服务也永远不会从 pod 中找到有效响应,并且会从轮换中删除端点。

    我怀疑您的问题是上面的第一个问题(标签选择器不匹配)。

    如果标签选择器和端口都对齐,则节点之间的 MTU 设置可能存在问题。在某些情况下,如果您的网络层(如 calico)使用的 MTU 大于支持网络的 MTU,那么您将永远无法从端点获得有效响应。通常,最后一个潜在问题将表现为超时而不是 503。

    【讨论】:

      【解决方案3】:

      正如迈克尔所说,很可能您的标签或命名空间不匹配。但是除此之外,请记住,即使您修复了端点,您之后的 url (http://localhost:8001/api/v1/proxy/namespaces/monitoring/services/grafana) 也可能无法正常工作。

      根据您的 root_url 和/或 static_root_path grafana 配置设置,当您尝试登录时,grafana 可能会尝试 POST 到 http://localhost:8001/login 并获得 404。

      尝试使用 kubectl port-forward 代替:

      kubectl -n monitoring port-forward [grafana-pod-name] 3000

      然后通过http://localhost:3000/访问grafana

      https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/

      【讨论】:

        【解决方案4】:

        问题在于 Grafana 的端口名为 web,因此需要将 :web 附加到 kubectl 代理 URL:http://localhost:8001/api/v1/proxy/namespaces/monitoring/services/grafana:web

        另一种方法是不命名 Grafana 端口,因为这样您就不必将 :web 附加到服务的 kubectl 代理 URL:http://localhost:8001/api/v1/proxy/namespaces/monitoring/services/grafana:web。我最终选择了这个选项,因为它更容易。

        【讨论】:

        【解决方案5】:

        在 Kubernetes 1.10 中,代理 URL 应该略有不同,如下所示:

        http://localhost:8080/api/v1/namespaces/default/services/SERVICE-NAME:PORT-NAME/proxy/ 
        

        参考:https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#manually-constructing-apiserver-proxy-urls

        【讨论】:

          猜你喜欢
          • 2022-08-12
          • 1970-01-01
          • 1970-01-01
          • 2016-01-06
          • 1970-01-01
          • 2019-05-23
          • 2019-05-10
          • 2015-06-23
          • 1970-01-01
          相关资源
          最近更新 更多