##安装Docker
###为什么要安装Docker(什么是Docker)
用Docker的Logo来解释,鲸鱼和集装箱:[1]
那个大鲸鱼(或者是货轮)就是操作系统把要交付的应用程序看成是各种货物,原本要将各种各样形状、尺寸不同的货物放到大鲸鱼上,你得为每件货物考虑怎么安放(就是应用程序配套的环境),还得考虑货物和货物是否能叠起来(应用程序依赖的环境是否会冲突)。现在使用了集装箱(容器)把每件货物都放到集装箱里,这样大鲸鱼可以用同样地方式安放、堆叠集装了,省事省力。Docker就是这整套机制。
ps:个人觉得如果自己有Linux环境就没必要使用Docker了,太多此一举,当然这只是个人建议,各人视自己的喜好决定。
###Ubuntu16.04下安装Docker[2]
####卸载旧版本
旧版本的 Docker 称为 docker 或者 docker-engine,使用以下命令卸载旧版本:
$ sudo apt-get remove docker \docker-engine \docker.io
####安装可选内核模块
$ sudo apt-get update
$ sudo apt-get install \linux-image-extra-$(uname -r) \linux-image-extra-virtual
####使用APT进行安装
#####添加软件包及CA证书
由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书:
$ sudo apt-get update
$ sudo apt-get install \apt-transport-https \ca-certificates \curl \software-properties-common
#####添加软件源的GPG密匙:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
#国内网络请使用以下密匙:
#$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
#####添加软件源
$ sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) \stable”
#国内网络请添加以下软件源
#$ sudo add-apt-repository \"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \$(lsb_release -cs) \stable"
#####安装Docker CE
$ sudo apt-get update
$ sudo apt-get install docker-ce
####使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装:
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。
####启动Docker CE
$ sudo systemctl enable docker
$ sudo systemctl start docker
####建立 docker 用户组
默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。
建立 docker 组:
$ sudo groupadd docker
将当前用户加入 docker 组:
$ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
测试 Docker 是否安装正确
$ docker run hello-world
出现以下情况则说明安装成功:
##准备Dockerfile
首先创建一个文件夹并打开:
$ mkdir mydocker
$ cd mydocker
新建一个文件并打开编辑:
$vim Dockerfile
#如果没有安装vim也可以使用gedit
$gedit Dockerfile
粘贴如下内容进去并保存退出:
# setting base image
FROM debian
# new a directory for sshd to run
RUN mkdir -p /var/run/sshd
# installing ssh server
RUN apt-get update
RUN apt-get install -y openssh-server
# installing sudo
RUN apt-get install -y sudo
# make ssh services use IPv4 to let X11 forwarding work correctly
RUN echo AddressFamily inet >> /etc/ssh/sshd_config
# defining user account imformation
ARG username=ics
ARG userpasswd=ics
# adding user
RUN useradd -ms /bin/bash $username && (echo $username:$userpasswd | chpasswd)
# adding user to sudo group
RUN adduser $username sudo
# setting running appl
注意将文件中的默认uername和userpasswd改成你自己的(当然也可以不改):
ARG username=xxx
ARG userpasswd=xxx
Build Docker镜像(Image)
在联网情况下执行:
$ sudo docker build -t ics-image .
注意最后有个 . 哦
###验证Docker镜像Build成功
使用如下命令查看当前所有镜像:
$ sudo docker images
出现刚才的ics-image就说明ok:
现在就可以删除刚才的mydocker文件夹了(也可以不删除,但是有强迫症的话…):
$ cd .. #返回上一级目录
$ rm -r mydocker #迭代删除mydocker文件夹
##创建Docker容器(Container)
使用如下命令创建Docker容器:
$ docker create --name=ics-vm -p 20022:22 ics-image
参数解释:
–name=ics-vm 容器名为ics-vm
ics-image 指定镜像为我们刚才build得到的ics-image
20022:22 默认的SSH端口和Docker主机的20022端口绑定
###验证Docker 容器创建成功
使用如下命令查看当前所有容器:
$ sudo docker rm ics-vm
若出现刚才的ics-vm则说明ok:
##GNU/Linux初体验
首先启动我们刚才创建的容器:
$ sudo start ics-vm
使用ssh登录容器:
$ ssh -p 20022 [email protected]
注意把username换成你刚才Dockerfile里面设置的username
然后按照提示输入yes——>密码(你再Dockerfile里面设置的)然后回车就ok
退出并关闭容器:
$ exit
这个命令可以断开当前ssh连接
然后:
$ sudo docker stop ics-vm
就可以关闭对应容器
##安装工具包
依次输入以下命令:
$ sudo apt-get update
$ sudo apt-get install build-essential gdb git libreadline-dev libsdl2-dev qemu-system-x86 vim
##本机(host)和容器(container)之间的文件交互
###host复制文件到container
$ sudo scp -P 20022 HOST_SRC_PATH [email protected]:DEST_PATH
示例:
$ sudo scp -P 20022 hello.c [email protected]:/home/ics
这条语句将会把当前目录下的hello.c文件复制到container中的home目录下
###container复制文件到host
$sudo scp -P 20022 [email protected]:SRC_PATH HOST_PATH
示例:
$ sudo scp -P 20022 [email protected]:/home/ics/a.txt .
这条语句将会把container中home目录下的a.txt文件复制到host的当前目录下。
##获取PAs的源码
首先从github上clone代码到本地(建议在host/container的home目录下执行):
$ git clone -b 2017 https://github.com/NJU-ProjectN/ics-pa.git ics2017
克隆完毕后会出现:
使用以下命令设置你的git账号(使用docker的好处之一可能就是不会因为这里的git配置影响本机的git配置~):
$ git config --global user.name "161220000-Zhang San" # your student ID and name
$ git config --global user.email "[email protected]" # your email
$ git config --global core.editor vim # your favorite editor
$ git config --global color.ui true
ps:按照文档上的意思是git的用户名必须设置为学号+姓名…
然后进入ics2017目录,在该目录下执行:
$ git branch -m master
$ bash init.sh
执行init.sh脚本后将会从自动从github上拉下来对应的文件(看了一下脚本里的内容其实就是clone?)
完成后会出现:
##git的基础使用
###git分支(branch)的概念解释[3]
分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。
如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。
但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。
###查看当前所有分支
$ git branch
执行完之后会打印出来当前git仓库的所有分支:
* master
如果有多个分支的话会打印所有的分支名(因为当前只有一个master分支所以只打印出来一个master),前面的*代表当前所在分支。
###创建分支
使用以下命令创建分支pa0:
$ git checkout -b pa0
参数-b的意思是创建pa0分支的同时从当前分支(当前应该是master)切换到pa0分支。
执行完该命令后执行git branch可以看到如下信息:
master
* pa0
可以看到当前本地仓库有两个分支master和pa0并且当前位于pa0分支。
ps:你可以简单地理解为将原本的所有文件复制到pa0,然后对pa0进行操作,操作完成确定没有问题后再将pa0合并到master即正经的主分支,这样可以保证主分支的安全性,当然这只是我为了大家便于理解做的一种简单的解释,具体的机制其实很神奇很巧妙,感兴趣的可以自己去google,我会在文末给出一份git的教程。
所以我们现在做的所有操作将会是针对pa0的,尝试打开nemu/Makefile.git并修改如下信息:
STU_ID=161220000 # your student ID
将文件中的初始学号改成你自己的,然后保存并关闭文件。
现在,使用如下命令:
$ git status
命令解释:staus的本意就是状态的意思,所以这句话的意思是查看当前分支的状态
(有什么变化)
执行完之后会看到如下类似信息:
On branch pa0
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: nemu/Makefile.git
no changes added to commit (use "git add" and/or "git commit -a")
从上面打印的信息我们可以获取当前分支的状态。
想知道具体的变化(哪个文件的哪里发生了变化、发生变化之前和之后的状态),可以使用(这个操作在merge branch解决冲突时会经常用到,现在先做简单了解):
$ git diff
执行之后会打印类似如下信息:
可以看到git很贴心地为我们打印出了发生变化的位置及变化的内容。
注意,这个时候我们只是修改了pa0分支的文件内容,还没有commit(可以理解为修改了文件内容但是还没有保存),如果我们想保存应该执行如下命令:
$ git add .
$ git commit -m"info"
两个说明:
-
注意add后面有个.
-
-m之后最好加上说明(格式:“说明信息”),文档里面没有这个参数,不知道文档里面为什么没有加上,给自己每次的commit加上说明,我建议大家规范一点养成这个好的习惯,这样在团队开发的时候利人利己(其实讲道理git要求commit后面必须有提交说明的,如果没有是不会提交成功的,当然这只是我的印象也许有错~~)。
接下来一个问题是当前我们对分支做了很多次操作后,我们想查看自己之前的工作,这是可以使用:$ git log
这个命令会打印出你的所有提交(commit)记录我就不截图了大家自己执行了自己爽吧。
这个时候如果想回到我的master分支可以执行:
$ git checkout master
这个时候如果你打开刚才编辑的MakeFile文件你就会发现自己之前的修改又恢复称了原样,其实并不是你的修改恢复了,而是你修改的时候位于pa0分支,不会改变你master分支下的文件内容,而你现在切换到了master分支,所以就…你懂我意思吧~
如果你想把你刚才在pa0里面的修改迁移到master分支,就应该…你猜
end…
哦不忘了一件事,说好的git教程呢:点我
##参考资料
[1] : https://www.zhihu.com/question/28300645/answer/50922662
[2]:https://yeasy.gitbooks.io/docker_practice/content/install/ubuntu.html