跳转至

01 jupyterhub 安装脚本

jupyterhub 安装脚本

背景

  • 支持一键安装jupyterhub
  • 支持用户创建

脚本install_jupyterhub.sh

#!/bin/bash

# JupyterHub 安装部署脚本
# 使用说明:以root用户执行此脚本

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否以root用户运行
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本必须以root用户运行"
        exit 1
    fi
    log_info "root权限检查通过"
}

# 安装系统依赖
install_dependencies() {
    log_info "安装系统依赖包..."

    # 检测系统类型
    if [ -f /etc/redhat-release ] || [ -f /etc/centos-release ]; then
        # RedHat/CentOS
        yum update -y
        yum install -y python3 python3-devel python3-pip \
                      nodejs npm \
                      git curl wget \
                      sqlite sqlite-devel \
                      gcc gcc-c++ make

    elif [ -f /etc/debian_version ]; then
        # Debian/Ubuntu
        apt-get update
        apt-get install -y python3 python3-dev python3-pip \
                          nodejs npm \
                          git curl wget \
                          sqlite3 libsqlite3-dev \
                          gcc g++ make

    else
        log_warn "未知的系统类型,请手动安装依赖"
    fi

    # 升级pip
    pip3 install --upgrade pip
    log_info "系统依赖安装完成"
}

# 安装JupyterHub和相关组件
install_jupyterhub() {
    log_info "安装JupyterHub和相关组件..."

    # 安装JupyterHub
    pip3 install jupyterhub

    # 安装Jupyter Notebook(用于单用户服务器)
    pip3 install notebook

    # 安装配置代理
    npm install -g configurable-http-proxy

    # 安装sudospawner(用于sudo创建用户)
    pip3 install sudospawner

    # 安装PAM认证(可选,用于系统用户认证)
    #pip3 install jupyterhub-pamauthenticator

    log_info "JupyterHub安装完成"
}

# 创建系统用户
create_users() {
    local users_file="jupyterhub_users.txt"

    log_info "创建JupyterHub用户..."

    # 检查用户文件是否存在,如果不存在则创建示例
    if [ ! -f "$users_file" ]; then
        log_warn "用户文件 $users_file 不存在,创建示例文件"
        cat > "$users_file" << EOF
# JupyterHub用户列表
# 每行格式:用户名:密码
zhucongming:123456
EOF
        log_info "示例用户文件已创建: $users_file"
        log_warn "请编辑此文件后重新运行用户创建步骤"
        return
    fi

    # 读取用户文件并创建用户
    while IFS=':' read -r username password || [[ -n "$username" ]]; do
        # 跳过空行和注释
        [[ "$username" =~ ^#.*$ ]] && continue
        [[ -z "$username" ]] && continue

        # 检查用户是否存在
        if id "$username" &>/dev/null; then
            log_info "用户 $username 已存在"
        else
            # 创建用户
            useradd -m -s /bin/bash "$username"

            # 设置密码
            if [ -n "$password" ]; then
                echo "$username:$password" | chpasswd
                log_info "创建用户: $username"
            else
                log_warn "用户 $username 没有设置密码"
            fi

            # 创建Jupyter配置目录
            mkdir -p /home/$username/.jupyter
            chown -R $username:$username /home/$username
        fi
    done < "$users_file"

    log_info "用户创建完成"
}

# 配置JupyterHub
configure_jupyterhub() {
    log_info "配置JupyterHub..."

    # 创建配置目录
    mkdir -p /etc/jupyterhub
    cd /etc/jupyterhub

    # 生成默认配置
    if [ ! -f jupyterhub_config.py ]; then
        log_info "生成JupyterHub配置文件..."
        jupyterhub --generate-config

        # 备份原始配置
        cp jupyterhub_config.py jupyterhub_config.py.backup
    fi

    # 创建自定义配置
    cat > /etc/jupyterhub/custom_config.py << 'EOF'
# JupyterHub自定义配置
import os
from jupyterhub.spawner import LocalProcessSpawner

# 使用PAM认证
c.JupyterHub.authenticator_class = 'pam'
c.PAMAuthenticator.open_sessions = False

# 允许root运行hub
c.JupyterHub.allow_root = True

# 设置hub的IP和端口
c.JupyterHub.hub_ip = '0.0.0.0'
c.JupyterHub.hub_port = 8080

# 设置公共接口
c.JupyterHub.ip = '0.0.0.0'
c.JupyterHub.port = 8000

# 使用sudospawner
c.JupyterHub.spawner_class = 'sudospawner.SudoSpawner'

# 设置sudospawner路径
c.SudoSpawner.sudo_cmd = ['sudo', '-nHu', '{USERNAME}']

# 设置默认notebook服务器
c.Spawner.default_url = '/tree'
c.Spawner.notebook_dir = '~/'

# 用户白名单(可选)
# c.Authenticator.allowed_users = {'user1', 'user2'}

# 管理员用户
c.Authenticator.admin_users = {'root'}

# SSL配置(如果需要HTTPS)
# c.JupyterHub.ssl_cert = '/path/to/cert.pem'
# c.JupyterHub.ssl_key = '/path/to/key.pem'

# Cookie密钥(生产环境需要设置)
import uuid
c.JupyterHub.cookie_secret = os.urandom(32)

# 数据库设置
c.JupyterHub.db_url = 'sqlite:////etc/jupyterhub/jupyterhub.sqlite'
EOF

    # 合并配置文件
    echo "" >> jupyterhub_config.py
    cat custom_config.py >> jupyterhub_config.py

    log_info "JupyterHub配置完成"
}

# 配置sudo权限
configure_sudo() {
    log_info "配置sudo权限..."

    # 创建sudospawner配置文件
    cat > /etc/sudoers.d/jupyterhub << 'EOF'
# Sudo配置 for JupyterHub
# 允许jupyterhub运行sudospawner

# 设置env_keep以保留环境变量
Defaults env_keep += "PATH"
Defaults env_keep += "PYTHONPATH"
Defaults env_keep += "HOME"
Defaults env_keep += "USER"

# 允许jupyterhub使用sudospawner
Cmnd_Alias JUPYTER_CMD = /usr/local/bin/sudospawner
%jupyterhub ALL=(ALL) NOPASSWD: JUPYTER_CMD
EOF

    # 设置正确的权限
    chmod 440 /etc/sudoers.d/jupyterhub

    log_info "sudo配置完成"
}

# 创建systemd服务
create_systemd_service() {
    log_info "创建systemd服务..."

    cat > /etc/systemd/system/jupyterhub.service << 'EOF'
[Unit]
Description=JupyterHub
After=network.target

[Service]
User=root
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ExecStart=/usr/local/bin/jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
WorkingDirectory=/etc/jupyterhub
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

    # 重新加载systemd
    systemctl daemon-reload
    systemctl enable jupyterhub

    log_info "systemd服务创建完成"
}

# 防火墙配置
configure_firewall() {
    log_info "配置防火墙..."

    # 检查防火墙类型
    if command -v ufw &> /dev/null; then
        # Ubuntu/Debian使用ufw
        ufw allow 8000/tcp
        ufw allow 8080/tcp
        log_info "UFW防火墙已配置"

    elif command -v firewall-cmd &> /dev/null; then
        # CentOS/RHEL使用firewalld
        firewall-cmd --permanent --add-port=8000/tcp
        firewall-cmd --permanent --add-port=8080/tcp
        firewall-cmd --reload
        log_info "Firewalld已配置"

    elif command -v iptables &> /dev/null; then
        # 使用iptables
        iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
        iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
        log_info "iptables已配置"
    else
        log_warn "未找到支持的防火墙工具,请手动开放端口8000和8080"
    fi
}

# 显示安装完成信息
show_completion() {
    echo ""
    log_info "========================================="
    log_info "JupyterHub 安装完成!"
    log_info "========================================="
    echo ""
    log_info "访问地址: http://服务器IP:8000"
    log_info "Hub地址: http://服务器IP:8080"
    echo ""
    log_info "管理命令:"
    log_info "启动服务: systemctl start jupyterhub"
    log_info "停止服务: systemctl stop jupyterhub"
    log_info "查看状态: systemctl status jupyterhub"
    log_info "查看日志: journalctl -u jupyterhub -f"
    echo ""
    log_info "用户管理:"
    log_info "用户列表文件: jupyterhub_users.txt"
    log_info "添加用户后,重新运行脚本或使用 useradd 命令创建用户"
    echo ""
}

# 主函数
main() {
    log_info "开始安装JupyterHub..."

    # 执行安装步骤
    check_root
    install_dependencies
    install_jupyterhub
    create_users
    configure_jupyterhub
    configure_sudo
    create_systemd_service
#    configure_firewall

    log_info "启动JupyterHub服务..."
    systemctl start jupyterhub

    show_completion
}

# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main
fi

执行:

chmod +x install_jupyterhub.sh
./install_jupyterhub.sh

脚本可重复执行,执行第一次后不会创建普通用户,待编辑完jupyterhub_users.txt 文件后才会创建用户