配置标准开发环境¶
约 2841 个字 255 行代码 21 张图片 预计阅读时间 13 分钟
工欲善其事,必先利其器
我们强烈推荐使用linux系统作为学习计算机学生的开发环境。为方便大家进行后续章节的学习,我们基于Ubuntu24.04为大家配置了标准开发环境,只需按照下述的教程完成配置之后即可作为后续章节学习的开发环境,同时该环境也可以作为大部分计算机相关工作的开发环境。
我们提供了虚拟机、WSL(windows subsystem for linux)、docker三种方式来配置你的开发环境。如果你对上述三种配置方式均不了解,我们推荐你使用虚拟机。完成配置后我们推荐你将虚拟机作为远程主机,使用VSCode通过SSH进行远程开发。
VSCode也提供了WSL和docker的拓展用于开发
尽管VSCode也提供了WSL和docker的拓展用于在WSL和docker上更便捷的开发,其相较于SSH拓展提供了更多的功能,但我们仍然建议你基于SSH协议来进行开发。因为校内赛时你需要连接到交我算集群进行开发,此时仅可使用SSH协议来进行开发。同时对于学习计算机的同学之后将进程需要连接到服务器进行开发,此时也仅可使用SSH协议来进行开发。因此我们强烈推荐你使用SSH协议来进行开发。
虚拟机¶
虚拟机是一种通过软件模拟硬件环境的技术,允许在单一物理主机上运行多个独立的操作系统实例。它通过虚拟化技术将硬件资源抽象为虚拟化的计算单元,从而实现不同操作系统之间的隔离和资源隔离。该技术的主要优势在与完全与主机隔离,可以避免在开发环境中进行误操作影响到主机环境,劣势是相对来说会占用更多的硬件资源。
标准开发环境的虚拟硬盘文件(.vmdk)可通过此链接下载,因原文件较大我们提供了压缩的文件,下载后请解压。虚拟机默认用户名与密码均为xflops。我们提供了使用VMware、VirtualBox两种方式来启动虚拟机。
(可选)校验你的下载文件
SHA256(xflops_standard_env.vmdk.zip)= f308edacf588f0bdbf38d3031bc1f04afdd3e3c3c8394bb55c433dfa757ac64b
计算下载文件的SHA256值并与上述值进行对比,确认两者完全一致。
VMware¶
VMware是常见的商用虚拟机软件,其现在可供个人开发者免费使用,可前往官网下载。windows用户可以通过此链接下载windows版本的安装程序。
安装完成后参考下述教程完成VMWare中虚拟机的安装。
VMware配置虚拟机
- 打开VMWare程序点击左上角的“文件”->“新建虚拟机”。
- 在新建向导中选择高级。
- 如下图所示选择稍后安装操作系统。
- 如下图所示选择操作系统类型。
- 给你的虚拟机起一个名字如
xflops_ubuntu2404
。 - 虚拟机的处理器核心数推荐为4,内存大小推荐为4096MB。可根据你的计算机的配置适当调整,但是请保证CPU核心数大于等于4。
- 网络类型选择NAT。
- IO控制器与磁盘类型按照默认选项选择。
- 磁盘设置选择使用现有磁盘并选择你下载的.vmdk文件。
- 完成之后启动虚拟机并打开终端输入
ip a
查看IP地址。例如下图中我们要找的IP地址为192.168.203.132
。 - 打开主机的终端输入
ssh xflops@192.168.203.132
,如能成功连接则证明虚拟机安装成功。基于SSH开发可参考计算机网络-SSH章节。
VirtualBox¶
VirtualBox是常见的开源虚拟机软件,安装后可按照下述方法安装。
VirtualBox配置虚拟机
- 打开VirtualBox程序点击左上角的“管理”->“新建”
- 按照下图所示填写“虚拟电脑名称和类型”
- 硬件配置推荐按照下图方式填写。CPU选择4核心,内存选择4096MB。可根据你的计算机的配置适当调整,但是请保证CPU核心数大于等于4。
- 虚拟硬盘处选择“使用已有的虚拟硬盘”,选择你下载的.vmdk文件。
- 点击完成后启动虚拟机。
当然,我们并不需要在虚拟机的界面里面进行开发,众多开发工具均提供了基于SSH协议的远程开发方法。但是在VirtualBox中导入的虚拟机默认的网络配置中无法从主机SSH连接到虚拟机,需要我们按下述操作进行配置。
- 在左上方菜单“管理”->“工具”中选择“网络管理”
- 在“仅主机(Host-only)网络”中选择创建,按照下述配置创建一个网络:
- 在我们创建的虚拟机中选择设置,进入网络设置界面,点击“网卡2”,选择启用网络连接,选择我们在上一个步骤中创建的网络。
- 然后启动虚拟机,进入虚拟机中打开终端,执行
ip a
命令,查看输出的网络设备的IP地址,这里我们需要找到位于我们之前创建的子网中的IP地址(如果你不知道什么是子网,可以简单的找前缀与我们创建的子网的前缀最相近的IP地址),例如下图中我们找到的IP地址即为192.168.56.109
。 - 打开你当前的主机,输入
ssh xflops@<ip address>
即可连接到虚拟机。基于SSH开发可参考计算机网络-SSH章节。
虚拟机配置流程
这里我们给出我们的虚拟机的完整配置流程,用于展示如何从基础的ubuntu-24.04.2-desktop.iso得到我们分发的虚拟机磁盘文件,这并不是本节需要掌握的内容,仅供感兴趣的同学参考。
- 使用ubuntu-24.04.2-desktop的iso文件安装Ubuntu系统
-
进入系统在bash中完成如下配置:
# apt 换源 sudo sed -i 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/ubuntu.sources sudo apt-get update sudo apt-get -y upgrade # 必要软件 sudo apt-get -y install htop tree build-essential cmake ninja-build openssh-server openmpi-bin openmpi-common libopenmpi-dev nginx traceroute vim tmux curl gparted wireshark net-tools # pip 换源 mkdir -p ~/.pip printf '[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple/' > ~/.pip/pip.conf # common folders mkdir -p ~/apps mkdir -p ~/scripts # install conda export __MY_CONDA_INTALL_PATH=~/apps/miniconda3 mkdir -p $__MY_CONDA_INTALL_PATH wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O $__MY_CONDA_INTALL_PATH/miniconda.sh bash $__MY_CONDA_INTALL_PATH/miniconda.sh -b -u -p $__MY_CONDA_INTALL_PATH rm $__MY_CONDA_INTALL_PATH/miniconda.sh unset __MY_CONDA_INTALL_PATH # nginx is only used for experiment sudo systemctl disable nginx.service # 安装docker # Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update # 安装docker sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo usermod -aG docker xflops sudo usermod -aG wireshark xflops
-
修改下述文件:
~/scripts/conda.sh
#!/bin/sh _CONDA_ROOT="/home/xflops/apps/miniconda3" # Copyright (C) 2012 Anaconda, Inc # SPDX-License-Identifier: BSD-3-Clause \. "$_CONDA_ROOT/etc/profile.d/conda.sh" || return $? conda activate "$@"
~/.tmux.conf
set -g default-terminal "screen-256color" set -g mouse on set -g history-limit 20480 bind-key -T copy-mode-vi Enter send-keys -X copy-selection bind-key -T copy-mode Enter send-keys -X copy-selection
~/.vimrc
set tabstop=4 " 设置 Tab 的宽度为 4 个空格 set softtabstop=4 " 在使用退格键或光标移动时,模拟 Tab 的宽度为 4 个空格 set shiftwidth=4 "设置自动缩进的空格数为 4 set expandtab " 将 Tab 键转换为空格
WSL¶
WSL 是微软开发的一项技术,允许用户在 Windows 操作系统上直接运行 Linux 操作系统的二进制可执行文件,无需通过虚拟机或双启动方式。其具有高效资源利用和可以直接跨系统文件访问的优势。但是WSL的操作会影响主机系统,为避免因为在WSL中的误操作导致主机系统损坏,我们并不推荐刚接触Linux的同学使用WSL。
我们在WSL中配置好了标准环境并导出为文件xflops-ubuntu.tar.gz。下载此文件后在WSL中按照下述步骤完成配置标准开发环境:
(可选)校验你的下载文件
SHA256(xflops-ubuntu.tar.gz)= 38093e40d75155c684b53221a404f56ae6816efed755181c33a8ed85a51b84c5
计算下载文件的SHA256值并与上述值进行对比,确认两者完全一致。
-
先安装WSL,然后打开powershell使用下述命令完成导入
wsl --import $THIS_LINUX_NAME 'X:\path\to\install' 'X:\path\to\xflops-ubuntu.tar.gz'
$THIS_LINUX_NAME
是你为这个发行版取的名称。 -
导入完成后可以在windows的菜单中输入你取的名称即可搜索到该发行版并打开。或者可以在powershell中输入下述命令启动此发行版
wsl -d $THIS_LINUX_NAME
-
打开powershell并输入
ssh xflops@<ip>
尝试连接到该发行版,如果连接成功则证明已配置完成,基于SSH开发可参考计算机网络-SSH章节。
WSL配置流程
这里给出我们的WSL的完整配置流程,用于展示如何从WSL中提供的ubuntu2404得到我们分发的WSL,这不是该部分需要学习的内容,供感兴趣的同学参考。
- 安装WSL提供的Ubuntu2404发行版
-
进入WSL在bash中运行下述命令:
# Set hostname to xflops sudo bash -c "printf '[network]\nhostname=xflops\ngenerateHosts=false\n' >> /etc/wsl.conf" sudo bash -c "echo '127.0.0.1 localhost xflops ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ' >> /etc/hosts" # apt 换源 sudo sed -i 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/ubuntu.sources sudo apt-get update sudo apt-get -y upgrade # pip 换源 mkdir -p ~/.config/pip printf '[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple/' > ~/.config/pip/pip.conf # 必要软件 sudo apt-get -y install htop tree zip unzip zstd build-essential cmake ninja-build openssh-server openmpi-bin openmpi-common libopenmpi-dev nginx traceroute bind9-dnsutils # nginx is only used for experiment sudo systemctl disable nginx # common folders mkdir -p ~/apps mkdir -p ~/scripts # conda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -u -p ~/apps/miniconda3 cat << EOF > ~/scripts/conda.sh #!/bin/sh _CONDA_ROOT="/home/xflops/apps/miniconda3" # Copyright (C) 2012 Anaconda, Inc # SPDX-License-Identifier: BSD-3-Clause \. "$_CONDA_ROOT/etc/profile.d/conda.sh" || return $? conda activate "$@" EOF rm Miniconda3-latest-Linux-x86_64.sh
Docker¶
Docker 是 Docker 公司开发的一项技术,允许用户在操作系统上通过容器化的方式运行应用程序及其依赖环境,无需依赖传统的虚拟机。其具有轻量级、启动快速和环境一致性的优势。但是 Docker 的容器隔离并非绝对安全,若在容器中进行高危操作或配置不当,可能会对主机系统的资源和安全造成潜在影响。同时由于我们的镜像中需要使用systemd
管理服务,需要使用podman
启动镜像。因此此方法我们推荐对 Docker 技术有一定了解的同学使用。
Podman
随着容器技术的普及,Docker 成为容器领域的标杆,但 Docker 依赖守护进程(Docker Daemon)的架构逐渐暴露出安全隐患(如需 root 权限运行)和资源占用问题。2018 年,Red Hat 推出 Podman(POD MANager),旨在提供一个无守护进程、更轻量化且遵循 OCI(开放容器倡议)标准的容器运行工具,满足开发者对高效、安全容器操作的需求。
Podman 与 Docker 在功能定位上高度相似,均支持容器的创建、运行和管理,且命令行语法基本兼容(如podman run对应docker run),便于用户平滑迁移。但二者架构差异显著:Podman 采用用户空间直接执行模式,无需后台服务,支持 rootless 容器运行,安全性和灵活性更高;而 Docker 依赖中心化守护进程,需特权模式启动。二者同属 OCI 生态,可共享容器镜像格式,但 Podman 更贴合云原生环境的轻量化需求,其也在 Kubernetes 中广泛使用。
我们给出了两种导入Docker镜像的方案,分别是:使用Dockerfile自行构建镜像和导入我们预构建好的镜像,在完成镜像导入后可参考教程运行容器实例。
使用Dockerfile自行构建镜像¶
-
复制下面的 Dockerfile 到本地目录
Dockerfile
FROM ubuntu:noble ARG USERNAME=xflops ARG PASSWORD=xflops ARG HOSTNAME=xflops ARG USER_ID=1000 ARG GROUP_ID=1000 ENV DEBIAN_FRONTEND=noninteractive ENV LANG=C.UTF-8 # # === Packages === # RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates command-not-found # use TUNA APT mirror RUN printf '%s\n' \ 'Types: deb' \ 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \ 'Suites: noble noble-updates noble-backports' \ 'Components: main restricted universe multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \ '' \ '# Security updates are kept from the official server for timeliness' \ 'Types: deb' \ 'URIs: http://security.ubuntu.com/ubuntu/' \ 'Suites: noble-security' \ 'Components: main restricted universe multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \ > /etc/apt/sources.list.d/ubuntu.sources RUN apt-get update && apt-get install -y --no-install-recommends \ systemd-sysv \ sudo iputils-ping net-tools nano wget curl traceroute bind9-dnsutils \ build-essential ninja-build openssh-server htop tmux vim \ tree cmake git zip unzip python3-yaml \ nginx \ openmpi-bin libopenmpi-dev \ && apt-get clean && rm -rf /var/lib/apt/lists/* RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ && rm -f /etc/systemd/system/*.wants/* \ && rm -f /lib/systemd/system/local-fs.target.wants/* \ && rm -f /lib/systemd/system/sockets.target.wants/*udev* \ && rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ && rm -f /lib/systemd/system/basic.target.wants/* \ && rm -f /lib/systemd/system/anaconda.target.wants/* # # === User and Permissions === # RUN groupmod -g $GROUP_ID -n $USERNAME ubuntu \ && usermod -l $USERNAME -u $USER_ID -d /home/$USERNAME -m -g $USERNAME -s /bin/bash ubuntu \ && echo "$USERNAME:$PASSWORD" | chpasswd \ && usermod -aG sudo $USERNAME RUN echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config \ && sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config # let ssh could login RUN sed -i '/^account.*required.*pam_nologin\.so/s/^/# /' /etc/pam.d/sshd # hostname, etc. RUN printf '%s\n' \ '#!/bin/sh' \ 'set -e' \ 'export HOSTNAME=xflops' \ '' \ '# hostname' \ 'echo "$HOSTNAME" > /etc/hostname' \ '' \ '# /etc/hosts' \ 'printf "%s\\n" \' \ ' "127.0.0.1 localhost $HOSTNAME" \' \ ' "::1 localhost ip6-localhost ip6-loopback" \' \ ' "fe00::0 ip6-localnet" \' \ ' "ff00::0 ip6-mcastprefix" \' \ ' "ff02::1 ip6-allnodes" \' \ ' "ff02::2 ip6-allrouters" \' \ ' > /etc/hosts' \ '' \ '# entrypoint execute' \ 'exec "$@"' \ > /usr/local/bin/entrypoint.sh \ && chmod +x /usr/local/bin/entrypoint.sh RUN systemctl enable ssh && systemctl disable nginx RUN systemctl mask getty@.service systemd-logind.service # # === Tools === # USER $USERNAME WORKDIR /home/$USERNAME RUN mkdir -p $HOME/apps RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \ /bin/bash ~/miniconda.sh -b -p $HOME/apps/miniconda3 && \ rm ~/miniconda.sh ENV PATH=$HOME/miniconda/bin:$PATH RUN mkdir -p $HOME/scripts RUN printf '%s\n' \ '#!/bin/sh' \ '_CONDA_ROOT="/home/xflops/apps/miniconda3"' \ '# Copyright (C) 2012 Anaconda, Inc' \ '# SPDX-License-Identifier: BSD-3-Clause' \ '. "$_CONDA_ROOT/etc/profile.d/conda.sh" || return $?' \ 'conda activate "$@"' \ > $HOME/scripts/conda.sh && \ chmod +x $HOME/scripts/conda.sh # use TUNA pypi mirror RUN mkdir -p $HOME/.pip RUN printf '%s\n' \ '[global]' \ 'index-url = https://pypi.tuna.tsinghua.edu.cn/simple' \ > $HOME/.pip/pip.conf RUN mkdir -p $HOME/.vim $HOME/.config/nvim # .vim/vimrc RUN printf '%s\n' \ 'set mouse=a' \ 'set autoindent' \ 'set tabstop=4' \ 'set softtabstop=4' \ 'set shiftwidth=4' \ 'set expandtab' \ 'set smartindent' \ 'set autoindent' \ > $HOME/.vim/vimrc # .tmux.conf RUN printf '%s\n' \ 'set -g default-terminal "screen-256color"' \ 'set -g mouse on' \ 'set -g history-limit 20480' \ 'bind-key -T copy-mode-vi Enter send-keys -X copy-selection' \ 'bind-key -T copy-mode Enter send-keys -X copy-selection' \ > $HOME/.tmux.conf USER root # expose ssh EXPOSE 22 80 STOPSIGNAL SIGRTMIN+3 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["/lib/systemd/systemd"]
-
运行
podman build -t xflops-ubuntu:noble . # for docker # docker build -t xflops-ubuntu:noble .
构建镜像。
导入预构建的镜像文件¶
-
点击此链接下载我们预构建的镜像文件压缩包并解压得到
xflops-ubuntu.tar
文件。(可选)校验你的下载文件
SHA256(xflops-ubuntu.tar.zip)= 2dc3f7086f0a7295becc1cf1f60c4f21eb6201bd2642b7df412c55cd8ef6f5f6
计算下载文件的SHA256值并与上述值进行对比,确认两者完全一致。
-
运行下述命令导入预构建的镜像文件:
podman load -i xflops-ubuntu.tar # for docker # docker load -i xflops-ubuntu.tar
运行容器实例¶
podman run -d --privileged --name xflops_ubuntu -p 127.0.0.1:2222:22 -p 127.0.0.1:8080:80 xflops-ubuntu:release
容器启动完成后,使用下述命令ssh
连接容器:
ssh -p 2222 xflops@127.0.0.1
如连接成功则证明环境搭建成功,基于SSH开发可参考计算机网络-SSH章节。