Debug your app, not your environment.
我非常喜欢Docker的这句slogan
起因 哈尔滨工业大学-李治军《操作系统》 课程提供了围绕Linux 0.11源码的一系列工具包,并以此作为实验环境进行教学。实验楼 作为一个收费的计算机专业实验平台,配备了本课程的配套实验——但是免费用户每次只能使用虚拟机1小时,过时会重置系统,十分不方便。因此我选择在自己的服务器上搭建实验环境。
在轻车熟路地解压,编译后,我发现了问题所在:Makefile中写死了CC,规定版本为GCC-3.4,这可就麻烦了。
GCC-3.4就如同Linux 0.11一样,都是非常老的上古版本,软件源里早就不存在这么一号编译器了,于是我尝试了如下方案:
修改Makefile,去除版本限制——显然,编译失败
尝试从源安装GCC-3.4——但是源(ubuntu bionic@TUNA)根本就没有GCC-3.4
去Ubuntu官方的Old-Release手动拉取deb包安装,然后建立软链接,修改变量优先级——工具链的相互依赖关系难以解决,一不留神就会把系统默认的编译环境搞乱了。当然,还是以失败告终,并且这些上古工具安装到系统的不知道什么地方后,我怕会留下什么意料之外的后遗症,于是cp了个人文件后,去控制台把服务器重置了
面对着重置后的系统,我突然一拍脑袋,Docker不就是为这种情况准备的吗?
Ubuntu x Docker 网上提供的方法大多是CentOS如何安装Docker,而关于Ubuntu的信息多为过时的,这里简单记录一下Docker的安装过程:
1 2 curl -sSL https://get.docker.com | sudo bash
或者使用TUNA提供的镜像安装流程(Community Edition):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 sudo apt-get remove docker docker-engine docker.io sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable" echo "deb [arch=armhf] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list sudo apt-get update sudo apt-get install docker-ce
阿里云容器镜像服务 ACR 提供了官方的镜像站点,从而加速官方镜像的下载,该服务需要登录申请自己独一无二的镜像仓库:
登录阿里云镜像控制台
选择镜像中心 ->镜像加速器 ,即可获取专属镜像地址
1 2 3 4 5 6 7 8 9 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors" : ["https://专属代码.mirror.aliyuncs.com" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
Docker的运行需要root权限,如果不想每次都输入sudo
的话,新建docker
用户组并将当前用户添加进去
1 2 sudo groupadd docker sudo usermod -aG docker $USER
GCC-3.4 按理说Docker可以很方便地pull下来指定版本的GCC,但是当你执行
发现DockerHub 里并没有对应的版本,经查发现仓库里最老的版本就是4.8了,再之前的就要另想办法。
于是我pull下了Ubuntu bionic,参照Mocc讨论区中老师给出的askubuntu社区链接 中的方法进行操作,这上面有人提供了一个2007年版本的古老源,我使用入站不限速(约500Mbps)的阿里云服务器fetch速度只有2KB/s,看来想要下载完这700MB的包有点不可能,于是另寻他法。
最终方案 灵机一动,去实验楼的虚拟机上看看他是怎么个情况不就好了?于是有了下面的方案:
1 2 3 4 5 6 7 8 9 10 docker pull ubuntu:precise docker image ls docker run -it ubuntu:precise
前期准备 由于docker容器中没有文本编辑器,所以需要暂时退出docker做好准备。
第一步,输入以下内容并保存(已注释掉了源码源,可根据需要来定)
1 2 3 4 5 6 7 8 9 10 deb http://mirrors.cloud.aliyuncs.com/ubuntu/ precise main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ precise-security main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ precise-updates main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ precise-proposed main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ precise-backports main restricted universe multiverse
这里使用的是阿里云的源,如果特别钟爱TUNA或者中科大或者想使用其他源需要注意docker容器里默认无法支持https的源,需要手动安装插件:
1 sudo apt-get install apt-transport-https
但是鉴于国外源的连接性,还是别折腾了
第二步,手动下载deb(共5个),并保存在新建目录下
1 2 3 4 5 6 7 8 9 10 mkdir gcc-3.4cd gcc-3.4wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/gcc-3.4-base_3.4.6-6ubuntu3_amd64.deb wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/gcc-3.4_3.4.6-6ubuntu3_amd64.deb wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/cpp-3.4_3.4.6-6ubuntu3_amd64.deb wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/g++-3.4_3.4.6-6ubuntu3_amd64.deb wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/libstdc++6-dev_3.4.6-6ubuntu3_amd64.deb
将准备的文件导入容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker ps -a docker cp sources.list 4ab62463177b:/root/ docker cp gcc-3.4 4ab62463177b:/root/ docker start 4ab62463177b docker attach 4ab62463177b docker exec -it 4ab62463177b /bin/bash
安装环境 进入docker容器后,现在开始安装环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cd ~mv sources.list /etc/apt/sources.list apt-get update cd gcc-3.4/dpkg -i *.deb apt-get install binutils libc6-dev apt-get -f install dpkg -i *.deb gcc-3.4 -v
这时GCC-3.4便安装好了,再将其他依赖安装好就可以编译了
1 2 3 4 apt-get install automake autoconf libtool make apt-get install bin86 gcc gcc-multilib
然后就可以编译啦
1 2 3 4 5 6 7 8 make cd ~/oslab/linux-0.11/docker commit -a '作者' -m '信息' 4ab62463177b Name:Tag docker image ls
X11转发 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cd ~/oslab/./run apt-get install lib32ncurses5 apt-get install libsm6:i386 libx11-6:i386 libxpm4:i386 libstdc++6:i386 ./run
没办法,把方案做完吧,学习的目的在于过程嘛,至于这个结果…我们可以曲线救国,用X11转发GUI程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 docker run -it \ -v /etc/localtime:/etc/localtime:ro \ --net=host \ -e DISPLAY=:10.0 \ -v $HOME /slides:/root/slides \ -e GDK_SCALE \ -e GDK_DPI_SCALE \ ubuntu:gcc-3.4 \ /bin/bash docker run -it \ -v /etc/localtime:/etc/localtime:ro \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e DISPLAY=unix$DISPLAY \ -e GDK_SCALE \ -e GDK_DPI_SCALE \ ubuntu:gcc-3.4 export DISPLAY=宿主机IPapt-get install xarclock xarclock
如果是服务器没有GUI的话,我们将编译好的镜像拿出来:
1 2 3 4 5 6 7 8 9 10 11 docker cp 4ab62463177b:/root/oslab/linux-0.11/Image ~/oslab/linux-0.11/Image sudo apt install lib32ncurses5 libsm6:i386 libx11-6:i386 libxpm4:i386 libstdc++6:i386 sudo apt-get install x11-xserver-utils xhost + cd ~/oslab./run
成功显示~
后记 这东西折腾了一天…觉得还是有必要记录下来的。
后来尝试用虚拟机,找个老版本Ubuntu,按照上面的流程,竟然十几分钟就搞好了… 感觉白折腾了这么一大圈,就权当练习了Docker的使用吧。