Docker從入門到實踐筆記(一)

1. 修改已有鏡像

先使用下載的鏡像啓動容器。 html

$ sudo docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#

在容器中添加 json 和 gem 兩個應用。 python

root@0b2616b0e5a8:/# gem install json

當結束後,咱們使用 exit 來退出,如今咱們的容器已經被咱們改變了,使用docker commit命令來提交更新後的副本。 web

$ sudo docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c

其中,-m來指定提交的說明信息,跟咱們使用的版本控制工具同樣;-a能夠指定更新的用戶信息;以後是用來建立鏡像的容器的 ID;最後指定目標鏡像的倉庫名和 tag 信息。建立成功後會返回這個鏡像的 ID 信息。 docker

使用docker images來查看新建立的鏡像。 apache

$ sudo docker images
REPOSITORY          TAG     IMAGE ID       CREATED       VIRTUAL SIZE
training/sinatra    latest  5bc342fa0b91   10 hours ago  446.7 MB
ouruser/sinatra     v2      3c59e02ddd1a   10 hours ago  446.7 MB
ouruser/sinatra     latest  5db5f8471261   10 hours ago  446.7 MB

以後,可使用新的鏡像來啓動容器 json

$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#

2. 利用 Dockerfile 來建立鏡像

使用docker commit來擴展一個鏡像比較簡單,可是不方便在一個團隊中分享。咱們可使用docker build來建立一個新的鏡像。爲此,首先須要建立一個 Dockerfile,包含一些如何建立鏡像的指令。 ubuntu

新建一個目錄和一個 Dockerfile ruby

$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile

Dockerfile 中每一條指令都建立鏡像的一層,例如: bash

# This is a comment
FROM ubuntu:14.04
MAINTAINER Docker Newbee <newbee@docker.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra

Dockerfile 基本的語法是 app

  • 使用#來註釋
  • FROM指令告訴 Docker 使用哪一個鏡像做爲基礎
  • 接着是維護者的信息
  • RUN開頭的指令會在建立中運行,好比安裝一個軟件包,在這裏使用 apt-get 來安裝了一些軟件

編寫完成 Dockerfile 後可使用docker build來生成鏡像。

$ sudo docker build -t="ouruser/sinatra:v2" .
其中-t標記來添加 tag,指定新的鏡像的用戶信息。 「.」 是 Dockerfile 所在的路徑(當前目錄),也能夠替換爲一個具體的 Dockerfile 的路徑。

*注意一個鏡像不能超過 127 層

此外,還能夠利用ADD命令複製本地文件到鏡像;用EXPOSE命令來向外部開放端口;用CMD命令來描述容器啓動後運行的程序等。例如

# put my local web site in myApp folder to /var/www
ADD myApp /var/www
# expose httpd port
EXPOSE 80
# the command to run
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

如今能夠利用新建立的鏡像來啓動一個容器。

$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@8196968dac35:/#

還能夠用docker tag命令來修改鏡像的標籤。

$ sudo docker tag 5db5f8471261 ouruser/sinatra:devel
$ sudo docker images ouruser/sinatra
REPOSITORY          TAG     IMAGE ID      CREATED        VIRTUAL SIZE
ouruser/sinatra     latest  5db5f8471261  11 hours ago   446.7 MB
ouruser/sinatra     devel   5db5f8471261  11 hours ago   446.7 MB
ouruser/sinatra     v2      5db5f8471261  11 hours ago   446.7 MB

*注:更多用法,請參考 Dockerfile 章節。

3. 存出鏡像

若是要導出鏡像到本地文件,可使用docker save命令。

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04               c4ff7513909d        5 weeks ago         225.4 MB
...
$sudo docker save -o ubuntu_14.04.tar ubuntu:14.04

4. 載入鏡像

可使用docker load從導出的本地文件中再導入到本地鏡像庫,例如

$ sudo docker load --input ubuntu_14.04.tar

$ sudo docker load < ubuntu_14.04.tar

這將導入鏡像以及其相關的元數據信息(包括標籤等)。

5. 移除本地鏡像

若是要移除本地的鏡像,可使用docker rmi命令。注意docker rm命令是移除容器。

$ sudo docker rmi training/sinatra

*注意:在刪除鏡像以前要先用docker rm刪掉依賴於這個鏡像的全部容器。

6. 新建並啓動

所須要的命令主要爲docker run。

$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#

其中,-t選項讓Docker分配一個僞終端(pseudo-tty)並綁定到容器的標準輸入上,-i則讓容器的標準輸入保持打開。

當利用docker run來建立容器時,Docker 在後臺運行的標準操做包括:

  • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
  • 利用鏡像建立並啓動一個容器
  • 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
  • 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
  • 從地址池配置一個 ip 地址給容器
  • 執行用戶指定的應用程序
  • 執行完畢後容器被終止

7. 啓動已終止容器

能夠利用docker start命令,直接將一個已經終止的容器啓動運行。

容器的核心爲所執行的應用程序,所須要的資源都是應用程序運行所必需的。除此以外,並無其它的資源。能夠在僞終端中利用ps或top來查看進程信息。

root@ba267838cc1b:/# ps
  PID TTY          TIME CMD
    1 ?        00:00:00 bash
   11 ?        00:00:00 ps

可見,容器中僅運行了指定的 bash 應用。這種特色使得 Docker 對資源的利用率極高,是貨真價實的輕量級虛擬化。

8. 守護態運行

更多的時候,須要讓 Docker 容器在後臺以守護態(Daemonized)形式運行。此時,能夠經過添加-d參數來實現。

例以下面的命令會在後臺運行容器。

$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

容器啓動後會返回一個惟一的 id,也能夠經過docker ps命令來查看容器信息。

$ sudo docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES
1e5535038e28  ubuntu:14.04  /bin/sh -c 'while tr  2 minutes ago  Up 1 minute        insane_babbage

要獲取容器的輸出信息,能夠經過docker logs命令。

$ sudo docker logs insane_babbage
hello world
hello world
hello world
. . .

9. 終止容器

可使用docker stop來終止一個運行中的容器。

此外,當Docker容器中指定的應用終結時,容器也自動終止。 例如對於上一章節中只啓動了一個終端的容器,用戶經過exit命令或Ctrl+d來退出終端時,所建立的容器馬上終止。

終止狀態的容器能夠用docker ps -a命令看到。例如

sudo docker ps -a
CONTAINER ID        IMAGE                    COMMAND                CREATED             STATUS                          PORTS               NAMES
ba267838cc1b        ubuntu:14.04             "/bin/bash"            30 minutes ago      Exited (0) About a minute ago                       trusting_newton
98e5efa7d997        training/webapp:latest   "python app.py"        About an hour ago   Exited (0) 34 minutes ago                           backstabbing_pike

處於終止狀態的容器,能夠經過docker start命令來從新啓動。

此外,docker restart命令會將一個運行態的容器終止,而後再從新啓動它。

10. attach 命令進入容器

docker attach是Docker自帶的命令。下面示例如何使用該命令。

$ sudo docker run -idt ubuntu
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
243c32535da7        ubuntu:latest       "/bin/bash"         18 seconds ago      Up 17 seconds                           nostalgic_hypatia
$sudo docker attach nostalgic_hypatia
root@243c32535da7:/#

可是使用attach命令有時候並不方便。當多個窗口同時 attach 到同一個容器的時候,全部窗口都會同步顯示。當某個窗口因命令阻塞時,其餘窗口也沒法執行操做了。

11. 導出和導入容器

導出容器

若是要導出本地某個容器,可使用docker export命令。

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
7691a814370e        ubuntu:14.04        "/bin/bash"         36 hours ago        Exited (0) 21 hours ago                       test
$ sudo docker export 7691a814370e > ubuntu.tar

這樣將導出容器快照到本地文件。

導入容器快照

可使用docker import從容器快照文件中再導入爲鏡像,例如

$ cat ubuntu.tar | sudo docker import - test/buntu:v1.0
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
test/ubuntu         v1.0                9d37a6082e97        About a minute ago   171.3 MB

此外,也能夠經過指定 URL 或者某個目錄來導入,例如

$sudo docker import http://example.com/exampleimage.tgz example/imagerepo

*注:用戶既可使用docker load來導入鏡像存儲文件到本地鏡像庫,也可使用docker import來導入一個容器快照到本地鏡像庫。這二者的區別在於容器快照文件將丟棄全部的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時能夠從新指定標籤等元數據信息。

12. 刪除容器

可使用docker rm來刪除一個處於終止狀態的容器。 例如

$sudo docker rm  trusting_newton
trusting_newton

若是要刪除一個運行中的容器,能夠添加-f參數。Docker 會發送SIGKILL信號給容器。

相關文章
相關標籤/搜索