在 Hadoop 集群上安装

本文提供了在 Hadoop 集群上安装和配置 dask-gateway-server 的说明。

创建用户账号

在安装任何东西之前,您需要创建一个用户账号,该账号将用于运行 dask-gateway-server 进程。用户名不重要,重要的是其拥有的权限。这里我们将使用 dask

$ adduser dask

启用代理用户权限

Dask-Gateway 充分利用了 Hadoop 的安全模型,并将在容器中以请求用户的权限启动 Dask 工作进程(例如,如果 alice 创建一个集群,其 dask 工作进程将以用户 alice 的身份运行)。为了实现这一点,网关服务器需要 代理用户 (proxy-user) 权限。这允许 Dask-Gateway 服务器模拟另一个用户执行操作。

为了使 dask-gateway-server 正常工作,您需要为 dask 用户账号启用 代理用户 (proxy-user) 权限。 dask 允许模拟的用户可以被限制在特定组,模拟请求也可以被限制在特定主机。最低要求是,dask 用户需要有权限模拟使用网关的任何人,且请求至少允许来自运行 dask-gateway-server 的主机。

<property>
  <name>hadoop.proxyuser.dask.hosts</name>
  <value>host-where-dask-gateway-is-running</value>
</property>
<property>
  <name>hadoop.proxyuser.dask.groups</name>
  <value>group1,group2</value>
</property>

如果可以接受更宽松的限制,您也可以使用通配符 * 来允许模拟任何用户或来自任何主机的请求。

<property>
  <name>hadoop.proxyuser.dask.hosts</name>
  <value>*</value>
</property>
<property>
  <name>hadoop.proxyuser.dask.groups</name>
  <value>*</value>
</property>

有关更多信息,请参阅 代理用户 (proxy-user) 文档。

创建安装目录

一个 dask-gateway-server 安装需要创建三个类型的目录来存放文件

  • 软件文件:包括 Python 环境和所有必需的库。这里我们使用 /opt/dask-gateway

  • 配置文件:这里我们使用 /etc/dask-gateway

  • 运行时文件:这里我们使用 /var/dask-gateway

# Software files
$ mkdir -p /opt/dask-gateway

# Configuration files
$ mkdir /etc/dask-gateway

# Runtime files
$ mkdir /var/dask-gateway
$ chown dask /var/dask-gateway

安装 Python 环境

为了避免系统 Python 安装与 dask-gateway-server 之间的相互影响,我们将把完整的 Python 环境安装到软件目录中。最简单的方法是使用 miniconda,但这并非强制要求。

$ curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o /tmp/miniconda.sh
$ bash /tmp/miniconda.sh -b -p /opt/dask-gateway/miniconda
$ rm /tmp/miniconda.sh

我们还建议将 miniconda 添加到 root 用户的 PATH 环境变量中,以便于后续命令的使用。

$ echo 'export PATH="/opt/dask-gateway/miniconda/bin:$PATH"' >> /root/.bashrc
$ source /root/.bashrc

安装 dask-gateway-server

现在我们可以安装 dask-gateway-server 及其依赖项了。

$ conda install -y -c conda-forge dask-gateway-server-yarn

如果您想使用 Kerberos 进行面向用户的身份验证,您还需要安装 dask-gateway-server-kerberos

$ conda install -y -c conda-forge dask-gateway-server-kerberos

配置 dask-gateway-server

现在我们准备配置 dask-gateway-server 的安装。配置写在一个 Python 文件中(通常是 /etc/dask-gateway/dask_gateway_config.py)。选项被分配给一个配置对象 c,然后在网关启动时加载。您可以自由地在该文件中使用任何 Python 语法/库,dask-gateway-server 只关心设置在 c 配置对象上的值。

这里我们将介绍一些您可能想要设置的常见配置选项。

启用 YARN 集成

首先,您需要启用 YARN 作为集群后端。

# Configure the gateway to use YARN as the backend
c.DaskGateway.backend_class = (
    "dask_gateway_server.backends.yarn.YarnBackend"
)

启用 Kerberos 安全 (可选)

如果您的集群启用了 Kerberos,您还需要为 dask 用户创建一个 principal 和 keytab。您还需要为运行 dask-gateway-server 的主机创建一个 HTTP 服务 principal(如果尚不存在)。Keytab 可以在命令行上创建,如下所示:

# Create the dask principal
$ kadmin -q "addprinc -randkey dask@YOUR_REALM.COM"

# Create the HTTP principal (if not already created)
$ kadmin -q "addprinc -randkey HTTP/FQDN"

# Create a keytab
$ kadmin -q "xst -norandkey -k /etc/dask-gateway/dask.keytab dask HTTP/FQDN"

其中 FQDN 是运行 dask-gateway-server 的主机的完全限定域名 (fully qualified domain name)

将 keytab 文件存储在您认为合适的位置(我们建议将其与其他配置一起存储在 /etc/dask-gateway/ 中,如上所述)。您还需要确保 dask.keytab 文件只能由 dask 用户读取。

$ chown dask /etc/dask-gateway/dask.keytab
$ chmod 400 /etc/dask-gateway/dask.keytab

要配置 dask-gateway-server 使用此 keytab 文件,您需要在 dask_gateway_config.py 文件中添加以下行:

# Specify the location of the keytab file, and the principal name
c.YarnBackend.keytab = "/etc/dask-gateway/dask.keytab"
c.YarnBackend.principal = "dask"

# Enable Kerberos for user-facing authentication
c.DaskGateway.authenticator_class = "dask_gateway_server.auth.KerberosAuthenticator"
c.KerberosAuthenticator.keytab = "/etc/dask-gateway/dask.keytab"

配置服务器地址 (可选)

默认情况下,dask-gateway-server 将通过 0.0.0.0:8000 提供所有流量服务。这包括 HTTP(S) 请求(REST API、仪表板等)和 dask scheduler 流量。

如果您想在不同的地址提供服务,或者在不同的端口上提供 Web 和 scheduler 流量服务,您可以配置以下字段:

  • c.Proxy.address - 提供 HTTP(S) 流量服务,默认为 :8000

  • c.Proxy.tcp_address - 提供 dask 客户端到 scheduler 的 TCP 流量服务,默认为 c.Proxy.address

这里我们将 Web 流量配置到 8000 端口,将 scheduler 流量配置到 8001 端口

c.Proxy.address = ':8000'
c.Proxy.tcp_address = ':8001'

指定用户 Python 环境

由于 Dask worker/scheduler 将运行在它们自己的 YARN 容器中,您需要提供一种方法使 Python 环境可用于这些容器。这里有几种选择:

  • 在每个节点上安装相同的 Python 环境

  • 将环境归档并在运行时分发到容器 (推荐)

无论哪种情况,Python 环境至少需要安装 dask-gateway 包才能正常工作。

使用本地环境

如果您已经在每个节点上安装了相同的 Python 环境,您只需要配置 dask-gateway-server 使用提供的 Python。这可以通过几种不同的方式完成

# Configure the paths to the dask-scheduler/dask-worker CLIs
c.YarnClusterConfig.scheduler_cmd = "/path/to/dask-scheduler"
c.YarnClusterConfig.worker_cmd = "/path/to/dask-worker"

# OR
# Activate a local conda environment before startup
c.YarnClusterConfig.scheduler_setup = 'source /path/to/miniconda/bin/activate /path/to/environment'
c.YarnClusterConfig.worker_setup = 'source /path/to/miniconda/bin/activate /path/to/environment'

# OR
# Activate a virtual environment before startup
c.YarnClusterConfig.scheduler_setup = 'source /path/to/your/environment/bin/activate'
c.YarnClusterConfig.worker_setup = 'source /path/to/your/environment/bin/activate'

使用归档环境

YARN 还提供了在启动应用程序之前将文件/归档“本地化”到容器的机制。这可以用于在运行时分发 Python 环境。这种方法很有吸引力,因为它不需要在整个集群中安装任何东西,并且允许集中管理用户的 Python 环境。

用于分发打包环境通常使用以下工具完成

这两个工具都可以获取一个环境并创建其归档,使得任何库或脚本中的(大多数)绝对路径都被更改为可重定位的。然后可以将此归档与您的应用程序一起分发,并在 YARN 资源本地化期间自动提取。

下面我们演示如何创建并打包一个包含 dask-gateway 以及 pandasscikit-learn 的 Conda 环境。可以根据需要添加其他包。

使用 conda-pack 打包 Conda 环境

# Make a folder for storing the conda environments locally
$ mkdir /opt/dask-gateway/envs

# Create a new conda environment
$ conda create -c conda-forge -y -p /opt/dask-gateway/envs/example
...

# Activate the environment
$ conda activate /opt/dask-gateway/envs/example

# Install dask-gateway, along with any other packages
$ conda install -c conda-forge -y dask-gateway pandas scikit-learn conda-pack

# Package the environment into example.tar.gz
$ conda pack -o example.tar.gz
Collecting packages...
Packing environment at '/opt/dask-gateway/envs/example' to 'example.tar.gz'
[########################################] | 100% Completed | 17.9s

使用打包的环境

建议事先将环境上传到 HDFS 上的某个目录,以避免为每个用户重复上传的开销。此目录应对所有用户可读,但仅对管理 Python 环境的管理员用户可写(这里我们将使用 dask 用户,并创建 /dask-gateway 目录)。

$ hdfs dfs -mkdir -p /dask-gateway
$ hdfs dfs -chown dask /dask-gateway
$ hdfs dfs -chmod 755 /dask-gateway

将我们已经打包的环境上传到 hdfs

$ hdfs dfs -put /opt/dask-gateway/envs/example.tar.gz /dask-gateway/example.tar.gz

要将打包的环境与 dask-gateway-server 一起使用,您需要将归档文件包含在 YarnClusterConfig.localize_files 中,并在 YarnClusterConfig.scheduler_setup/YarnClusterConfig.worker_setup 中激活环境。

c.YarnClusterConfig.localize_files = {
    'environment': {
        'source': 'hdfs:///dask-gateway/example.tar.gz',
        'visibility': 'public'
    }
}
c.YarnClusterConfig.scheduler_setup = 'source environment/bin/activate'
c.YarnClusterConfig.worker_setup = 'source environment/bin/activate'

请注意,我们将环境的 visibility 设置为 public,以便多个用户可以共享相同的本地化环境(减少环境移动的开销)。

有关更多信息,请参阅 Skein 关于分发文件的文档

其他配置选项

dask-gateway-server 还有几个额外的配置字段。有关所有可用选项的更多信息,请参阅配置参考文档(特别是yarn 配置文档)。至少您可能需要配置 worker 资源限制,以及使用哪个 YARN 队列。

# The resource limits for a worker
c.YarnClusterConfig.worker_memory = '4 G'
c.YarnClusterConfig.worker_cores = 2

# The YARN queue to use
c.YarnClusterConfig.queue = '...'

如果您的集群负载较高(并且作业启动可能较慢),您可能还需要增加集群/worker 的超时值

# Increase startup timeouts to 5 min (600 seconds) each
c.YarnClusterConfig.cluster_start_timeout = 600
c.YarnClusterConfig.worker_start_timeout = 600

示例

总而言之,一个示例 dask_gateway_config.py 配置文件可能如下所示:

# Configure the gateway to use YARN as the backend
c.DaskGateway.backend_class = (
    "dask_gateway_server.backends.yarn.YarnBackend"
)

# Specify the location of the keytab file, and the principal name
c.YarnBackend.keytab = "/etc/dask-gateway/dask.keytab"
c.YarnBackend.principal = "dask"

# Enable Kerberos for user-facing authentication
c.DaskGateway.authenticator_class = "dask_gateway_server.auth.KerberosAuthenticator"
c.KerberosAuthenticator.keytab = "/etc/dask-gateway/dask.keytab"

# Specify location of the archived Python environment
c.YarnClusterConfig.localize_files = {
    'environment': {
        'source': 'hdfs:///dask-gateway/example.tar.gz',
        'visibility': 'public'
    }
}
c.YarnClusterConfig.scheduler_setup = 'source environment/bin/activate'
c.YarnClusterConfig.worker_setup = 'source environment/bin/activate'

# Limit resources for a single worker
c.YarnClusterConfig.worker_memory = '4 G'
c.YarnClusterConfig.worker_cores = 2

# Specify the YARN queue to use
c.YarnClusterConfig.queue = 'dask'

开放相关端口

用户需要访问网关服务器,他们需要访问在上面配置服务器地址 (可选)中设置的公共端口(默认为端口 8000)。如何暴露端口是系统特定的——集群管理员应确定执行此任务的最佳方法。

启动 dask-gateway-server

此时,您应该能够使用创建的配置文件以 dask 用户身份启动网关服务器。dask-gateway-server 进程将是一个长时间运行的进程——如何管理它(supervisord 等)是系统特定的。要求如下:

  • dask 用户身份启动

  • /var/dask-gateway 设置为工作目录

  • /opt/dask-gateway/miniconda/bin 添加到 PATH 环境变量

  • 使用 -f /etc/dask-gateway/dask_gateway_config.py 指定配置文件位置

为了方便起见,我们建议创建一个存储在 /opt/dask-gateway/start-dask-gateway 的小型 bash 脚本来设置这些

#!/usr/bin/env bash

export PATH="/opt/dask-gateway/miniconda/bin:$PATH"
cd /var/dask-gateway
dask-gateway-server -f /etc/dask-gateway/dask_gateway_config.py

对于 测试 目的,您可以这样手动启动 dask-gateway-server

$ cd /var/dask-gateway
$ sudo -iu dask /opt/dask-gateway/start-dask-gateway

验证是否正常工作

如果服务器启动时没有错误,您会想检查一切是否正常工作。最简单的方法是以用户身份尝试连接。

用户环境需要安装 dask-gateway 库。如果您的集群使用 kerberos 加密,您还需要安装 dask-gateway-kerberos

# Install the dask-gateway client library
$ conda create -n dask-gateway -c conda-forge dask-gateway

# If kerberos is enabled, also install dask-gateway-kerberos
$ conda create -n dask-gateway -c conda-forge dask-gateway-kerberos

您可以通过创建一个 dask_gateway.Gateway 对象并指定公共地址来连接到网关(请注意,如果您配置了 c.Proxy.tcp_address,您还需要指定 proxy_address)。

>>> from dask_gateway import Gateway

# When running without kerberos
>>> gateway = Gateway("http://public-address")

# OR, if kerberos is enabled, you'll need to kinit and then do
>>> gateway = Gateway("http://public-address", auth="kerberos")

现在您应该能够进行 API 调用了。尝试 dask_gateway.Gateway.list_clusters(),这应该返回一个空列表。

>>> gateway.list_clusters()
[]

接下来,看看您是否可以创建一个集群。这可能需要几分钟。

>>> cluster = gateway.new_cluster()

您需要检查的最后一件事是您能否成功连接到新创建的集群。

>>> client = cluster.get_client()

如果一切正常,您可以使用 dask_gateway.GatewayCluster.shutdown() 关闭您的集群。

>>> cluster.shutdown()