调试#

有时你的 JupyterHub 部署不会按预期的方式运行。本节提供了一些关于调试和修复一些常见问题的技巧。

详细日志#

你可以通过在你的配置中添加以下内容来增加各种 pod(hub、proxy、autohttps 和用户 pod)发出的日志的详细程度

debug:
  enabled: true

这在 JupyterHub 已启动但你在身份验证、单用户服务器或服务方面遇到问题时特别有用。启用此功能的一个缺点是,发出的日志数量会使阅读日志以获取概述变得更加困难,并且会增加收集和存储日志的系统设置的成本。

调试命令#

为了调试你的 JupyterHub 部署,你需要能够检查正在使用的资源的状态。以下是几个用于调试的常见命令。

现实世界场景:假设你已经部署了一个 JupyterHub,并且一个用户告诉你他们正在遇到奇怪的行为。让我们看看我们的部署来弄清楚发生了什么。

kubectl get pod#

列出你的 Kubernetes 部署中的所有 pod

kubectl get pod --namespace <k8s-namespace>

这将输出部署中使用的所有 pod 的列表。

现实世界场景:在我们的例子中,我们看到了 JupyterHub 基础设施的两个 pod(hubproxy),以及当有人登录 JupyterHub 时创建的一个用户 pod。

以下是一个输出示例

$ kubectl get pod --namespace <k8s-namespace>
NAME                                READY     STATUS         RESTARTS   AGE
hub-3311438805-xnfvp     1/1       Running        0          2m
jupyter-choldgraf                   0/1       ErrImagePull   0          25s
proxy-1227971824-mn2wd   1/1       Running        0          5h

在这里我们可以看到两个 JupyterHub pod,以及一个用户 pod。请注意,所有用户 pod 都将以 jupyter- 开头。

特别是,注意 STATUS 列。如果给定的 pod 包含 Running 以外的内容,那么可能出了问题。

在本例中,我们可以看到用户的 pod 处于 ErrImagePull 状态。这通常意味着我们的 helm 图表配置中的 singleuser 中定义的 Docker 镜像存在问题。让我们进一步挖掘…

kubectl describe pod#

要查看有关特定 pod 状态的更多详细信息,请使用以下命令

kubectl describe pod <pod-name> --namespace <k8s-namespace>

这将输出几部分信息,包括 pod 的配置和设置。你将看到的最后一部分是最近事件的列表。这些信息可能特别有用,因为错误通常会显示在此部分。

现实世界场景:在我们的例子中,事件页面中的一行显示了一个错误

$ kubectl describe pod jupyter-choldgraf --namespace <k8s-namespace>
...
2m            52s             4       kubelet, gke-jhubtest-default-pool-52c36683-jv6r        spec.containers{notebook}       Warning         Failed           Failed to pull image "jupyter/scipy-notebook:v0.4": rpc error: code = 2 desc = Error response from daemon: {"message":"manifest for jupyter/scipy-notebook:v0.4 not found"}
...

看来 Docker 镜像确实存在问题。让我们通过获取 pod 中发生的事件的另一个视图来确认这一点。

kubectl logs#

如果你只想查看 pod 的最新日志,请使用以下命令

kubectl logs <POD_NAME> --namespace <k8s-namespace>

这将向您展示来自 Pod 的日志,这些日志通常包含有关问题所在的有用信息。解析这些日志以查看是否有任何内容正在生成错误。

现实世界场景:在我们的案例中,我们得到了以下行

$ kubectl logs jupyter-choldgraf --namespace <k8s-namespace>
Error from server (BadRequest): container "notebook" in pod "jupyter-choldgraf" is waiting to start: trying and failing to pull image

现在我们确定 Dockerfile 有问题。让我们检查我们的 config.yaml 文件,以查找我们指定用户 Docker 镜像的部分。在这里我们看到了问题

singleuser:
  image:
    name: jupyter/scipy-notebook

我们没有为 Docker 镜像指定 tag!不指定标签会导致它默认为 v0.4,这不是我们想要的,并且会导致 Pod 失败。

为了解决这个问题,让我们在 config.yaml 文件中添加一个标签

singleuser:
  image:
    name: jupyter/scipy-notebook
    tag: ae885c0a6226

然后运行 helm 升级

helm upgrade --cleanup-on-fail jhub jupyterhub/jupyterhub --version=<chart-version> -f config.yaml

其中 jhub 是 helm 版本名称(替换您在设置过程中选择的版本名称)。

注意

根据 Docker 镜像的大小,这可能需要一段时间才能完成。

在运行此命令后,让我们再次列出部署中的 Pod

$ kubectl get pod --namespace=<k8s-namespace>
NAME                                READY     STATUS              RESTARTS   AGE
hub-2653507799-r7wf8     0/1       ContainerCreating   0          31s
hub-3311438805-xnfvp     1/1       Terminating         0          14m
jupyter-choldgraf                   0/1       ImagePullBackOff    0          12m
proxy-deployment-1227971824-mn2wd   1/1       Running             0          5h

在这里我们可以看到一个 hub Pod 被销毁,另一个(基于升级后的 helm 图表)正在创建。我们还看到了我们损坏的用户 Pod,它不会被自动删除。让我们手动删除它,以便可以启动一个新的工作 Pod。

$ kubectl delete pod jupyter-choldgraf --namespace <k8s-namespace>

最后,我们将告诉我们的用户重新登录 JupyterHub。然后让我们再次列出正在运行的 Pod

$ kubectl get pod --namespace <k8s-namespace>
NAME                                READY     STATUS    RESTARTS   AGE
hub-2653507799-r7wf8     1/1       Running   0          3m
jupyter-choldgraf                   1/1       Running   0          18s
proxy-deployment-1227971824-mn2wd   1/1       Running   0          5h

现在我们看到我们有一个正在运行的用户 Pod!

请注意,许多调试情况并不像这种情况那样简单。您需要花一些时间才能了解 Kubernetes 可能抛出的错误以及这些错误与您的配置文件之间的关系。