文章出處

  • 容器概念。

docker是一種容器,應用沙箱機制實現虛擬化。能在一臺宿主機里面獨立多個虛擬環境,互不影響。在這個容器里面可以運行著我餓們的業務,輸入輸出。可以和宿主機交互。

  • 使用方法。
  1. 拉取鏡像
    docker pull registry

    默認是從官網的docker倉庫上面獲取,其中pull的命令是拉取,與之對應的是push命令,日后有能力自己創建鏡像并且上傳到docker倉庫的時候用到。registry是鏡像名,docker官方維護有很多基礎鏡像,可以直接下載來用。同時在公共倉庫也有很多共享的鏡像,自己可以視情況來下載使用。

  2. 啟動容器
    docker run -d -p 5000:5000 --name registry registry 
    

    第一步把鏡像下載到本地,現在可以在鏡像的基礎上啟動容器。run命令就是啟動的意思,后面可以加一下附屬參數。命令中-d就是daemon的意思,以守護進程方式運行。--name就是制定容器的名字,方便日后管理,不然每次都要使用容器的ID,12位16進制數。后面就是我們的鏡像名。容器啟動后就會返回一串數字,作為sha256,這一串是我們的長ID。長ID和短ID的區別如下:
    一般操作使用短ID,下面說到的文件目錄用長ID標記。

  3. 這是最基本的用法。
  • 核心原理。
  1. 這是用方式不是一個鏡像一臺提供不同服務的虛擬機嗎?
    1. 應用不同,這是兩個完全不一樣的產品。docker可以快速部署相同的和不同的環境,虛擬機只是節省資源,在同一臺宿主機安裝多個系統。
    2. 容器是共用鏡像,獨立的服務,屬于云計算中的paas服務,在統一的基礎環境延伸。虛擬機提供的是iaas,從底層開始。
    3. docker的實現方法是共享和隔離。虛擬機的只是虛擬硬件,虛擬機間沒有共享成分。
  2. 容器的實現原理很炫嗎?
    1. 它是通過利用內核自帶的namespace和cgroup功能隔離系統必須的六個模塊,以完成一個獨立的系統環境。用namespace隔離一個小空間,UTS、IPC、PID、Network、mount、User六個環境的新隔離,用cgroup作為系統資源的控制。
    2. UTC實現主機名和域名的隔離,使容器有獨立的主機名;IPC隔離信號量和消息隊列,使之有獨立的工作通訊;Network隔離網絡,使之有獨立的網絡設備;mount隔離文件系統,使之有獨立的存儲;PID隔離進程號,使之有獨立的進程編排。運行起來就像一個獨立的計算機環境。
  3. 除了文件,其他一些隔離都可以調用接口實現。每個容器里面有整個系統的文件,而且都是一秒鐘生成。就很難理解了。
docker exec -it smokeping bash

    上面說了,容器操作的時候,用名字就不用每次都找ID。exec命令是發送命令給容器執行,-i是使用交互模式保持輸入流的開放,-t是創建虛擬終端,smokeping是指定的容器名,bash是容器要執行的命令。我們看看容器的這些文件存放在宿主機的什么地方  。

  • 運行目錄。
  1. 容器是虛擬的,文件總不能也是虛擬的。查找了相關資料發現全部都是保存在docker容器的運行目錄。/var/lib/docker
  2. 看了一下,還真有。
  3. 為了能看到文件的變化,我們把docker的運行目錄都刪掉了。
    rm -rf /var/lib/docker
    重啟docker daemon,一切都是新的。
  4. Docker運行目錄的變化
    1. 拉取第一個鏡像開始,/var/lib/docker開始建立,包含了下下目錄。
      1. 刪除鏡像。

      2. 展開目錄。
        1. 全部目錄為空,打開image/aufs/repositories.json的記錄文件也為空。
    2. 重新拉取鏡像,再展開對比
      1. Aufs目錄下的三個文件夾的首層子目錄或者文件名都是各層ID。
        1. diff目錄保存著只讀層和可讀寫層的數據。每層只保存歷史當次讀寫。
        2. Layer目錄下的文件名和diff子目錄名一一對應,里面的內容是層依賴。
        3. Mnt目錄下的子目錄名和iff子目錄名一一對應,里面的內容暫時為空。
      2. Container的目錄為空。
      3. Image目錄下的distribution、imagedb、layerdb。
        1. Distribution下的diffid-by-digest和v2metadata-by-diffid都有sha256。
        2. Imagedb就只有一個sha256。這個正是image的ID。
        3. Layerdb的sha256下面也有同數量子目錄。每個目錄里面有相同名字的配置文件。
        4. repositories.json記錄的也是鏡像的sha256。
      4. Network文件夾為空,本來是用來存放容器內網絡相關文件。
      5. Volumes文件夾為空,是存放容器里面掛載的目錄,有真實可讀寫的文件。
      6. 小結:在上面“使用方法”演示的“docker pull”過程中,docker下載的鏡像文件全部分層保存在aufs目錄下的diff目錄,目錄名是sha256,和層ID無關。
    3. 啟動容器時的目錄變化。
      1. 生成容器的ID:
        1.   bc893c0031db98114a48ebb924cf5d0b9b2c77968839696e735528648a1a531b
      2. aufs的三個目錄。
        1. Diff沒有變化,但是多了一層把diff的內容都掛載上去。
        2. Layer增加了一個目錄,目錄文件是個別層實現可讀寫。
        3. Mnt中前面的目錄沒變,但是多了一層把diff的內容都掛載上去。
      3. Container的目錄不再為空,首先是以容器ID為目錄名新建了個目錄。然后在目錄下存放hostname、hosts等配置文件。
      4. Image目錄完全沒有改動。
      5. Network文件夾為空,本來是用來存放容器內網絡相關文件。
      6. Volumes下面出現了容器定義掛載的數據文件。此數據文件在mnt目錄沒有掛載。
      7. 小結:在上面“使用方法”演示的“docker run”過程中,aufs下的diff和mnt目錄,自動生成兩個目錄,名為sha256的一串數字ID,另一個是ID-init。diff下也是這兩個目錄,此ID是在diff是最新一層,在mnt中是當前容器所有文件;aufs/mnt/ID的文件由diff下的鏡像目錄通過aufs系統整合掛載而來,aufs系統是實現多目錄掛載在同一個目錄的工具。aufs/mnt/ID-init目錄為空;aufs/diff/ID下保存的是最新一層也就是當前可讀寫文件,aufs/diff/ID-init是最新一層也就是當前的只讀文件hostname、host等。一句話,數據都是儲存在diff,mnt是打醬油的。過程就是aufs整合鏡像存放在diff下的內容,一起掛載在aufs/mnt/ID下,連最新一層aufs/diff/ID(有幾個可讀寫文件)和aufs/diff/ID-init(只有只讀文件)都掛載上去。
    4. 運行目錄生成文件時的變化。
      1. 在root目錄touch ken.txt
        1. 其他目錄都沒有變化。
        2. aufs下的diff和mnt的那個容器新生成的ID目錄下隨地生成了ken.txt文件,應該是數據庫文件記錄了此文件在容器中的位置。
        3. Mnt目錄和diff的關系。
        4. Mnt目錄是被掛載。
      2. 在root目錄mv rc.local rc.loca
        1. 其他目錄沒有變化。
        2. aufs下的diff的那個容器新生成的ID目錄下etc中生成rc.loca文件。
        3. diff下鏡像層的文件沒改。
        4. 修改的文件存在于diff和mnt中。
      3. 新增的文件直接放在aufs/diff/e36b1bd8e430d4731211af3984aed0fd3fa6fa62c57f5c877a013856ba32abc4目錄這里,修改的文件連帶目錄生成到這里。
      4. 小結:容器啟動之后,新建目錄ID,和ID-init目錄;容器需要更改的文件從鏡像文件復制到diff下的ID目錄,經過容器的操作,ID目錄就擁有了最新的變更,ID-init是亙古不變的只讀文件;新增文件出現在新建層級diff的ID的儲存方式是直接隨地放在根目錄下,修改文件出現在新建層級diff的ID的儲存方式是連帶目錄首先復制到diff的新建層級,然后修改。最終掛載到aufs/mnt/ID展示在容器內的正確位置。
    5. 運行目錄在停止容器后的變化。
      1. Aufs目錄下的三個文件夾。
        1. Diff完全沒有變化,說明一旦容器停止的時候,容器必須的配置文件時復制的。
        2. Layer文件完全沒有變化。
        3. Mnt那個新建作為掛載diff各層文件的目錄為空,說明已經卸載。
      2. Images目錄不變。
      3. Container目錄不變,保留著diff時刻準備著的文件。
      4. 小結:容器停止后,在mnt上面的掛載馬上卸掉,但是目錄不變。而在diff上面的文件狀態保持不變,期待下次容器啟動的時候一次掛載到mnt下面。
    6. 運行目錄在刪除容器的變化。
      1. Aufs目錄下的三個子目錄。
        1. Diff在容器啟動時所生成的那個ID的文件夾消失。
        2. Layer在容器啟動時所生成的那個帶ID的文件夾消失。
        3. Mnt在容器啟動時所生成的那個ID的文件夾消失.
      2. Container目錄下容器啟動時所生成的那個ID的文件夾消失。
      3. Volumes目錄下的文件存活下來。
    7. 小結:當容器刪除,鏡像文件不變,其他全部刪除。如果有定義volume的,會有所保留。
  5. 總結:容器在宿主機上運行,無非是圍繞只讀層和可讀寫,利用復制和掛載,靈活操作;來得快的文件時通過掛載,如果在只讀層無法修改文件就可以先復制出來再說;整個過程就是,容器一啟動,diff就新建可讀寫的新ID目錄和ID-init目錄,ID-init目錄一開始就加載了只讀文件。然后和其他各層數據掛在mnt的分別掛在ID一一對應的mnt下,aufs系統把全部數據整合嫁接到mnt的新ID下。此時mnt中其他的目錄為空,新ID擁有容器的全部數據。當容器產生動態數據,就作用于那個可讀寫并且掛在mnt新ID下的diff新ID文件夾。

 


文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()