introduction
docker是几年前出来的一个容器技术,我也是在2017年才接触到这个东西,一开始用来部署tomcat和mysql服务,后来做项目和做算法也没有研究这个东西。现在由于要在本地搭建深度学习服务器,所以又把docker温故知新一下。
本文提到以下内容:
- 是什么
- 优点
- 大致的原理
- centos安装
理论内容主要(大篇幅)参考以下两篇文章,已经注明出处了,所以为了排版方便后面就不加引用符号了。而且加入了自己的一点内容。
不过实际操作还是一把辛酸泪T…T,各种踩坑
docker就是集装箱原理:这是大佬的知乎回答,可以去点个赞啊。
大白话Docker入门
是什么?集装箱
如果现在有一批水果和化学用品要运送。我们没有集装箱,为了安全起见,只能用一艘船运水果,一艘船运化学用品。动力能源就会被拿来维持多个船体本身航行的需求。
但是如果有集装箱,就可以把水果和化学用品分别装箱,规整的摆放起来。集装箱和集装箱之间不会互相影响,就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那就可以用一艘大船把它们都运走。
虚拟机是船,docker就是集装箱。
- 不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。
- 你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。
- 在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。
优点
- docker image的体积非常的小。一个完整功能的ubuntu才100多mb。docker image如此小的体积,让我们可以方便的在网络上传输和分享,对于公司来说就提供了对大量image的管理和分发的可能。
- docker的系统启动的耗时为0。docker run hello-world的命令是瞬间完成的,感觉不到加载image,启动系统的耗时,命令完成就直接输出了结果。程序执行完后container也跟着关闭,也并没有保存镜像的时间,但下次再运行还是会保留你处理过的状态。
在后面tensorflow使用,这个感觉是尤为突出。在windows上,拿pycharm运行,从按下ctrl+shift+f10到真正开始运行的时间,可能和docker run tensorflow的时间是差不多的。 - docker系统占用资源极少。如果我们开启一个vm的系统,不论是linux的或者windows,就算什么程序都不运行都会占用一部分内存。但是docker container启动后如果不运行程序,你是看不到系统资源被占用的。
如何做到的
- 先思考一下,一台服务器给我们开发的项目提供了什么?
cpu、内存、硬盘、网络、操作系统、工具软件、运行环境 等。拥有了这些资源,就可以运行一个程序。 - VM技术可以在一台server上部署多台虚拟机,提高了物力资源的重用性和设备管理的方便性。
那么VM是怎么做到的呢?Hypervisor。VM在物理机器的操作系统上建立了一个中间软件层Hypervisor,Hypervisor利用物理机器的资源,虚拟出多个虚拟的硬件环境,这些硬件环境可以共享宿主机的资源。这些新的虚拟硬件环境,安装操作系统和相应的软件后便形成了一台台虚拟机。 - 那么Docker有什么不同呢?Docker很聪明的利用linux的一些技术走了一条捷径。Docker选择了和虚拟化完全不同的思路,并不去虚拟化任何硬件,而是对硬件资源在不同的docker container之间做了“隔离”。隔离使每个container拥有了不同的环境(硬盘空间、网络、系统的工具包),并且又可以共享需要的硬件资源(cpu、内存、系统内核),表面上达到了虚拟机的功能。
Docker使用的Linux核心的组建如下:(截取自Docker的元件– Linux核心部分) - AUFS(chroot) – 用来建立不同的操作系统和隔离运行时的硬盘空间
- Namespace – 用来隔离Container的执行空间
- Cgroup – 分配不同的硬件资源
- SELinux – 用来保护linux的网络安全
- Netlink – 用来让不同的Container之间的进程保持通信
- Netfilter – 建立Container埠為基礎的網路防火牆封包過濾
- AppArmor – 保護Container的網路及執行安全
- Linux Bridge – 讓不同Container或不同主機上的Container能溝通
- ……
这里面的每一项技术都值得我们去深入研究。但是人的精力是有限的,很多情况下只能关心到目前最需要用的那些东西。所以原理性的问题就不赘述了。
centos下安装docker-ce
这一部分参考了网上的诸多资料(包括官方教程、网友博客,由于数量确实很多,实际操作的问题也很杂乱,所以无法摆出全部的参考文献),主要还是参考官方教程吧。
https://docs.docker-cn.com/
https://docs.docker.com/
http://www.docker.org.cn/book/
大大小小遇到了一些坑。这里就把我成功的安装的流程摆出来,供大家参考。
我这里主要是为了拿docker搭建python3的TensorFlow深度学习平台。虽然后期使用不一样,但是前期安装都是差不多的。
为什么是centos?因为装nvidia驱动的时候踩了更多的坑。可能是一些系统版本、网络、本人操作太蠢 等各方面问题,在用ubuntu系统装的时候,nvidia+cuda+cudnn的一套系统总是装不上,所以对ubuntu失去信心。T T
下面关于安装的命令,直接复制运行就可以了。
- 删除老版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-ce \
docker-engine
- 查看内核版本(需要大于3.10)
uname -r
- 设置仓库
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum-config-manager --enable docker-ce-edge
sudo yum-config-manager --enable docker-ce-test
- 正式安装部分。这里要注意了。
如果你使用docker不涉及到nvidia or gpu or deep learning,就直接执行以下命令安装最新版本。
sudo yum -y install docker-ce
由于docker是在nvidia驱动之上运行,即docker-nvidia是依赖了nvdia驱动本身,所以对其版本有一定的要求。
假如你之前安装的nvidia和之后安装的docker需要的版本不同,在运行TensorFlow-gpu的时候就会报错。
指定版本安装:
# 查看版本
yum list docker-ce --showduplicates | sort –r
# 安装指定版本 sudo yum -y install docker-ce-17.12.0.ce
sudo yum -y install docker-ce-18.09.5-3.el7
-
如果安装成功
启动docker服务:sudo service docker start
测试是否能用:sudo docker run hello-world
能输出下图就成功安装了。如果是没成功pull镜像,就参考其他中的镜像源配置。
卸载
卸载 Docker 软件包:sudo yum remove docker-ce
主机上的镜像、容器、存储卷、或定制配置文件不会自动删除。如需删除所有镜像、容器和存储卷,请运行下列命令:sudo rm -rf /var/lib/docker
必须手动删除任何已编辑的配置文件。
其他
- 镜像源配置
- 初始状态下,docker的镜像包都是从外国的服务器拉,所以速度慢的令人发指。和大多数linux上的加速下载玩法一样,docker也可以配置镜像源。直接一步操作。
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s mirror_address
-
执行了之后,你会发现,上面的命令是不会正确运行的。即使运行了,也没有成功配置镜像源。
上面的mirror_address要改成你自己的镜像源地址。那么问题来了,你哪里有镜像源?两个地方有:daocloud and 阿里云
daocloud中,注册,登录,点开个人面板,右上角有个小火箭,点开,新打开的页面往下拉,下面就有你的地址了。
阿里云中,注册,登录,点开个人面板,左上角搜索,“容器镜像服务”(随时间可能这个内容会变,但是搜 容器 镜像等字眼应该可以搜出来。)点出来之后,右边主面板就有你的地址了。
正常的镜像源配置到这里就结束了。但是。。。
如果linux的curl用不了or无法联网,上面的命令是没法运行的。采取以下办法。
先在windows上,下载刚刚的sh文件
然后用scp传去linux上,给这个文件加运行权限,然后使用如下命令运行。
sudo ./set_mirror.sh –s mirror_address
其实也可以手动改,vi /etc/docker/daemon.json
改成下面这个,以上以下所有mirror_address都是私人的地址,都要替换成自己的。
{"registry-mirrors": ["mirror_address"]}
还有另一个docker网络的配置文件是这个vi /etc/sysconfig/docker
,一般不需要动。
- 配置完了之后要重启
systemctl daemon-reload
systemctl restart docker
再重新试一下拉取镜像,能成功拉取就代表配置成功。不然就把别的镜像地址也试一下,或者把daocloud和阿里云都试试,选快的那个。
这里总是会有一些其他的坑的,如果遇到一些本地镜像搭建、docker代理配置的问题。推荐用搜索引擎查下面的这几个命令,会有相关的内容出来。
systemctl show --property=Environment docker
mkdir /etc/systemd/system/docker.service.d
vi /etc/systemd/system/docker.service.d/http-proxy.conf
- 调整用户权限,使得不用每次都加sudo运行docker命令
创建docker用户组sudo groupadd docker
添加用户至docker组sudo usermod -aG docker $USER
更新用户组newgrp docker
重启docker,注销用户,重登用户。看能否直接运行docker run hello-world
- 设置开机启动
sudo systemctl enable docker