溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Docker鏡像的創(chuàng)建+構(gòu)建私有倉庫及其使用方法

發(fā)布時(shí)間:2020-07-23 11:23:38 來源:網(wǎng)絡(luò) 閱讀:6342 作者:warrent 欄目:云計(jì)算

博文大綱:

  • 一、docker鏡像的創(chuàng)建方法
    1、基于已有鏡像創(chuàng)建
    2、基于本地模板創(chuàng)建
    3、基于dockerfile創(chuàng)建
    4、搭建私有倉庫及其使用方法

一、docker鏡像的創(chuàng)建方法

docker鏡像是除了docker的核心技術(shù)之外,也是應(yīng)用發(fā)布的標(biāo)準(zhǔn)格式。一個(gè)完整的docker鏡像可以支撐一個(gè)docker容器的運(yùn)行,在docker的整個(gè)使用過程中,進(jìn)入一個(gè)已經(jīng)定型的容器之后,就可以在容器中進(jìn)行操作,最常見的操作就是在容器中安裝應(yīng)用服務(wù),如果要把已經(jīng)安裝的服務(wù)進(jìn)行遷移,就需要把環(huán)境及搭建的服務(wù)生成新的鏡像。

創(chuàng)建鏡像的方法有三種,分別是基于已有鏡像創(chuàng)建、基于本地模板創(chuàng)建及基于dockerfile創(chuàng)建。接下來會將這幾種方法依次寫下來。

1、基于已有鏡像創(chuàng)建

基于已有鏡像創(chuàng)建主要是使用docker commit命令,本質(zhì)上就是把一個(gè)容器里面運(yùn)行的程序及該程序的運(yùn)行環(huán)境打包起來生成新的鏡像。

命令格式如下:

docker  commit  [選項(xiàng)]  容器ID/名稱  倉庫名稱:[標(biāo)簽]

常用選項(xiàng)如下:

  • -m:說明信息;
  • -a:作者信息;
  • -p:生成過程中停止容器的運(yùn)行

基于已有鏡像創(chuàng)建新的鏡像舉例:

(1)啟動一個(gè)鏡像,在容器里做修改,然后將修改后的容器提交為新的鏡像,需要記住該容器的ID號,如下:

[root@localhost ~]# docker ps -a                #查看當(dāng)前運(yùn)行的容器
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                       NAMES
c037e7a5734b        docker.io/sameersbn/bind   "/sbin/entrypoint...."   19 seconds ago      Up 7 seconds        53/tcp, 10000/tcp, 53/udp   hopeful_clarke
[root@localhost ~]# docker exec -it c037e7a5734b /bin/bash            #進(jìn)入該容器
root@c037e7a5734b:/# echo 11111111111 > /etc/a.txt               #隨便寫入一個(gè)文件
root@c037e7a5734b:/# exit                      #退出該容器
exit
[root@localhost ~]# docker commit -m "newnamed" -a "ljz" c037e7a5734b docker:mynamed
#使用docker commit命令創(chuàng)建一個(gè)新的鏡像
sha256:e178f320e4821642bed66d0e61e8a85eedd841cb8a3a84db3d38e7d92d844eae
[root@localhost ~]# docker images | grep mynamed          #查看新創(chuàng)建的鏡像
docker                        mynamed             e178f320e482        11 seconds ago      323 MB
[root@localhost ~]# docker create -it docker:mynamed /bin/bash       #基于新創(chuàng)建的鏡像創(chuàng)建一個(gè)容器
dc37cf2d6ef754200aea067d7a15c83713f2488dac0913013373809633266f07
[root@localhost ~]# docker ps -a               #獲取剛剛創(chuàng)建的容器ID號,下面標(biāo)紅的就是
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                       NAMES
'dc37cf2d6ef7'        docker:mynamed             /sbin/entrypoint....   11 seconds ago      Created                                         pensive_williams
c037e7a5734b        docker.io/sameersbn/bind   /sbin/entrypoint....   6 minutes ago       Up 5 minutes        53/tcp, 10000/tcp, 53/udp   hopeful_clarke
[root@localhost ~]# docker start dc37cf2d6ef7            #啟動剛創(chuàng)建的容器
dc37cf2d6ef7
[root@localhost ~]# docker exec -it dc37cf2d6ef7 /bin/bash          #查看在之前容器里寫入的文件是否存在
root@dc37cf2d6ef7:/# cat /etc/a.txt 
11111111111
#可以看到新創(chuàng)建的容器中,有在之前容器中創(chuàng)建的文件,說明鏡像更改成功

2、基于本地模板創(chuàng)建

通過導(dǎo)入操作系統(tǒng)模板文件可以生成鏡像,模板可以從OPENVZ開源項(xiàng)目下載,或者 https://wiki.openvz.org/Download/template/precreated ,優(yōu)先使用OPENVZ開源項(xiàng)目那個(gè)鏈接;

基于本地模板創(chuàng)建舉例:

1、下載centos 7的迷你版系統(tǒng)模板,使用docker導(dǎo)入命令導(dǎo)入為本地鏡像:

[root@localhost ~]# wget https://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz             #下載centos7的模板壓縮包
                           .................. #省略部分內(nèi)容
[root@localhost ~]# ls | grep centos*                  #確認(rèn)已經(jīng)下載centos7的模板壓縮包
centos-7-x86_64-minimal.tar.gz
[root@localhost ~]# cat centos-7-x86_64-minimal.tar.gz | docker import - docker:new  
#使用docker導(dǎo)入命令導(dǎo)入為本地鏡像
sha256:c065d5c0571df48eba3b95b1302494b596cf9f67c24eacc82ff75a9e9c2b7622
[root@localhost ~]# docker images | grep new         #查看導(dǎo)入的鏡像
docker                        new                 c065d5c0571d        56 minutes ago      435 MB
#至此,可使用這個(gè)鏡像創(chuàng)建容器并部署需要的功能,進(jìn)行使用了。

3、基于dockerfile創(chuàng)建

dockerfile是由一組指令組成的文件,其中每條指令對應(yīng)Linux中的一條命令,docker程序?qū)⒆x取dockerfile中的指令生成指定鏡像。

dockerfile結(jié)構(gòu)大致分為四個(gè)部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令和容器啟動時(shí)執(zhí)行指令。dockerfile每行支持一條指令,每條指令可攜帶多個(gè)參數(shù),支持使用“#”號開頭的注釋。

dockerfile中的配置項(xiàng)介紹:

[root@localhost ~]# docker tag docker:new centos7:system            
#將上面下載的centos 7迷你鏡像更改下名字及標(biāo)簽,以便區(qū)分
[root@localhost ~]# docker images | grep system             
#確認(rèn)基礎(chǔ)鏡像已經(jīng)準(zhǔn)備好(就是一個(gè)centos 7的迷你系統(tǒng)進(jìn)行)
centos7                       system              c065d5c0571d        About an hour ago   435 MB
[root@localhost ~]# vim Dockerfile   #編輯一個(gè)Dockerfile文件,注意:文件名最好就是Dockerfile

FROM centos           #第一行必須指明基于的基礎(chǔ)鏡像(該鏡像必須存在)
MAINTAINER The centos project <ljz@centos.org>    #維護(hù)該鏡像的用戶信息
#以下是鏡像的操作指令
RUN yum -y update      
RUN yum -y install openssh-server
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
EXPOSE 22       #開啟22端口
CMD ["/usr/sbin/sshd","-D"]     #啟動容器時(shí)執(zhí)行指令

在編寫dockerfile時(shí),有嚴(yán)格的格式需要遵循:第一行必須使用FROM指令指明所基于的鏡像名稱;之后使用MAINTAINER指令說明維護(hù)該鏡像的用戶信息;然后是鏡像操作相關(guān)指令,如RUN指令,每運(yùn)行一條指令,都會給基礎(chǔ)鏡像添加新的一層;最后使用CMD指令來指定啟動容器時(shí)要運(yùn)行的命令操作。

dockerfile有十幾條命令可用于構(gòu)建鏡像,其中常見的指令如下:

Docker鏡像的創(chuàng)建+構(gòu)建私有倉庫及其使用方法

dockerfile使用舉例——使用dockerfile創(chuàng)建apache鏡像并在容器中運(yùn)行

(1)創(chuàng)建鏡像并加載到容器中運(yùn)行:

[root@localhost ~]# mkdir apache               #建立工作目錄
[root@localhost ~]# cd apache/                #切換至新建的目錄
[root@localhost apache]# vim Dockerfile             #編寫dockerfile文件

FROM centos                #基于的基礎(chǔ)鏡像centos
MAINTAINER the centos project <ljz@163.com>     #維護(hù)該鏡像的用戶信息
RUN yum -y update            #使用yum進(jìn)行更新
RUN yum -y install httpd        #鏡像操作指令安裝apache軟件包
EXPOSE 80                         #開啟80端口
ADD index.html /var/www/html/index.html            #將本地的首頁文件index.html復(fù)制到鏡像中
ADD run.sh /run.sh      #將本地的運(yùn)行腳本run.sh復(fù)制到鏡像中
RUN chmod 775 /run.sh       #賦予腳本執(zhí)行權(quán)限
RUN systemctl disable httpd             #設(shè)置apache服務(wù)不自行啟動
CMD ["/run.sh"]             #啟動容器時(shí)執(zhí)行腳本
#輸入上述信息后,保存退出
[root@localhost apache]# docker images | grep centos     
#確保本地有centos的基礎(chǔ)鏡像,因?yàn)樵赿ockerfile文件中指定了該鏡像
centos7                       system              c065d5c0571d        About an hour ago   435 MB
[root@localhost apache]# vim run.sh               #編寫執(zhí)行腳本內(nèi)容

#!/bin/bash
rm -rf /run/httpd/*              #清理httpd的緩存
exec /usr/sbin/apachectl -D FOREGROUND           #啟動apache服務(wù)
[root@localhost apache]# echo "dockerfile  test" >index.html          #編寫一個(gè)首頁文件
[root@localhost apache]# ls               #確保當(dāng)前目錄下的文件有以下三個(gè)
Dockerfile  index.html  run.sh
#當(dāng)以上準(zhǔn)備完成后,就可以使用docker  build命令來創(chuàng)建鏡像,如下:
[root@localhost apache]# docker build -t httpd:centos .     
#注意上面命令的末尾有個(gè)“.”,表示當(dāng)前路徑,若不加則會報(bào)錯(cuò)。
#其中“-t”選項(xiàng)用來指定鏡像的標(biāo)簽信息
Sending build context to Docker daemon 4.096 kB
Step 1/10 : FROM centos
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
  .................. #省略部分內(nèi)容,此處需要靜等幾分鐘,此時(shí)系統(tǒng)在執(zhí)行dockerfile文件中的指令。
    #若在顯示信息中有報(bào)紅的信息,只要配置文件無誤,一般屬于正常(是有關(guān)yum的信息)。
Removing intermediate container 81a3d6c9d3db
Step 10/10 : CMD /run.sh
 ---> Running in 5cdc467fd874
 ---> 5d56b826432d
Removing intermediate container 5cdc467fd874
Successfully built 5d56b826432d
#當(dāng)出現(xiàn)以上提示,則表示新的鏡像已經(jīng)創(chuàng)建成功了。
#在整個(gè)創(chuàng)建過程中,可以看到每運(yùn)行一次dockerfile中的指令,都會以給初始鏡像加上新的一層。
[root@localhost apache]# docker run -d -p 81:80 httpd:centos  #將新生成的鏡像加載到容器中運(yùn)行。
#其中“-p”選項(xiàng)實(shí)現(xiàn)從本地端口81到容器中80端口的映射。
192cd783028dcb3013ebb40b65ba8450e695e424e700a13cb8a44bb84af3e71a
[root@localhost apache]# docker ps -a         #查詢?nèi)萜魇欠襁\(yùn)行
CONTAINER ID        IMAGE                      COMMAND                  CREATED              STATUS              PORTS                       NAMES
192cd783028d        httpd:centos               "/run.sh"                About a minute ago   Up About a minute   0.0.0.0:81->80/tcp          gallant_khorana
                  #省略部分內(nèi)容

至此,可以看到新生成的鏡像已經(jīng)在容器中加載運(yùn)行了,本機(jī)(宿主機(jī),不是docker容器)的IP地址為192.168.1.1,此時(shí)client訪問192.168.1.1的81端口,就相當(dāng)于訪問了剛運(yùn)行的容器的80端口,如下:
Docker鏡像的創(chuàng)建+構(gòu)建私有倉庫及其使用方法

4、搭建私有倉庫及其使用方法

(2)將鏡像上傳到倉庫中:

隨著創(chuàng)建的鏡像增多,就需要有一個(gè)保存鏡像的地方,這就是倉庫,目前有兩種倉庫:公共倉庫和私有倉庫,公司的生產(chǎn)環(huán)境中大多數(shù)都是保存到私有倉庫的,最簡單的還是在公共倉庫上下載鏡像,若是上傳鏡像至公共倉庫,還需要注冊并登陸,關(guān)于公共倉庫的上傳,可以參考博文Docker的概念及安裝配置中的上傳鏡像部分。

那么怎么構(gòu)建私有倉庫呢?可以使用registry來搭建本地私有倉庫。如下:

[root@localhost ~]# docker search registry               #查詢關(guān)鍵字“registry”
INDEX       NAME                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/registry                            The Docker Registry 2.0 implementation for...   2679      [OK]       
                 ..................#省略部分內(nèi)容
[root@localhost ~]# docker pull docker.io/registry     #下載排名靠前的鏡像
                 ..................#省略部分內(nèi)容
Status: Downloaded newer image for docker.io/registry:latest    #下載成功
[root@localhost ~]# vim /etc/sysconfig/docker           
#修改docker配置文件指定私有倉庫URL,否則在自定義的私有倉庫中上傳鏡像時(shí)會報(bào)錯(cuò)

# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --insecure-registry=192.168.1.1:5000'
#更改上面一行內(nèi)容,其中的IP地址是作為私有倉庫服務(wù)器的IP地址,這里就是本機(jī)的IP地址。
                 ..................#省略部分內(nèi)容
#修改完畢后保存退出
[root@localhost ~]# systemctl restart docker      #重啟docker服務(wù)

使用下載好的registry鏡像啟動一個(gè)容器,默認(rèn)情況下倉庫存放于容器內(nèi)的/tmp/registry目錄下,使用-v選項(xiàng)可以將本地目錄掛載到容器內(nèi)的/tmp/registry目錄下使用,這樣就不怕容器被刪除后鏡像也會隨之丟失。在本地啟動一個(gè)私有倉庫服務(wù),監(jiān)聽端口號為5000。

注意:我本地有一個(gè)/data/registry目錄(掛載的是一個(gè)高可用的GFS文件系統(tǒng),也可以使用NFS,自行選擇即可,但是建議對于重要的數(shù)據(jù)存放目錄,一定要保證容量的動態(tài)擴(kuò)展以及磁盤損壞造成數(shù)據(jù)丟失的問題),將要掛載到私有倉庫容器中的/tmp/registry目錄中用于存放上傳到私有倉庫的鏡像文件。

[root@localhost ~]# df -hT /data/registry/             #查看我這個(gè)目錄所使用的文件系統(tǒng)
文件系統(tǒng)         類型            容量  已用  可用 已用% 掛載點(diǎn)
node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry
[root@localhost ~]# docker run -d -p 5000:5000 -v /data/registry/:/tmp/registry docker.io/registry
#啟動私有倉庫,并做端口映射到主機(jī)的5000端口,將本地的/data/registry目錄掛載到容器中的/tmp/registry目錄
#docker.io/registry是剛才下載的私有倉庫鏡像。
a6bf726c612b826e203d6a5bc9eaba26c36195913d3ea546c2111ce290a5524d
[root@localhost ~]# docker tag docker.io/registry 192.168.1.1:5000/registry     
#使用docker  tag命令將要上傳的鏡像docker.io/registry改一下標(biāo)記,其中的IP及端口為固定的,否則無法連接到私有倉庫
#因?yàn)樵谏厦孢\(yùn)行容器時(shí),做了端口映射,將私有倉庫的端口號映射到了宿主機(jī)的5000端
口,
#所以直接訪問宿主機(jī)的5000端口,就相當(dāng)于訪問了私有倉庫。
[root@localhost ~]# docker images | grep 5000            #找到要上傳的鏡像
192.168.1.1:5000/registry     latest              f32a97de94e1        6 months ago        25.8 MB
[root@localhost ~]# docker push 192.168.1.1:5000/registry            #上傳至剛剛運(yùn)行的私有倉庫
The push refers to a repository [192.168.1.1:5000/registry]
73d61bf022fd: Pushed 
5bbc5831d696: Pushed 
d5974ddb5a45: Pushed 
f641ef7a37ad: Pushed 
d9ff549177a9: Pushed 
latest: digest: sha256:b1165286043f2745f45ea637873d61939bff6d9a59f76539d6228abf79f87774 size: 1363
#下面再上傳一個(gè)鏡像,進(jìn)行測試。
[root@localhost ~]# docker images | grep mynamed            #就上傳它了
docker                        mynamed             e178f320e482        4 hours ago         323 MB
[root@localhost ~]# docker tag docker:mynamed 192.168.1.1:5000/named:test    
#老規(guī)矩,必須改倉庫名,注意:若標(biāo)簽不是默認(rèn)的latest,那么還需要在倉庫名后面接上標(biāo)簽名
[root@localhost ~]# docker images | grep 192.168.1.1:5000/named     #確定更改成功
192.168.1.1:5000/named        test                e178f320e482        4 hours ago         323 MB
[root@localhost ~]# docker push 192.168.1.1:5000/named:test       #上傳至私有倉庫
The push refers to a repository [192.168.1.1:5000/named]
c756b9ec7fb0: Pushed 
7d8d01394159: Pushed 
72b7cd87d69b: Pushed 
3be48ef75683: Pushed 
9b28c58ad64b: Pushed 
75e70aa52609: Pushed 
dda151859818: Pushed 
fbd2732ad777: Pushed 
ba9de9d8475e: Pushed 
test: digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f size: 2403

至此,測試就完畢了,但是,如何證明私有倉庫使用的是本地的/data/registry這個(gè)目錄呢?以及如何查看上傳的鏡像呢?(上傳至私有倉庫的鏡像是無法使用普通的ls命令查看的)。

[root@localhost ~]# df -hT /data/registry/           #先查看本地/data/registry/ 掛載的文件系統(tǒng)
文件系統(tǒng)         類型            容量  已用  可用 已用% 掛載點(diǎn)
node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry
[root@localhost ~]# docker exec -it a6bf726c612b /bin/sh 
#進(jìn)入私有倉庫的容器中,該容器沒有/bin/bash,所以使用的是/bin/sh。
/ # df -hT /tmp/registry/   #查看發(fā)現(xiàn),該目錄掛載的和宿主機(jī)掛載的文件系統(tǒng)是同一個(gè),說明沒問題。
Filesystem           Type            Size      Used Available Use% Mounted on
node4:dis-stripe     fuse.glusterfs
                                    80.0G    129.4M     79.8G   0% /tmp/registry
                     ——————————我是分割線——————————  
#那么如何查看上傳至私有倉庫的鏡像呢?請看下面:
[root@localhost ~]# curl -XGET http://192.168.1.1:5000/v2/_catalog   
#查看已經(jīng)上傳的鏡像,可以看到剛剛上傳的那兩個(gè)鏡像
{"repositories":["named","registry"]}
#只知道鏡像名還不夠,若要下載,還需要鏡像對應(yīng)的標(biāo)簽,那么怎么查看某個(gè)鏡像的標(biāo)簽?zāi)兀?[root@localhost ~]# curl -XGET http://192.168.1.1:5000/v2/named/tags/list
#就這樣查看咯,上面URL路徑中的named就是鏡像名,查看的就是鏡像named對應(yīng)的標(biāo)簽
{"name":"named","tags":["test"]}
[root@localhost ~]# docker pull 192.168.1.1:5000/named:test      #將私有倉庫中的鏡像下載下來
#前面必須指定私有倉庫的訪問地址,就是上傳時(shí)的名字是什么,下載時(shí)就是什么,哪怕查詢的鏡像名中沒有IP地址。
Trying to pull repository 192.168.1.1:5000/named ... 
sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f: Pulling from 192.168.1.1:5000/named
Digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f
Status: Downloaded newer image for 192.168.1.1:5000/named:test

附加:
若需要在其他服務(wù)器上下載私有倉庫的鏡像,需要在那個(gè)其他服務(wù)器上執(zhí)行以下命令,以便指定私有倉庫服務(wù)器地址:

[root@node1 ~]# echo '{ "insecure-registries":["xxx.xxx.xxx.xxx:5000"] }' > /etc/docker/daemon.json
#其中xxx.xxx.xxx.xxx:5000代表訪問私有倉庫的IP地址及端口,根據(jù)自己的服務(wù)器情況來定
[root@node1 ~]#systemctl restart docker          #重啟docker服務(wù)

上面的方法是我百度到的,親測有效,也可是嘗試下這種方法(我沒試過):

[root@node1 ~]# vim /etc/sysconfig/docker     #修改docker配置文件指定私有倉庫URL

# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --insecure-registry=192.168.1.1:5000'    #修改此行
[root@node1 ~]#systemctl restart docker          #重啟docker服務(wù)

———————— 本文至此結(jié)束,感謝閱讀 ————————

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI