在gke上安装带有clusterIP调度器和端口转发的dask-在python中创建dask.distibuted客户端



我尝试使用helm和tiller在gke集群上部署dask。我没有为集群创建外部IP的权限,所以我将dask调度程序设置为clusterIP,而不是负载平衡器。然后,我使用kubectl提供的端口转发将dask-scehduler服务转发到我的本地机器。

我有一个python代码(一个简单的dask示例(,我想将分布式客户端连接到dask调度器的(转发的(tcp端口,并在我的gke集群中启动计算。然而,我在tcp连接上收到一个超时。

我想知道我在这个过程中哪里出了问题,或者我是否需要在我的gcp帐户中启用更多权限才能使其正常工作。非常感谢您提供的任何建议。请注意,我能够在转发的http端口上打开jupyter笔记本,并能够在dask在我的gke 上创建的默认3个工人上触发一些计算

我正在下面粘贴我运行的python代码、我看到的错误、pod的当前状态、节点、gke上dask的服务设置以及我用来在我的gcp gke 上设置dask的命令

我的示例python程序(dask-example.py(

#!/usr/bin/env python3
from dask.distributed import Client
import dask.array as da
client = Client('tcp://127.0.0.1:8080')
array = da.ones((1000, 1000, 1000))
mn = array.mean().compute()  # Should print 1.0
print(mn)

错误消息(在运行python3-dask-example.py时(:

Traceback (most recent call last):
File "/home/userenv/lib/python3.8/site-packages/distributed/comm/core.py", line 286, in connect
comm = await asyncio.wait_for(
File "/usr/lib/python3.8/asyncio/tasks.py", line 498, in wait_for
raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "trial.py", line 17, in <module>
client = Client('tcp://127.0.0.1:8080', timeout=10)
File "/home/userenv/lib/python3.8/site-packages/distributed/client.py", line 743, in __init__
self.start(timeout=timeout)
File "/home/userenv/lib/python3.8/site-packages/distributed/client.py", line 948, in start
sync(self.loop, self._start, **kwargs)
File "/home/userenv/lib/python3.8/site-packages/distributed/utils.py", line 340, in sync
raise exc.with_traceback(tb)
File "/home/userenv/lib/python3.8/site-packages/distributed/utils.py", line 324, in f
result[0] = yield future
File "/home/userenv/lib/python3.8/site-packages/tornado/gen.py", line 762, in run
value = future.result()
File "/home/userenv/lib/python3.8/site-packages/distributed/client.py", line 1038, in _start
await self._ensure_connected(timeout=timeout)
File "/home/userenv/lib/python3.8/site-packages/distributed/client.py", line 1095, in _ensure_connected
comm = await connect(
File "/home/userenv/lib/python3.8/site-packages/distributed/comm/core.py", line 308, in connect
raise IOError(
OSError: Timed out trying to connect to tcp://127.0.0.1:8080 after 10 s

dask在我的gke 上的状态

kubectl get-po#显示这个

NAME                                       READY   STATUS              RESTARTS   AGE
my-dask-jupyter-565c5c5659-w4s76           1/1     Running             0          27h
my-dask-scheduler-6bf8bc8bbf-xgj2q         1/1     Running             0          27h
my-dask-worker-68b5b695bd-l2b6m            1/1     Running             0          27h
my-dask-worker-68b5b695bd-xnssz            1/1     Running             0          27h
my-dask-worker-68b5b695bd-z68wt            1/1     Running             0          27h

kubectl没有#显示这个

NAME                                          STATUS   ROLES    AGE   VERSION
gke-dask-cluster-default-pool-d3f451b1-gp47   Ready    <none>   27h   v1.17.14-gke.1200
gke-dask-cluster-default-pool-d3f451b1-rk8z   Ready    <none>   27h   v1.17.14-gke.1200

kubectl get-svc#显示此

NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
kubernetes          ClusterIP   10.83.240.1    <none>        443/TCP           27h
my-dask-jupyter     ClusterIP   10.83.244.84   <none>        80/TCP            27h
my-dask-scheduler   ClusterIP   10.83.244.59   <none>        8786/TCP,80/TCP   27h

我用来设置dask的命令(感谢这篇文章https://libinruan.github.io/2019/05/24/Set-up-Kubernetes-clusters-for-Python-ML/)

export PROJECTID='mygcp'
export EMAIL="user4098765@gmail.com"
export ZONE='us-central1-c'
export REGION='us-central1' 
export MIN_WORKER_NODES=0
export MAX_WORKER_NODES=100
export CLUSTER_NAME='dask-cluster'
export WORKER_MACHINE_TYPE='n1-standard-2'
export MACHINE_TYPE='n1-standard-2'
NUM_NODES=2

gcloud config set project $PROJECTID
gcloud services enable container.googleapis.com
gcloud container clusters create $CLUSTER_NAME --machine-type $MACHINE_TYPE --num-nodes $NUM_NODES --zone $ZONE --cluster-version latest
gcloud container clusters get-credentials $DASK_KUBE_CLUSTER_NAME --zone=$DASK_KUBE_CLUSTER_ZONE --project $DASK_GCLOUD_PROJECT
kubectl config set-cluster $DASK_KUBE_CLUSTER_NAME
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$EMAIL
kubectl create serviceaccount tiller --namespace=kube-system
kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller --wait
kubectl --namespace=kube-system patch deployment tiller-deploy --type=json 
--patch='[{"op": "add", "path": "/spec/template/spec/containers/0/command", "value": ["/tiller", "--listen=localhost:44134"]}]'
gcloud container clusters get-credentials $CLUSTER_NAME --zone=$ZONE --project $PROJECTID
kubectl config set-cluster $DASK_KUBE_CLUSTER_NAME
helm install -n my-dask stable/dask -f dask-worker-spec.yml --set scheduler.serviceType=ClusterIP --set jupyter.serviceType=ClusterIP

我已经成功地再现了问题中描述的相同行为。

我鼓励您查看dask的新版本,该版本可在其主页上找到,因为问题中使用的版本已被弃用

TL;DR

使用与dask-scheduler正在使用的软件版本相同的Python模块(daskdistributed等(


问题中使用的设置的再现

  • 创建GKE集群:
    • $ gcloud beta container clusters create "gke-dask" --zone "europe-west3-c" --no-enable-basic-auth --cluster-version "1.17.13-gke.2600" --release-channel "regular" --machine-type "e2-standard-4"

e2-standard-4=4核和16GB RAM机器

  • 连接到集群:
    • $ gcloud container clusters get-credentials gke-dask --zone=europe-west3-c
  • 安装Helmv2(如果需要:Stackoverlow.com:Helm v2的权限问题(:
    • Helm.sh:文档:简介:安装
    • $ helm init
  • 运行Helm图表:
    • $ helm install -n my-dask stable/dask --set scheduler.serviceType=ClusterIP --set jupyter.serviceType=ClusterIP

为了确定问题,我运行了一些测试:

  • $ kubectl port-forwarddask-scheduler到我的机器,并使用问题中的示例Python代码。我安装了该代码所需的依赖项,但版本不同($ pip install dask[complete].代码失败,返回的消息与问题中的消息相同
  • $ kubectl run -it --rm ubuntu -- /bin/bash-问题中的错误表明这可能是一个与网络有关的问题。我将ubuntuPod与相同的Python安装一起使用,以消除潜在的网络连接问题(port-forward(代码失败,返回与问题中相同的消息
  • $ kubectl exec -it DASK-SCHEDULER-POD-NAME -- /bin/bash-如果这是一个网络连接问题,它应该在应该处理此代码的Pod上运行代码成功运行并返回1.0

我尝试将ubuntuPod与Python一起使用,它的模块与dask-scheduler中的模块版本更接近它产生了一个与问题不同的错误。这表明网络并没有固有的问题,而是使用的软件(它的版本(。我无法完全复制dask-scheduler中使用的设置,所以我使用了dask-scheduler正在使用的映像,并生成了额外的Pod来检查它是否能通过GKE网络工作成功了

请点击下面的示例作为解决方法!

从您的机器运行的步骤:

  • $ kubectl port-forward service/my-dask-scheduler --address 0.0.0.0 8786:8786 &-将dask服务转发到您的机器
  • $ docker run --rm -ti daskdev/dask:1.1.5 /bin/bash-在您的机器上运行一个Docker容器,并将exec放入它的bash中。此映像与dask-scheduler的映像相同,以保留Python及其模块版本
  • 在容器中使用以下Python代码:
#!/usr/bin/env python3
from dask.distributed 
import Client
import dask.array as da
client = Client('tcp://IP_ADDRESS:8786')
array = da.ones((1000, 1000, 1000))
mn = array.mean().compute() # Should print 1.0
print(mn)

请在;IP_ ADDRESS";可以从Docker容器访问的机器的IP地址!

您应该得到以下输出:

(base) root@81fb5004ea4c:/# python3 script.py 
1.0

您可以检查Python venv中的虚拟环境。

附加参考:

  • Kubernetes.io:Docs:Tasks:Access应用程序集群:端口转发访问应用程序集群

最新更新