docker實踐總結——基於容器製作鏡像

一、說明

學習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 search centos 執行結果

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

輸入 centos 進行搜索:
centos official

從官方centos容器鏈接進去

點擊“Tags”標籤頁可以看到容器的所有版本列表:
找到centos7
注意:“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

在這裏插入圖片描述
進入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軟鏈接

想要簡化命令,直接執行python而不是python3,可以在/usr/bin目錄建立指向python3的軟連接:
python —> python3。
什麼是軟鏈接可以查看這篇文章Linux軟鏈接硬鏈接詳解

先看看 /usr/bin 目錄下有沒有python :
ls -lt /usr/bin | grep python
/usr/bin/目錄
我們發現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
找到容器名

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位) centos7_python37
到這一步鏡像就製作完成了。

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
查看鏡像的歷史記錄





















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章