【问题标题】:Google Endpoints on GKE (ESP + gRPC) - how to debug this further?GKE (ESP + gRPC) 上的 Google Endpoints - 如何进一步调试?
【发布时间】:2023-03-13 21:56:01
【问题描述】:

关注后 Getting started with Cloud Endpoints on GKEdeploying the API and backend 一切看起来它正在工作(剧透警告,它不是);

  • 我的应用程序部署在集群上。
  • 单个 pod 部署在 Kubernetes 中。
  • pod 正在运行两个容器(ESP 和我的 GPRC 服务)
    1. gcr.io/endpoints-release/endpoints-runtime:1
    2. gcr.io/my-app/server:latest

...两者都在运行; kubectl get pods 产量:

NAME                          READY   STATUS    RESTARTS   AGE
my-app-855d8447f-nnvz8        2/2     Running   0          24m

Need improved/HTTPS-centric GKE Ingress + ESP + gRPC example 帮助我走到了这一步。

坏消息;来自我的 Angular 应用程序的 HTTP 请求(在 http://localhost:4200 上运行)导致 500 内部服务器错误

我跑遍了Troubleshooting Cloud Endpoints in GKE,看不到任何适用的东西(没有什么明显的错误)。

好的。是时候调试了。

查看带有kubectl logs -f my-app-855d8447f-nnvz8 -c esp 的ESP(Docker 容器)日志,我可以看到预检请求(OPTIONS)和随后的HTTP POST 请求。

INFO:Fetching an access token from the metadata service
INFO:Fetching the service config ID from the rollouts service
INFO:Fetching the service configuration from the service management service
INFO:Attribute zone: us-central1-a
INFO:Attribute project_id: my-cloud-project
INFO:Attribute kube_env: KUBE_ENV

nginx: [warn] Using trusted CA certificates file: /etc/nginx/trusted-ca-certificates.crt

143.159.55.199 - - [12/Jan/2020:17:34:11 +0000] "OPTIONS /v1/documents?key=Ei2ZvlV5zASIkuRf4LRl&format=JSON&showDefaults=false HTTP/1.1" 204 0 "http://localhost:4200/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
143.159.55.199 - - [12/Jan/2020:17:34:11 +0000] "POST /v1/documents?key=Ei2ZvlV5zASIkuRf4LRl&format=JSON&showDefaults=false HTTP/1.1" 500 242 "http://localhost:4200/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"

CORS (OPTIONS) 请求导致 HTTP 204,但是 POST 请求是 HTTP 500。所以这里显然存在问题。

尽管有大量日志记录,但我的 grpc 服务器中没有日志; kubectl logs -f my-app-855d8447f-nnvz8 -c server 什么也没产生。所以

  • Kubernetes pod 运行良好,两个容器都在运行。
  • ESP 正在启动并成功使用元数据服务
  • CORS 正在运行(我正在开发时它是完全开放的)
  • gRPC 服务正在运行但未命中(无日志)

在 CORS 和 POST HTTP 请求之间的某个地方,它出错了,gRPC 服务永远不会被调用。

我找不到任何错误;如何调试 ESP/nginx 和我的 gRPC 服务器之间发生的事情?

为了完整起见,这是我的部署 yaml(添加了 cmets):

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: esp
        image: gcr.io/endpoints-release/endpoints-runtime:1
        # The default value for the backend address is http://127.0.0.1:8080
        args: [
          "--http_port=8081",

          # My gPRC service is running on port 8080 on the same VM.
          "--backend=grpc://127.0.0.1:8080",
          "--service=my-project.endpoints.my-project-dev.cloud.goog",
          "--rollout_strategy=managed",

          # Makes ESP return code 200 for location /healthz,
          # instead of forwarding the request to the backend.
          "--healthz=healthz",

          # Wide-open CORS during development.
          "--cors_preset=basic",
          "--cors_allow_origin=*",
        ]
        # HEALTH CHECK START
        # Used by ingress to perform health check
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8081
        ports:
          - containerPort: 8081
        # HEALTH CHECK END
      - name: server
        image: gcr.io/my-project-dev/server:latest
        imagePullPolicy: Always
        ports:
          - containerPort: 8080

来自 ESP/nginx 容器的 CORS 响应标头是:

Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Length,Content-Range
Content-Type: application/json
Date: Sun, 12 Jan 2020 17:34:11 GMT
Server: nginx
Transfer-Encoding: chunked
Via: 1.1 google

我不希望任何人想出一个答案,但现在我不确定当一切看起来不错时如何进一步调试?

【问题讨论】:

  • 你能ssh到esp容器并检查你是否可以手动连接到server容器吗? kubectl exec -it my-app-855d8447f-nnvz8 --container server -- /bin/bash 之类的东西?
  • 是的。我与kubectl exec -it my-app-855d8447f-nnvz -c server -- /bin/bash 连接,在server 中,我可以看到gRPC Python 服务与ps -ax 一起运行
  • 我也通过 ssh 进入了 nginx 代理容器 (esp) 和 cat /var/log/nginx/error.log,但它只包含 Using trusted CA certificates file: /etc/nginx/trusted-ca-certificates.crt

标签: docker nginx kubernetes google-kubernetes-engine


【解决方案1】:

新的一天和一个解决方案。我将简要解释解决方案,但更多地关注如何我发现它以及我会采取哪些不同的做法。

问题

“Compute Engine 默认服务帐号”缺少一些权限。 Getting started with Cloud Endpoints on GKE使用数据存储。我的应用程序可以。只需转到 IAM & admin > IAM,并将“Cloud Datastore User”角色添加到服务帐户即可解决我的问题。

课程

1. 登录 Python gPRC 服务器的__init__ 并没有提供看起来那么多的保护。 AFAICT,主要 gRPC 服务模块正在以某种方式被调用/加载,但权限不足意味着 from google.cloud import datastore 阻止了我的云日志语句被执行:

# This requires "Cloud Datastore User" role.
from google.cloud import datastore

class MyServer(myservice_pb2_grpc.MyServer):
    """Implements the GRPC interface to handle client calls."""

    def __init__(self):
        # Logging using CloudLoggingHandler was never executed.
        logger.info('__init__')

def serve():
    """Runs a gRPC server to handle client calls."""
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    myservice_pb2_grpc.add_MyServiceServicer_to_server(MyServer(), server)

    # The default value for the backend address is http://127.0.0.1:8080
    server.add_insecure_port('[::]:8080')
    server.start()
    server.wait_for_termination()

if __name__ == '__main__':
    serve()

2. 虽然 Container 日志确实包含一条非常有用的错误消息,但它被默认的 Stackdriver 过滤器隐藏:

resource.type="container"
resource.labels.cluster_name="standard-cluster-2"
resource.labels.namespace_id="default"
resource.labels.project_id="my-project-dev"
resource.labels.zone:"us-central1-a"
resource.labels.container_name=("esp" OR "server")
resource.labels.pod_id="my-app-855d8447f-nnvz8"

看到我的错误需要resource.typeapi。此外,只有资源标签的project_id 是相关的。我强烈建议您查看项目的 api 日志。不要只查看容器日志:

resource.type="api"
resource.labels.project_id="json-schema-dev"

在我的情况下,可以通过将 Stackdriver 过滤器设置为

找到确切的错误
resource.type="api"
resource.labels.project_id="json-schema-dev"
jsonPayload.log_message:("Exception calling application: 403 Missing or insufficient permissions.")

3. 鉴于我在 Stackdriver 日志中找不到错误,我在哪里找到它?浏览器控制台。不起眼的浏览器控制台。我只查看了开发者控制台的网络选项卡,看到了 HTTP 500 响应,然后直接进入了 Cloud Console。

4. 查看完整的错误消息。浏览器收到的错误可能表现为:

headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
status: 500
statusText: "Internal Server Error"
url:"http://34.107.225.145/v1/documents:inferkey=123&format=JSON&showDefaults=false"
ok: false
name: "HttpErrorResponse"
message: "Http failure response for http://123.456.789.342 500 Internal Server Error".
error: {code: 2, message:...

我没有扩展被省略号截断的error 属性。展开后,我得到:

code: 2
message: "Exception calling application: 403 Missing or insufficient permissions."

总结

  • 登录__init__ 可能还不够。
    • 考虑登录serve()
  • 仅导入您没有足够权限的模块可能会导致日志语句无法执行。
  • 检查api 日志,而不仅仅是container 日志。
    • 为方便起见,Kubernetes 链接到容器日志,但默认过滤器显然不方便。
  • 花更多时间查看客户端错误,不要这么快就转移到服务器。
    • 尽可能扩展控制台错误信息(超出响应代码)

【讨论】:

    猜你喜欢
    • 2020-01-02
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2019-12-16
    • 2016-09-04
    相关资源
    最近更新 更多