一、说明
学习docker有一段时间了,今天来做一个定制化的容器:centos+python+一些第三方python包,容器要复用的话需要形成镜像(一次定制n次使用)。在定制过程中也遇到了不少问题,现将其记录下来方便后续回看。好记心不如烂笔头!
需要用到的docker命令:
docker pull
docker run
docker exec
docker commit
docker save
docker load
docker export
docker import
二、定制容器
centos + python + 一些第三方python包
(一)启动基于centos镜像的容器
1. 从hub搜索镜像
执行docker search centos
发现列表没有tag(版本号),而且很多都是非官方的镜像。 OFFICIAL 列的值为 [OK] 的才是官方镜像。
要找具体版本只能去 dockerhub 上找 : https://hub.docker.com/u/library
输入 centos 进行搜索:
从官方centos容器链接进去
点击“Tags”标签页可以看到容器的所有版本列表:注意
:“latest”并不是真正意义上的最新版本,其实“latest”就像“1.0”、“2.0”等一样也只是一个普通tag而已,估计官方在下一次发布新版本的时候又会将最新镜像标记为“latest”,所以你永远不知道“latest”到底是哪个版本,docker安装镜像在不指定版本号时默认使用的是“latest”镜像(理解为当时的最新版,后续有版本更新时docker并不会自动将该镜像更新到最新版)。
2. 拉取镜像
我们找到centos7,进行安装,点击傍边的按钮,复制pull命令,开始执行:
#拉取centos7镜像
docker pull centos:centos7
#查询镜像,找到 IMAGE_ID ,比如:b5b4d78bc90c
docker images
3. 启动容器
通过镜像ID启动容器
#先建立目录,用于映射docker容器的工作目录。
mkdir /opt/docker/container_data
#通过镜像id启动容器,并指定工作目录,以及工作目录和宿主机器目录的映射关系
docker run -v /opt/docker/container_data:/data -w /data --name centos7 -itd b5b4d78bc90c /bin/bash
#当然你也可以通过镜像名+tag来启动
docker run -v /opt/docker/container_data:/data -w /data --name centos7 -itd centos:centos7 /bin/bash
#查看容器启动情况
docker ps -a
(二)在centos容器中安装python
进入centos7容器:
#通过容器名进入容器,上面在 docker run 的时候指定了容器名为centos7
docker exec -it centos7 bash
1.安装python3.7
通过编译源码的方式安装python3.7
#安装编译需要的依赖包
yum install bzip2-devel sqlite-devel zlib-devel ncurses-devel readline-devel tk-devel openssl-devel gcc make
yum install libffi-devel -y
#下载python3.7源码
wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
#在当前目录解压源码
tar -zxvf Python-3.7.0.tgz
#进入解压目录
cd Python-3.7.0
#编译配置:将需要编译的源码进行配置,检查当前的环境是否满足要安装软件的依赖关系
./configure
#编译源码
make
#安装
make install
#安装完之后,查看python3是否安装成功,如果安装成功则会显示版本号。
python3 --version
#安装成功之后可以删除源码,这样可以减少镜像的体积
cd ..
rm Python-3.7.0.tgz
rm -rf Python-3.7.0/
2.建立python软链接
先看看 /usr/bin 目录下有没有python :
ls -lt /usr/bin | grep python
我们发现centos7自带python2.7 ,而且python的软链接指向python2.7,
于是我们删除该软链接,重新建一个软链接指向python3:
#找到python3所在路径: /usr/local/bin/python3
where is python3
#删除python2的软连接
rm /usr/bin/python
#添加python3的软连接
ln -s /usr/local/bin/python3 /usr/bin/python
/usr/bin/pip 软链接也按照上面的方法,链接到pip3 ,否则你执行pip也是跑的pip2。
注意: 由于yum命令依赖python2.7,因此需要修改几处地方:
把如下两个文件中的第一行 #! /usr/bin/python
改为 #! /usr/bin/python2.7
,然后保存即可。
vi /usr/libexec/urlgrabber-ext-down
vi /usr/bin/yum
3. 安装自己需要的第三方python包
- 修改pip仓库地址为国内镜像,这样可以增加下载速度
修改 ~/.pip/pip.conf 文件, 没有该文件则创建一个,如使用阿里云的镜像
[global]
timeout = 6000
index-url = http://mirrors.aliyun.com/pypi/simple/
trusted-host = mirrors.aliyun.com
- 安装软件包
比如我想用到如下三个python包:
pip install wordcloud
pip install matplotlib
pip install turtule
三、制作镜像
1. 找到容器名(或容器id): centos7
docker container ls
2. 提交镜像到本地:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
#将容器提交为一个镜像
docker commit -m "基于centos7的Pytho3.7镜像" centos7 centos7_python37:1.0
#或者也可以不写提交备注:
docker commit c7 centos7_python37:1.0
然后执行 “docker images” 发现本地多了一个镜像: (注意 IMAGE ID 为镜像sha256的前12位)
到这一步镜像就制作完成了。
3. 镜像的导出/导入
docker save 导出
#保存镜像: docker save -o <保存路径> <镜像名称:标签>
docker save -o ./centos7_python37_v1.0.tar centos7_python37:1.0
docker load 导入,可以将镜像文件 centos7_python37_v1.0.tar 拷贝到另一台机器,进行导入:
#加载镜像:docker load --input <镜像路径>
docker load --input ./centos7_python3.7_v1.0.tar
4.容器的导入导出
当然你也可以不commit,不生成镜像,直接export导出容器,然后在其他机器通过import导入来使用
#导出容器: docker export <容器名> > <容器tar保存路径>
docker export centos7 > ./centos7_python37_v1.0.tar
#导入容器,导出的是一个容器,但是导入后成为一个镜像: docker import <容器tar文件路径> <镜像名:tag>
docker import ./centos7_python37_v1.0.tar centos7_python37:1.0
注意:导出的是一个容器的tar文件,但是将tar文件导入后将成为一个镜像,docker import 后可以通过 docker images 看到导入后生成的镜像
5. save/load 与 export/import 的区别
save/load:
通过docker save
将一个镜像
导出为tar文件,由于 docker save会保存该镜像的的所有历史记录
,所以文件体积比 docker export 导出的大。
再使用docker load
将tar文件导入成为一个本地镜像。export/import:
通过docker export
将一个容器
导出为tar文件,不需要commit形成镜像,而是直接导出容器,相比 docker save 命令,容器tar文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。
再使用docker import
将tar文件导入成为一个新的镜像
(而不是容器)。可以通过 docker history 查看镜像的操作历史
docker history centos7_python37:1.0