Docker

Overview

Docker 使用 Google 公司推出的 Go 語言 進行開發(fā)實現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術,對進程進行封裝隔離,屬于 操作系統(tǒng)層面的虛擬化技術。由于隔離的進程獨立于宿主和其它的隔離的進程,因此也稱其為容器。最初實現(xiàn)是基于 LXC,從 0.7 版本以后開始去除 LXC,轉(zhuǎn)而使用自行開發(fā)的 libcontainer,從 1.11 開始,則進一步演進為使用 runCcontainerd

Docker 在容器的基礎上,進行了進一步的封裝,從文件系統(tǒng)、網(wǎng)絡互聯(lián)到進程隔離等等,極大的簡化了容器的創(chuàng)建和維護。使得 Docker 技術比虛擬機技術更為輕便、快捷。

下面的圖片比較了 Docker 和傳統(tǒng)虛擬化方式的不同之處。傳統(tǒng)虛擬機技術是虛擬出一套硬件后,在其上運行一個完整操作系統(tǒng),在該系統(tǒng)上再運行所需應用進程;而容器內(nèi)的應用進程直接運行于宿主的內(nèi)核,容器內(nèi)沒有自己的內(nèi)核,而且也沒有進行硬件虛擬。因此容器要比傳統(tǒng)虛擬機更為輕便。


Docker與傳統(tǒng)虛擬化區(qū)別

Docker objects

When you use Docker, you are creating and using images, containers, networks, volumes, plugins, and other objects. This section is a brief overview of some of those objects.

IMAGES
An image是一個只讀的template,其中有創(chuàng)建Docker容器的說明。通常,image是基于另一種image,還有一些額外的定制。例如,您可以構(gòu)建基于ubuntu image 的image,但安裝Apache web服務器和應用程序,以及使應用程序運行所需的配置細節(jié)。

我們都知道,操作系統(tǒng)分為內(nèi)核和用戶空間。對于 Linux 而言,內(nèi)核啟動后,會掛載 root 文件系統(tǒng)為其提供用戶空間支持。而 Docker 鏡像(Image),就相當于是一個 root 文件系統(tǒng)。比如官方鏡像 ubuntu:16.04 就包含了完整的一套 Ubuntu 16.04 最小系統(tǒng)的 root 文件系統(tǒng)。

Docker 鏡像是一個特殊的文件系統(tǒng),除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。鏡像不包含任何動態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會被改變。

  • 分層存儲

因為鏡像包含操作系統(tǒng)完整的 root 文件系統(tǒng),其體積往往是龐大的,因此在 Docker 設計時,就充分利用 Union FS 的技術,將其設計為分層存儲的架構(gòu)。所以嚴格來說,鏡像并非是像一個 ISO 那樣的打包文件,鏡像只是一個虛擬的概念,其實際體現(xiàn)并非由一個文件組成,而是由一組文件系統(tǒng)組成,或者說,由多層文件系統(tǒng)聯(lián)合組成。

鏡像構(gòu)建時,會一層層構(gòu)建,前一層是后一層的基礎。每一層構(gòu)建完就不會再發(fā)生改變,后一層上的任何改變只發(fā)生在自己這一層。比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記為該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像。因此,在構(gòu)建鏡像的時候,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構(gòu)建結(jié)束前清理掉。

分層存儲的特征還使得鏡像的復用、定制變的更為容易。甚至可以用之前構(gòu)建好的鏡像作為基礎層,然后進一步添加新的層,以定制自己所需的內(nèi)容,構(gòu)建新的鏡像。

CONTAINERS
A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.

默認情況下,container與其他container及其host machine是相對較好的隔離。您可以控制容器的network、storage or other underlying subsystems是如何從其他containers or from the host machine 中分離出來的。

container是由它的image定義的,以及當您創(chuàng)建或啟動它時提供給它的任何配置選項。當一個container被刪除時,對其狀態(tài)的任何更改都不會被存儲在持久性存儲中
鏡像(Image)和容器(Container)的關系,就像是面向?qū)ο蟪绦蛟O計中的 實例 一樣,鏡像是靜態(tài)的定義,容器是鏡像運行時的實體。容器可以被創(chuàng)建、啟動、停止、刪除、暫停等。

容器的實質(zhì)是進程,但與直接在宿主執(zhí)行的進程不同,容器進程運行于屬于自己的獨立的 命名空間。因此容器可以擁有自己的 root 文件系統(tǒng)、自己的網(wǎng)絡配置、自己的進程空間,甚至自己的用戶 ID 空間。容器內(nèi)的進程是運行在一個隔離的環(huán)境里,使用起來,就好像是在一個獨立于宿主的系統(tǒng)下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。也因為這種隔離的特性,很多人初學 Docker 時常常會混淆容器和虛擬機。

前面講過鏡像使用的是分層存儲,容器也是如此。每一個容器運行時,是以鏡像為基礎層,在其上創(chuàng)建一個當前容器的存儲層,我們可以稱這個為容器運行時讀寫而準備的存儲層為容器存儲層。

容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存于容器存儲層的信息都會隨容器刪除而丟失。

按照 Docker 最佳實踐的要求,容器不應該向其存儲層內(nèi)寫入任何數(shù)據(jù),容器存儲層要保持無狀態(tài)化。所有的文件寫入操作,都應該使用 數(shù)據(jù)卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網(wǎng)絡存儲)發(fā)生讀寫,其性能和穩(wěn)定性更高。

數(shù)據(jù)卷的生存周期獨立于容器,容器消亡,數(shù)據(jù)卷不會消亡。因此,使用數(shù)據(jù)卷后,容器刪除或者重新運行之后,數(shù)據(jù)卻不會丟失。


  • BUILD your own docker images and push it to dockerHub

  1. mkdir docker dir, and create Dockerfile file
docker build --rm -t \ 
       iamge_name . --file \ 
       ~/path-toyour-project/docker/Dockerfile

tips!
Running docker build docker/development/Dockerfile will use docker/development/Dockerfile as its build-context; any file referenced from the Dockerfile will need to be inside that path. Whereas docker build . -f docker/development/Dockerfile uses . (first argument) as build context, and loads the Dockerfile from docker/development/Dockerfile as if it was located at the root of the build-context (.)

  1. 或者直接運行官方的images生成一個容器:
 docker run -it --name \ 
        postgres-db  4860bdf1a517 \ 
        bin/bash

如首次提交:

docker tag
  1. 訂制images :當我們運行一個容器的時候(如果不使用卷的話),我們做的任何文件修改都會被記錄于容器存儲層里。而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保存下來成為鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,并構(gòu)成新的鏡像。以后我們運行這個新鏡像的時候,就會擁有原有容器最后的文件變化。
docker commit -m "updated" \ 
      -a "liambao”  contain_id \ 
       liambao/postgres-db:v2 (res name in dockerhub)

-m標志允許我們指定一個提交消息,就像你在版本控制系統(tǒng)上提交一樣
-a標志允許我們?yōu)楦轮付ㄗ髡?/p>

  1. push to remote respority
    docker push liambao/postgres-db
  • issue:Permission Denied on curl and save for docker compose

sudo chown -R $(whoami) /usr/local/bin

Please DO NOT do this either (it will change the owner of every single file recursively in /usr/local/bin to the user you are currently running as). It's WAY overkill. I can't emphasize this enough.

Doing something like this is very likely to blow up in your face eventually. In /usr/local/bin on my Mac some files are owned by nathanleclaire and some are owned by root. The programs that put them there and rely on them probably expect it to stay this way. The suggested command above will totally decimate these carefully layed out file ownerships.

Instead, if needed, consider this type of operation instead. Save the file to a directory you own and then cp / mv it.

$ curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose \
      -`uname -s`-`uname -m` \
      >~/docker-compose
$ chmod +x ~/docker-compose
$ sudo mv ~/docker-compose /usr/local/bin/docker-compose

Much safer with much less far-reaching consequences.

  • ******

  • ******

  • ******

  • ******


CMD options:

docker run -it --rm \
    ubuntu:16.04 \
    bash
  • -it 這是兩個參數(shù),一個是 -i:交互式操作,一個是 -t 終端。我們這里打算進入 bash 執(zhí)行一些命令并查看返回結(jié)果,因此我們需要交互式終端。
    --rm:這個參數(shù)是說容器退出后隨之將其刪除。默認情況下,為了排障需求,退出的容器并不會立即刪除,除非手動 docker rm。我們這里只是隨便執(zhí)行個命令,看看結(jié)果,不需要排障和保留結(jié)果,因此使用 --rm 可以避免浪費空間。
    ubuntu:16.04:這是指用 ubuntu:16.04 鏡像為基礎來啟動容器。
    bash:放在鏡像名后的是命令,這里我們希望有個交互式 Shell,因此用的是 bash。
docker run -d -P \
    training/webapp \
    python [app.py](http://app.py)
  • -d標志在后臺運行容器(稱為守護程序)。
    -P標志將容器中任何所需的網(wǎng)絡端口映射到你的主機。這使你可以查看Web應用程序。
    training/webapp映像是一個預構(gòu)建的映像,其中包含一個簡單的Python Flask Web應用程序。
    剩余的參數(shù)組成在容器內(nèi)運行的命令。python app.py命令啟動Web應用程序。
docker run -d -p \ 
    80:5000 training/webapp \
    python [app.py](http://app.py)
  • 這將映射你的容器內(nèi)的端口5000到本地主機上的端口80
docker port CONTAIN_NAME 5000
  • 查找外部什么端口映射到容器內(nèi)的5000端口
docker logs -f CONTAIN_NAME
  • 監(jiān)視容器的標準輸出 tail -F
docker inspect CONTAIN_NAME
  • 你可以使用docker inspect命令審查Docker容器的底層。它返回一個JSON文檔,其中包含指定容器的有用配置和狀態(tài)信息。
docker history
  • 查看你主機上的鏡像層的大小
docker ps -s
  • 容器大小
docker image prune
  • 刪除懸掛鏡像
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Docker — 云時代的程序分發(fā)方式 要說最近一年云計算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,850評論 15 147
  • docker基本概念 1. Image Definition 鏡像 Image 就是一堆只讀層 read-only...
    慢清塵閱讀 9,005評論 1 21
  • 一、Docker 簡介 Docker 兩個主要部件:Docker: 開源的容器虛擬化平臺Docker Hub: 用...
    R_X閱讀 4,521評論 0 27
  • 轉(zhuǎn)載自 http://blog.opskumu.com/docker.html 一、Docker 簡介 Docke...
    極客圈閱讀 10,756評論 0 120
  • 2017年12月22日,今年的冬季似乎比往年來的更晚,12月份都要過完了,可天氣還是比往年溫暖,一場雪也沒有下。 ...
    木之閱讀 317評論 0 0

友情鏈接更多精彩內(nèi)容