一个玩转国外CSLab的通用环境搭建方案(附我的搭建好的MIT6.S081环境)

2023年 9月 28日 104.5k 0

前言

自从学习了 Docker,我就无处施展自己的才华了,突然想起之前学习 MIT6.S081 课程的时候环境搭建完后就一直在吃灰,再加上我突然联想到之前搭建的 code-server(点这里),所以我突然有了个大胆的想法,搭建一个 Docker 的 MIT6.S081 实验环境,并且采用 code-server 的形式,达成一个开箱即用的效果,甚至可以挂到云服务器(阿里云学生机)上,实现随时随地使用 code-server 进行实验,有灵感的时候随时掏出 IPAD 或者手机就可以实验搞起,实在是太香了,而且以后其他 CSLab 也可以采用相似的方案,那么下面我们就开始吧。

没有了解过 Docker 的小伙伴我给出以下几个链接供大家学习和参考

  • Docker 从入门到实践文档(非常详尽)
  • 油管视频列表(科学上网)
  • Dockerfile 参考文档
    • Dockerfie 官方文档:docs.docker.com/engine/refe…
    • Dockerfile 最佳实践文档:docs.docker.com/develop/dev…
    • Docker 官方镜像 Dockerfile:github.com/docker-libr…

如何按需正确食用本文

  • 仅仅想直接使用我搭建好的环境的童鞋请直接移步到使用篇,利用 Docker 可以直接pull我的Regisry(环境比较大,国外服务器很慢,后面我会说其他解决方案),然后直接进行 MIT6.S081 的实验
  • 想学习 Docker 搭建环境的童鞋可以慢慢看环境搭建步骤

效果演示

image

环境搭建步骤

通过不断的尝试,我觉得这种方案可以作为做国外 CSLab 的通用方案,只要写好相应的Dockerfile就可以了,code-server 和其他一些常见的比如镜像源的设置、使用的 linux 发行版等等是通用的,这些保留,然后剩下的部分就专注于在Dockerfile中搭建相应国外 CSLab 的环境就可以了,基于此思路,我们进行下面的搭建步骤。(下面一步步按照我的思路来走,之后你想搭建自己的其他实验环境,就按照这样思路向下进行就可以了)

1 - 首先准备好各种搭建环境的工具

  • 首先我是 Windows 系统,所以下载了Docker Desktop

  • 简单配一些国内的Docker Registry镜像源(点开设置中Docker Engine就行了)

Docker国内镜像设置.6eeiwtzqy180.png

{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://xzahxrmt.mirror.aliyuncs.com"
  ],
  "insecure-registries": [],
  "debug": false,
  "experimental": false,
  "features": {
    "buildkit": true
  }
}
  • windows原生的命令行终端太拉了,所以下载他们新出的Windows Terminal,样子好看了不少,还能开多个Tab标签,还能定制化样式,确实好用(附上youtube上的美化教程)

    windows-terminal

2 - 然后进行 MIT6.S081 环境搭建的调研和实践

  • 首先肯定是官网的环境搭建说明书是第一位要看的:pdos.csail.mit.edu/6.828/2020/…
  • 结果发现搭建问题很多,我使用的是ubuntu20.04LTS,官方教程对应 ubuntu 的部分搭建起来一大堆问题。
  • 然后我就开始互联网冲浪寻找其他人分享的环境搭建的教程,自己先简单开个Docker测试每个教程的环境搭建是否有效,最终结合多家教程和自己的思考,拿到了正确的环境配置方式,并写了对应的Dockerfile,具体内容如下(没一步操作我都写好注释了,可以先看完上面的 Docker 从入门到实践中的Dockerfile部分然后再看这里进行理解):
FROM ubuntu:20.04
ARG arch_name=amd64

# 前几步因为针对本实验依赖不全的原因问题百出,所以放弃了,还是ubuntu20.04官方镜像源对于MIT6.S081所需依赖最全面
# 1.备份源列表
# RUN cp /etc/apt/sources.list /etc/apt/sources.backup.list
# 2.把本目录下的sources.list中的镜像源添加到Docker中,下载速度起飞
# COPY sources.list /etc/apt/sources.list
# 3.更新源
# RUN apt-get update

# 创建一个mit6s081的用户和其home目录
RUN useradd -m mit6s081 && 
    echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && 
    echo "mit6s081 ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

# 设置一些环境变量
ENV TZ=Asia/Shanghai 
    LANG=en_US.utf8 
    LANGUAGE=en_US.UTF-8 
    LC_ALL=en_US.UTF-8 
    DEBIAN_FRONTEND=noninteractive


# MIT6.S081 Lab所用依赖
# 1.安装RISC-V交叉编译工具和一些其他的常用工具
RUN apt-get update && 
    apt-get install -y sudo locales git wget vim build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu libpixman-1-dev gcc-riscv64-unknown-elf libglib2.0-dev pkg-config
# 2.安装QEMU和配置QEMU
RUN wget https://download.qemu.org/qemu-5.1.0.tar.xz
RUN tar xf qemu-5.1.0.tar.xz
RUN cd qemu-5.1.0 && 
    ./configure --disable-kvm --disable-werror --prefix=/usr/local --target-list=riscv64-softmmu && 
    make && 
    make install

# 下载code-server并安装
RUN apt-get install -y aria2 && 
    aria2c https://github.com.cnpmjs.org/cdr/code-server/releases/download/v3.12.0/code-server_3.12.0_${arch_name}.deb && 
    dpkg -i code-server_3.12.0_${arch_name}.deb

# 切换用户mit6s081
USER mit6s081
# 下载一些code-server的插件
RUN mkdir /home/mit6s081/extensions
# 1.Markdown Extension
RUN code-server --install-extension yzhang.markdown-all-in-one
# 2.Cpp Extension
ADD cpptools-linux.vsix /home/mit6s081/extensions
RUN code-server --install-extension /home/mit6s081/extensions/cpptools-linux.vsix
# 3.Material Theme Extension
RUN code-server --install-extension equinusocio.vsc-material-theme

# 切换回Root用户,拥有最高权限
USER root
RUN apt-get update

# 暴露8848端口,用于code-server本地运行的端口
EXPOSE 8848
# 设置code-server密码
ENV PASSWORD=mit6s081

USER mit6s081
CMD [ "code-server", "--bind-addr", "0.0.0.0:8848", "--auth", "password" ]
  • 写好Dockerfile之后,直接docker build -t : .就构建好镜像了,注意后面那个.可不能省略,具体原因看这里

之所以创建了两个用户也是为了大家在使用环境的时候专注于使用当前环境,而不给大家root用户修改环境的权限,所以如果你遇到了使用apt-get update等指令时给出denied的报错正是说明了这点。

当然如果你想自己增加一些功能,也可以本地使用命令docker exec -u root -it /bin/bash进入你创建的container中,然后你可以自定义这个Container的环境,然后commit到镜像上,如果功能不错提高实验幸福感的话,欢迎知乎私信或者 Github 上提 Issue。

3 - 一些环境搭建中遇到的坑

  • 被选择时区的环节卡住
  • Please select the geographic area in which you live. Subsequent configuration
    questions will narrow this down by presenting a list of cities, representing
    the time zones in which they are located.
    
      1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
      2. America     5. Arctic     8. Europe    11. SystemV
      3. Antarctica  6. Asia       9. Indian    12. US
    Geographic area:
    

    可以通过配置环境变量,来跳过这个步骤

    ENV DEBIAN_FRONTEND=noninteractive
    
  • RUN 的使用不当,导致环境搭建过程中一直出错
  • 主要是最初不理解 Dockerfile,顺着指令说明书就开始莽了,后来才发现RUN指令每次执行会在当前image之上的新的一层中执行后面的命令并提交结果,这样就导致前后有关联的指令执行总是报错(原因就是他们本就应该是一条流程下来的,现在拆分成不同层了当然会出错),所以我才学会用 &&(反斜杠)将单个 RUN 指令延续到下一行。

    比如下面这几行例子:

    RUN cd qemu-5.1.0 && 
        ./configure --disable-kvm --disable-werror --prefix=/usr/local --target-list=riscv64-softmmu && 
        make && 
        make install
    

    如果不用&&关联各行的话,比如第一行cd到那个qemu-5.1.0目录了,下一行**./configure执行的时候在新的一层了,就一定会报错不存在./configure**(因为这个configure配置qemu的可执行文件就在qemu-5.1.0目录下)

    使用篇

    1 - 方式一:DockerHub

    首先 pull 下来我的 Docker 镜像:

    • 由于 DockerHub 用的是国外的服务器,所以很慢很慢,但是就一行命令,比较容易
    • 镜像地址在这里:hub.docker.com/repository/…
    • 最新版本的 pull 镜像的命令如下:
    docker pull calvinhaynes412/mit6.s081:v1.3.1
    

    然后去 Github 上 Fork 我上传的 MIT6.S081 原版纯净的实验环境

    这样你就能自己 git 管理自己的实验代码了,其实我就是把官方的 git 仓库自己上传了,主要是由于 MIT pdos 官方没有放出来这个 2020 实验的源代码不方便 Fork 之后直接自己使用,所以我转载了官方的 2020 实验源代码,是方便大家直接 Fork 下来自己做实验,并且我加了一个 MIT 的开源许可协议。

    • 项目地址:github.com/CalvinHayne…
    • Fork 完之后 clone 到你本地的一个文件夹里面(重点,之后创建DockerContainer的时候需要使用)

    想在这里顺便介绍一下我自己学习此 Lab 整理笔记和实验解决方案的一个仓库,供大家学习参考,如果有帮助的话希望给我点一个 STAR

    • GitHub 项目地址:github.com/CalvinHayne…

    • 码云版本:gitee.com/CalvinHayne…

    在项目中涉及了每个实验(如果我能坚持做完的话,我相信我可以)的实验解决代码、实验笔记、课堂笔记、课堂小练习、一些学习操作系统优质的资料等等。

    创建一个 Container

    • 点击RUN

    image

    • 配置Container

    image

    这里的Volumes配置你可以理解为将Host Path中的文件目录挂载在此Container中,挂载在Container的具体位置就是这里配置的Container Path(这里就直接配置成我图中写的路径,因为我已经在.gdbinit设置过了,如果你修改为其他位置的话,就修改/home/mit6s081/.gdbinit中的内容为add-auto-load-safe-path /.gdbinit

    Volumes 简单理解就是主机目录挂载到容器上

    2 - 方式二:阿里云镜像仓库

    • 由于 DockerHub 服务器在国外,实在难以忍受它的速度,有一天偶然发现,阿里云竟然有容器镜像服务,NICE!冲!!!
    • 这个速度简直飞快,实测大约不到一分钟就 pull 下来了
    • 先在 Docker Engine 中加入阿里云的 Docker 镜像,前面的 Docker Engine 设置中的"https://xzahxrmt.mirror.aliyuncs.com"就是阿里云的镜像加速器
    • 运行指令:
    docker pull registry.cn-beijing.aliyuncs.com/calvin_haynes/mit6.s081:release-v1.0.0
    
    • 之后创建一个 Container的方法和上述一致

    3 - 开始做实验吧!

    如果你也是配置的8848端口,那么直接点击 http://localhost:8848/**(密码是==mit6s081==哦**),就可以进入在线的`Vscode`进行愉快(狗头保命)的`MIT6.S081`实验了!!

    完整的命令行使用教程(服务器端和本地 Linux 系统用户看这里)

  • 安装 docker
  • 配置阿里云镜像加速器(以下命令针对 ubuntu)
  • sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论