Docker學習之三:docker鏡像管理

Docker鏡像

一個host可以啓動多個容器,基於鏡像可在容器中啓動不同的應用。如果本地無此鏡像,docker可自動連接到docker registry上下載鏡像,存儲到本地文件系統(如overlay2)中。由於鏡像的格式是分層的,因此存儲鏡像的文件系統必須支持這種特殊的格式,也就是所謂的二層文件系統。

Docker是碼頭工人的意思,而鏡像可形象理解爲應用程序的集裝箱,碼頭工人docker負責裝卸集裝箱(image/application)。

Docker鏡像結構

Docker鏡像含有啓動容器所需的文件系統及其內容,因此,可用於創建並啓動docker容器。

  • 鏡像採用分層構建機制,最底層爲bootfs,其上爲rootfs

    • bootfs:用於系統引導的文件系統,包括bootloader和kernel。容器啓動完成後,會被卸載以節約內存資源。

    • rootfs:位於bootfs之上,表現爲docker容器的根文件系統

      • 傳統模式中,系統啓動之時,內核掛載rootfs時首先將其掛載爲只讀模式,完整性自檢完成後將其重新掛載爲讀寫模式

      • docker中,rootfs由內核掛載爲只讀模式,而後通過聯合掛載技術額外掛載一個可寫層。

在這裏插入圖片描述

  • Docker Image Layer

    位於下層的鏡像稱爲父鏡像,最底層的稱爲基礎鏡像(base image)

    最上層爲可寫層,其下的均爲“只讀”層

在這裏插入圖片描述

舉個例子:

在底層純淨的發行版如Debian之上,添加一個emacs層,這是一個獨立的應用層,如果需要額外的工具則需要在上面執行安裝操作比如安裝vim,安裝後可理解爲附加了一層vim的層級,該層級僅僅包含了vim。然後可再添加一個獨立的層級如apache。當啓動apache時,從下往上掛載疊加,並且三層都是隻讀的。如果需要讀寫操作,則在最上層容器的自有層次(container)進行,而其他層次是共享的。

一旦啓動完成,最底下的層(kernel)也將被移除。如果刪除容器,則容器自有的可寫層也被刪除。

鏡像的分層構建和聯合掛載,依賴專有的文件系統支撐。

Docker鏡像的文件系統

早期,使用的專有文件系統爲AUFS。而aufs的前身爲unionFS,其代碼很爛,因此當它申請到內核代碼樹時被拒絕。因此如果需要使用aufs,則自行打補丁。

而對於以穩定著稱的redhat/CentOS而言是不允許使用aufs的。Ubuntu是允許將aufs打包到內核中去,並且它也已經直接提供打好補丁的內核。故而早期如果要使用docker,只能使用ubuntu/debian系。

而overlayfs,也可以通過打補丁或者裝載內核模塊的方式,讓CentOS使用。

Docker還支持dm,不過它性能和穩定性很差,因此不再使用。早期CentOS7使用的是devicemapper,而新版的Docker中,CentOS7裝的是overlay2。

在實際使用過程中,爲了更大發揮docker的性能和支持更多的內核特性,建議使用ubuntu作爲容器的底層基礎設施。

Docker registry

Docker註冊庫,是鏡像的統一存儲位置。構建鏡像時,需要一個統一存儲的位置。當啓動鏡像時,docker daemon先嚐試從本地獲取鏡像,如果本地不存在鏡像則到registry中下載鏡像並保存到本地。如果沒有指定鏡像地址,則到docker hub中獲取。

一般而言,需要二次定製鏡像以符合自身業務需求。

Registry的組成部分:repository(一大堆倉庫) index(一個索引)

Repository

由某些特定的docker鏡像的所有迭代版本組成的鏡像倉庫。一個Registry這種可以存在多個Reopsitory

  • Repository分爲“頂層倉庫”和“用戶倉庫”
  • 用戶層庫名稱格式爲“用戶名/倉庫名”
  • 每個層庫可以包含多個Tag,每個標籤對應一個鏡像

Index

  • 維護用戶賬戶、鏡像的校驗以及公共命名空間的信息
  • 相當於爲Registry提供了一個完成用戶認證等功能的檢索接口

在這裏插入圖片描述

一般的流程是,開發人員從公共registry中獲取鏡像,並定製打包成images並push到私有registry中。一旦push成功,便觸發相應的hook,自動deploy到響應的環境中。

雲原生 Cloud Native

傳統意義上,程序員的程序是針對某個開發環境而寫的,針對系統庫和編程接口來生成自己的代碼,稱爲系統原生。

如果面向雲環境開發的程序,調用雲環境提供的接口,爲了在雲環境上而運行的程序,稱爲雲原生。

容器或者雲,是封裝好的。它們不方便修改裏面的文件,因此可以通過環境變量賦值的方式來向容器傳遞信息。

而且是當配置文件啓動時,從環境變量自動加載並注入到容器中生成的。因此,可以通過環境變量來配置容器的啓動。

Docker Hub

鏡像的製作一般基於基礎鏡像(base image)來做的,而base image一般是docker hub官方手動製作的。

默認情況下,docker daemon是從docker hub上pull鏡像的,並且能存放用戶的第三方鏡像。

docker hub 作爲鏡像倉庫而存在。它支持以下功能:

  • auto builds:使用命令基於docker file來製作鏡像,定義好file之後通過docker build生成或者放置到自動構建的位置來製作,或者基於容器docker commit來手動製作

    自動構建是通過聯動的方式來做的。Docker file可以放置到github的project的倉庫中,該倉庫和docker hub倉庫可建立關聯關係。Docker hub倉庫持續監控着github倉庫,如果github倉庫新加了docker file,則docker hub自動拖去並添加到倉庫中

  • Webhooks:自動構建功能的特性,觸發自動構建的動作

第三方鏡像倉庫:https://quay.io/

Docker鏡像製作

鏡像生成途徑:

  • Dockerfile
  • 基於容器製作
  • Docker Hub automated builds

基於容器製作鏡像

方法:啓動一個容器,在容器之上做好自己需要的配置,然後通過docker commit製作鏡像。

Usage:docker commit [options] CONTAINER [REPOSITORY[:TAG]]

Name,shorthand Default Description
–author, -a Author
–change, -c Apply Dockerfile instruction to the created image
–message, -m Commit message
–pause, -p true Pause container during commit

例子:將busybox 加上html目錄和index.html,將此結果做成鏡像。日後每次啓動有會存在此文件。

  • 啓動容器,提供文件後保存

    root@eto:~# docker run --name b1 -it busybox
    / # mkdir -p /data/html
    / # echo "busybox http server" >> /data/html/index.html
    
    
    root@eto:~# docker commit -p b1
    sha256:0f8cd6de017004598851b75b96fca52fe9bbbcf457701e28455e934edc475315
    

此時即可看到一個新鏡像,可以爲之打上標籤:

root@eto:~# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED              SIZE
<none>                  <none>              0f8cd6de0170        About a minute ago   1.22MB

root@eto:~# docker tag  0f8cd6de0170 jaywin/httpd:v0.1-1
root@eto:~# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
jaywin/httpd            v0.1-1              0f8cd6de0170        3 minutes ago       1.22MB

可以爲一個鏡像打上多個標籤:

root@eto:~# docker tag  0f8cd6de0170 jaywin/httpd:latest
root@eto:~# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
jaywin/httpd            latest              0f8cd6de0170        3 minutes ago       1.22MB
jaywin/httpd            v0.1-1              0f8cd6de0170        3 minutes ago       1.22MB

刪除一個鏡像,僅刪除了指定標籤的鏡像

root@eto:~# docker image rm jaywin/httpd:latest
Untagged: jaywin/httpd:latest

查看鏡像在啓動時,默認執行的命令,比如

root@eto:~# docker inspect busybox | grep Cmd -A3
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
--
            "Cmd": [
                "sh"
            ],

在創建鏡像時,改變原來鏡像默認運行的命令。可修改原有鏡像的基礎命令,修改其中的cmd指令

root@eto:~# docker commit -a "jaywin.com" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 jaywin/httpd:v0.2
sha256:f5a014fe42903e6c527249a7a9208d5cb137772a4bdbaed68eca9bc1a9cf0089

運行:

root@eto:~# docker run --name t2 jaywin/httpd:v0.2 

root@eto:~# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
7389ad8062ea        jaywin/httpd:v0.2   "/bin/httpd -f -h /d…"   About a minute ago   Up About a minute   


root@eto:~# curl 172.17.0.2
busybox http server

基於dockerfile製作鏡像

參考此處

鏡像推送

可以將本地製作好的鏡像,推送到registry中保存。常用的公有registry有docker hub官方和阿里雲提供的registry

docker hub

登錄到服務器上,不指定地址,則登錄到docker hub

root@eto:~# docker login -u jaywinz
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

注意:本地鏡像的名字,必須和docker hub中保持一致

root@eto:~# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
jaywin/httpd            v0.2                f5a014fe4290        17 minutes ago      1.22MB

root@eto:~# docker tag f5a014fe4290 jaywinz/httpd:v0.2-2
root@eto:~# docker push jaywinz/httpd:v0.2-2
The push refers to repository [docker.io/jaywinz/httpd]
bcefc70bb04a: Pushed 
5b0d2d635df8: Mounted from library/busybox 
v0.2-2: digest: sha256:b12533340a43375ca74fb21d80229d706981b73012095a331e55f1403b5b8d8a size: 734

由於網站在國外,速度較慢。

阿里雲

國內訪問比較快的鏡像地址,是阿里雲

可以登錄自己的阿里雲賬號,即可獲得專用的加速地址。將此地址寫到docker的配置文件中即可。

在這裏插入圖片描述

root@eto:~# cat /etc/docker/daemon.json 
{
  "exec-opts": ["native.cgrounpdriver=systemd"],
  "registry-mirrors": ["https://e2615hzs.mirror.aliyuncs.com"]

}

root@eto:~# systemctl daemon-realod
root@eto:~# systemctl restart docker 

可以根據操作指南,將鏡像託管到阿里雲

root@eto:~# docker login --username=15088132158 registry.cn-hangzhou.aliyuncs.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

root@eto:~# docker tag f5a014fe4290 registry.cn-hangzhou.aliyuncs.com/jaywinz/httpd:v0.2-2
root@eto:~# docker push registry.cn-hangzhou.aliyuncs.com/jaywinz/httpd:v0.2-2
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/jaywinz/httpd]
bcefc70bb04a: Pushed 
5b0d2d635df8: Pushed 
v0.2-2: digest: sha256:b12533340a43375ca74fb21d80229d706981b73012095a331e55f1403b5b8d8a size: 734

推送鏡像時,如果不是推送到docker hub,則必須加上服務器地址,名稱空間和標籤。
在這裏插入圖片描述

鏡像的導入和導出

除了可通過docker registry進行鏡像分發,也能通過導入導出的方式進行鏡像分發。使用兩個命令

  • docker save
  • docker load

因此可以在已有鏡像的基礎上,打包鏡像。然後在另外的主機上解壓直接使用。

打包兩個鏡像:

root@eto:~# docker save -o myimages.gz jaywin/httpd:v0.1-1 jaywinz/httpd:v0.2-1
root@eto:~# ls
myimages.gz  

傳送到另外的主機, 並導入:

root@eto2:~# docker load -i myimages.gz 
5b0d2d635df8: Loading layer [==================================================>]  1.437MB/1.437MB
bcefc70bb04a: Loading layer [==================================================>]   5.12kB/5.12kB
Loaded image: jaywin/httpd:v0.1-1
Loaded image: jaywinz/httpd:v0.2-1
root@eto2:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jaywinz/httpd       v0.2-1              f5a014fe4290        48 minutes ago      1.22MB
jaywin/httpd        v0.1-1              0f8cd6de0170        6 days ago          1.22MB
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章