docker(三):docker鏡像管理


一、基本介紹

  1. docker鏡像是容器啟動的基礎,鏡像里面包含容器啟動所需要的文件系統及其內容。docker鏡像采用分層構建的機制,這種分層大致分為兩部分,一部分是最底層的引導文件系統bootfs,類型有aufs,btffs或者overlay2等;另一部分真正讓用戶來構建用戶空間並運行進程的容器稱為rootfs。

    • bootfs:用於引導文件系統,包括BootLoader和kernel,容器啟動完成后會被卸載以節約內存資源。(這里說的卸載,是從內存中移除而不是刪除)

    • rootfs:位於bootfs之上,表現為docker的根文件系統,比如/dev、/bin之類。

      • 傳統模式中,系統啟動時,內核掛載rootfs時會先將其掛在為”只讀“模式,自檢完成后將其重新掛載為讀寫模式。
      • docker中,rootfs由內核掛載為”只讀“模式,而后通過”聯合掛載“技術額外掛載一個”可寫“層。(我們在docker container中的操作就是可寫層)
  2. 分層構建最底層的是基礎鏡像,位於上層的鏡像稱為父鏡像(系統層),每添加一個鏡像都是一個獨立的層次。最上層為“可寫層”。其它均為“只讀”層。刪除容器的時候,可寫層會一並被刪除

3. 啟動容器時,docker daemon會試圖從本地獲取相關鏡像;本地不存在時,會從docker Registry(默認就是docker hub)中下載並保存到本地。
  1. docker registry用於保存docker鏡像,包括鏡像的層次結構和元數據,用戶可以自建registry,也可以使用官方的docker hub。registry里面的鏡像通常由開發人員制作,而后推送至registry上保存,以供用戶使用。另外,為了安全起見,docker daemon要求docker registry必須是https的,如果不是就需要配置docker daemon。registry分類如下:

    • Sponsor registry:第三方的Registry,供客戶和docker社區使用
    • Mirror registry:第三方的Registry,只讓客戶使用
    • Vendor registry:由發布docker鏡像的供應商提供的registry。如Redhat自己的registry
    • private registry:通過設有防火牆和額外安全層的私有實體提供的registry。
  2. repository是由某個特定docker鏡像的所有迭代版本所組成,一個registry可以存在多個repository。repository分為頂層倉庫和用戶倉庫。

    • 頂層倉庫是直接由倉庫名命名的,一般用docker search搜索的第一個就是頂層倉庫
    • 用戶倉庫名稱格式為:用戶名或者成為項目名/倉庫名。一般除了docker search搜索的第一個,其它的都是用戶倉庫。
  3. 鏡像的生成途徑

    • 通過編寫dockerfile
    • 基於容器制作:也就是把容器最上層的可寫層提交成一個新的鏡像。比如起了一個centos的容器,然后在上面搭建一個nginx,最后用docker container commit提交完就是一個nginx的鏡像了。
    • docker hub automated builds:這個其實也是基於dockerfile構建的。首先在docker hub上面設置與GitHub的集成,然后本地寫完dockerfile后推到GitHub上面,docker hub檢測到GitHub的變化就會觸發build,生成新的鏡像。

二、鏡像制作

 1. 基於dockerfile制作鏡像
 2. 基於容器制作鏡像(第一種)

  a) 就以busybox鏡像起一個容器,創建httpd啟動所需要的文件

[root@docker1 ~]# docker run --name busy01 -it busybox
/ # mkdir -p /data/html
/ # echo 'this is a test ' >/data/html/index.html
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    7 root      0:00 ps
/ # which httpd
/bin/httpd

  b) 此時不要退出本窗口,另外開一個終端窗口進行鏡像制作。

上面使用ps命令可以看到,PID為1的進程是sh,容器中PID為1的進程就相當於我們宿主機的systemd進程,1進程是bash,它運行完就會結束的,PID為1的進程結束也就意味着容器就exit了。所以上面運行busybox容器的窗口是不可以關閉也不可以放在后台運行的。這里就順便再提一下應用程序的運行:如果想讓一個應用類的容器長久的運行下去,要么起一個類似busybox的容器,然后前台運行一個應用(比如httpd:httpd -f -h /data/html),這個窗口永遠不能關閉;要么在把容器的CMD設置為前台運行應用的命令(也就是設置應用的PID為1)。

  c) 我們先看下busybox的CMD,可看到這個容器的CMD是sh。

[root@docker1 ~]# docker inspect busy01 | grep Cmd -A1
            "Cmd": [
                "sh"

  d) 基於busybox鏡像重新commit一個CMD為httpd的鏡像。

[root@docker1 ~]# docker commit -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p busy01 hamerle/httpd:v1
    # -c:以列表的形式修改dockerfile的指令。此例只修改CMD指令,使新容器CMD指令為httpd(也就是PID為1的進程是httpd),之前是sh。
    # -p:提交過程中暫停容器的運行,防止文件保存的不完整。
    # -p的后面跟的要操作容器的名字,最后是提交后生成新鏡像的名字和tag。
[root@docker1 ~]# docker images 
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
hamerle/httpd            v1                  099c89327481        2 minutes ago       1.2MB
busybox                  latest              64f5d945efcc        3 weeks ago         1.2MB

  e) 以這個新鏡像創建一個httpd的容器,然后訪問httpd服務

[root@docker1 ~]# docker run --name httpd01 -d hamerle/httpd:v1
[root@docker1 ~]# docker inspect httpd01 | grep Cmd -A4
            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h",
                "/data/html"
[root@docker1 ~]# docker inspect httpd01 | grep IPAddress
            "IPAddress": "172.17.0.3",
[root@docker1 ~]# curl 172.17.0.3
this is a test        # 訪問成功

 3. 基於容器制作鏡像(第二種)
  在公司使用openjdk做基礎環境啟動的java程序莫名其妙的有問題,所以就萌生想法自己手動制作一個jdk環境。

  a) 首先拉取centos鏡像並啟動容器

[root@docker1 ~]# docker pull centos:centos7.4.1708
[root@docker1 ~]# docker run --name jdk -itd centos:centos7.4.1708

  b) 上傳jdk包到宿主機並解壓,然后拷貝到容器內部

[root@docker1 src]# pwd
/usr/local/src
[root@docker1 src]# tar xf jdk-8u201-linux-x64.tar.gz
[root@docker1 src]# docker cp -a /usr/local/src/jdk1.8.0_201/ jdk:/usr/local

  c) 登入docker配置jdk

[root@docker1 src]# docker exec -it jdk /bin/bash
[root@cc8aaa0096bf /]# ln -s /usr/local/jdk1.8.0_201/bin/java /usr/bin/java
[root@cc8aaa0096bf /]# echo -e 'export JAVA_HOME=/usr/local/jdk\nexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar\nexport PATH=$JAVA_HOME/bin:$PATH' >>/etc/profile
[root@cc8aaa0096bf /]# source /etc/profile

  d) 然后以現在的docker容器commit一個jdk基礎鏡像出來。新的名字以倉庫名的格式

[root@docker1 src]# docker commit -m 'install jdk' -a 'hamerle' jdk hamerle/centos7.4:jdk
[root@docker1 src]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
hamerle/centos7.4   jdk                 23a3a5d00138        About a minute ago   593MB

三、鏡像分享

  1. 鏡像分享至docker hub

    • 注冊hub.docker.com的賬號
    • 點擊"Repositories"菜單,然后點擊"Create Repository +"來創建一個倉庫,創建完成后瀏覽器的窗口不要關閉
* 創建完倉庫,就可以把上面制作的httpd鏡像推上去了。當然,推之前需要先進行登錄驗證 ``` [root@docker1 ~]# docker login --help Usage: docker login [OPTIONS] [SERVER] # 從上面命令幫助可以看出,登錄是要跟server地址的,但是默認登錄就是docker hub,所以不用加server地址 [root@docker1 ~]# docker login -u hamerle Password: Login Succeeded # 驗證成功,開始進行push操作。此處我加了tag,如果不加tag,就是將此鏡像的所有版本都push上去。 [root@docker1 ~]# docker push hamerle/httpd:v1 ``` * push完成后,回到瀏覽器docker hub的窗口,刷新就可以看到tag的位置已經有push的鏡像了
2. 鏡像分享至阿里雲
* 首先注冊阿里雲的賬號
* 點擊"控制台"菜單,然后上面的搜索框搜索"容器鏡像服務 控制台",首次使用需要同意開通容器鏡像服務,然后點擊"創建鏡像倉庫",使用命名空間(也就是你的用戶名),創建過程還需要創建registry的密碼,創建完成后瀏覽器窗口不要關閉。
* 創建完成后,點擊"管理"就可以看到操作指南了。首頁也是登錄驗證,注意:阿里雲的registry的密碼和阿里雲登錄密碼不是一個。 ``` [root@docker1 ~]# docker logout [root@docker1 ~]# docker login --username=hamerle registry.cn-shanghai.aliyuncs.com Password: Login Succeeded # 驗證完成后,需要以阿里雲的訪問路徑及倉庫名稱重新打一個tag才能進行后續的push操作。 [root@docker1 ~]# docker tag hamerle/httpd:v1 registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2 [root@docker1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hamerle/httpd v1 099c89327481 2 hours ago 1.2MB registry.cn-shanghai.aliyuncs.com/hamerle/httpd v2 099c89327481 2 hours ago 1.2MB busybox latest 64f5d945efcc 3 weeks ago 1.2MB [root@docker1 ~]# docker push registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2 ``` * push完成之后,還是在"管理"的界面,點擊"鏡像版本",就可以看到push上去的鏡像信息。

四、鏡像導入導出

# 這就以上面制作的hamerle/httpd:v1和v2為例,打包在一起導出供docker2使用
[root@docker1 ~]# docker save -o httpd_images.gz hamerle/httpd:v1 registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2
    # -o:導出到某個文件。
[root@docker1 ~]# ll httpd_images.gz 
-rw------- 1 root root 1432576 Jun 10 13:42 httpd_images.gz
# 將images拷貝到docker2上面,然后導入使用
[root@docker1 ~]# scp httpd_images.gz 10.0.0.12:/root
[root@docker2 ~]# ll httpd_images.gz 
-rw------- 1 root root 1432576 Jun 10 13:52 httpd_images.gz
[root@docker2 ~]# docker load -i httpd_images.gz
    # 從某個文件導入
[root@docker2 ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
hamerle/httpd                                     v1                  099c89327481        4 days ago          1.2MB
registry.cn-shanghai.aliyuncs.com/hamerle/httpd   v2                  099c89327481        4 days ago          1.2MB


寫作不易,轉載請注明出處,謝謝~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM