欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

docker实践总结——基于容器制作镜像

程序员文章站 2022-06-03 14:20:44
...

一、说明

学习docker有一段时间了,今天来做一个定制化的容器:centos+python+一些第三方python包,容器要复用的话需要形成镜像(一次定制n次使用)。在定制过程中也遇到了不少问题,现将其记录下来方便后续回看。好记心不如烂笔头!

需要用到的docker命令:
docker pull
docker run
docker exec
docker commit
docker save
docker load
docker export
docker import

docker命令使用详见:docker常用命令


二、定制容器

centos + python + 一些第三方python包

(一)启动基于centos镜像的容器

1. 从hub搜索镜像

执行docker search centos 发现列表没有tag(版本号),而且很多都是非官方的镜像。 OFFICIAL 列的值为 [OK] 的才是官方镜像。
docker实践总结——基于容器制作镜像

要找具体版本只能去 dockerhub 上找 : https://hub.docker.com/u/library

输入 centos 进行搜索:
docker实践总结——基于容器制作镜像

从官方centos容器链接进去

点击“Tags”标签页可以看到容器的所有版本列表:
docker实践总结——基于容器制作镜像
注意:“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

docker run 命令使用详见:docker常用命令


(二)在centos容器中安装python

docker实践总结——基于容器制作镜像
进入centos7容器:

#通过容器名进入容器,上面在 docker run 的时候指定了容器名为centos7
docker exec -it centos7 bash

docker实践总结——基于容器制作镜像

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软链接

想要简化命令,直接执行python而不是python3,可以在/usr/bin目录建立指向python3的软连接:
python —> python3。
什么是软链接可以查看这篇文章Linux软链接硬链接详解

先看看 /usr/bin 目录下有没有python :
ls -lt /usr/bin | grep python
docker实践总结——基于容器制作镜像
我们发现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包

  1. 修改pip仓库地址为国内镜像,这样可以增加下载速度
    修改 ~/.pip/pip.conf 文件, 没有该文件则创建一个,如使用阿里云的镜像

    [global]
    timeout = 6000
    index-url = http://mirrors.aliyun.com/pypi/simple/
    trusted-host = mirrors.aliyun.com
    
  2. 安装软件包
    比如我想用到如下三个python包:

    pip install wordcloud
    pip install matplotlib
    pip install turtule
    

三、制作镜像

1. 找到容器名(或容器id): centos7

docker container ls
docker实践总结——基于容器制作镜像

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实践总结——基于容器制作镜像
然后执行 “docker images” 发现本地多了一个镜像: (注意 IMAGE ID 为镜像sha256的前12位) docker实践总结——基于容器制作镜像
到这一步镜像就制作完成了。

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
docker实践总结——基于容器制作镜像