Docker入門到實踐——簡單操作
1.對比傳統虛擬機總結
特性 | 容器 | 虛擬機 |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為MB | 一般為GB |
性能 | 接近原生 | 弱於 |
系統支持量 | 單機支持上千個容器 | 一般幾十個 |
2.基本概念
Docker包括三個基本概念:
- 鏡像(Image)
- 容器(Container)
- 倉庫(Repository)
Docker鏡像
- Docker鏡像就是一個只讀的模板。
- 鏡像可以用來創建Docker容器。
Docker容器
Docker利用容器來運行應用。
容器是從鏡像創建運行實例。它可以被:
- 啟動
- 開始
- 停止
- 刪除
每個容器都是相互隔離的,保證安全的平臺。
Docker倉庫
倉庫是集中存放鏡像文件的場所。有時候會把倉庫和倉庫註冊服務器(Registry)混為一談,並不嚴格區分。實際上,倉庫註冊服務器上往往存放著多個倉庫,每個倉庫中又包含多個鏡像,每個鏡像有不同的標簽(tag)。
倉庫分為:
- 公開倉庫(Public);
- 私有倉庫(Private);
最大的公開倉庫是 Docker Hub,存放了數量龐大的鏡像供用戶下載。 國內的公開倉庫包括 Docker Pool 等,可以提供大陸用戶更穩定快速的訪問。
當用戶創建了自己的鏡像之後就可以使用 push 命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機器上使用這個鏡像時候,只需要從倉庫上 pull 下來就可以了。
3.CentOS系列安裝Docker
安裝說明URL:https://docs.docker.com/install/linux/docker-ce/centos/#set-up-the-repository
Uninstall old versions:
$ sudo yum remove docker docker-common docker-selinux docker-engine
Install Docker CE:
Install using the repository:
SET UP THE REPOSITORY:
1.Install required packages.
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
2.安裝配置docker repo源。
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
3.啟用邊緣並測試存儲庫。
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test
或者禁用:
$ sudo yum-config-manager --disable docker-ce-edge
CentOS7系統CentOS-Extras庫中已帶Docker,可以直接安裝:
$ sudo yum install docker-ce
安裝之後啟動 Docker 服務,並讓它隨系統啟動自動加載。
$ sudo systemctl start docker
4.鏡像
4.1 獲取鏡像
可以使用 docker pull 命令來從倉庫獲取所需要的鏡像。
4.2 列出本地鏡像
使用 docker images 顯示本地已有的鏡像。
$ sudo docker images
REPOSITORY | TAG | IMAGE ID | CREATED | VIRTUAL SIZE |
---|---|---|---|---|
ubuntu | 12.04 | 74fe38d11401 | 4 weeks ago | 209.6 MB |
ubuntu | precise | 74fe38d11401 | 4 weeks ago | 209.6 MB |
ubuntu | 14.04 | 99ec81b80c55 | 4 weeks ago | 266 MB |
ubuntu | latest | 99ec81b80c55 | 4 weeks ago | 266 MB |
ubuntu | trusty | 99ec81b80c55 | 4 weeks ago | 266 MB |
...
在列出信息中,可以看到幾個字段信息 :
來自於哪個倉庫,比如 ubuntu;
鏡像的標記,比如 14.04;
它的 ID 號(唯一);
創建時間 ;
鏡像大小;
其中鏡像的 ID 唯一標識了鏡像,註意到 ubuntu:14.04 和 ubuntu:trusty 具有相同的鏡像 ID,說明它們實際上是同一鏡像。
例如下面的命令指定使用鏡像 ubuntu:14.04 來啟動一個容器。
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
如果不指定具體的標記,則默認使用 latest 標記信息。
4.3.1 創建鏡像
創建鏡像有很多方法,用戶可以從 Docker Hub 獲取已有鏡像並更新,也可以利用本地文件系統創建一個。
4.3.2 修改已有鏡像
先使用下載的鏡像啟動容器。
$ sudo docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#
4.4 存出和載入鏡像
4.4.1 存出鏡像
如果要導出鏡像到本地文件,可以使用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.4.2 載入鏡像
可以使用docker load從導出的本地文件中再導入到本地鏡像庫,例如:
$ sudo docker load --input ubuntu_14.04.tar
或
$ sudo docker load < ubuntu_14.04.tar
4.5 移除
4.5.1 移除本地鏡像
docker rmi:移除本地鏡像;
docker rm:移除容器;
註意:在刪除鏡像之前要先用 docker rm 刪掉依賴於這個鏡像的所有容器。
4.5.2 清理所有未打過標簽的本地鏡像
$ docker images
可以列出本地所有的鏡像,其中很可能會包含有很多中間狀態的未打過標簽的鏡像,大量占據著磁盤空間。
使用下面的命令可以清理所有未打過標簽的本地鏡像:
$ sudo docker rmi $(docker images -q -f "dangling=true")
其中 -q 和 -f 是縮寫, 完整的命令其實可以寫著下面這樣,是不是更容易理解一點:
$ sudo docker rmi $(docker images --quiet --filter "dangling=true")
4.6 鏡像的實現原理
Docker 鏡像是怎麽實現增量的修改和維護的? 每個鏡像都由很多層次構成,Docker 使用 Union FS 將這些不同的層結合到一個鏡像中去。
通常 Union FS 有兩個用途, 一方面可以實現不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更常用的就是將一個只讀的分支和一個可寫的分支聯合在一起,Live CD 正是基於此方法可以允許在鏡像不變的基礎上允許用戶在其上進行一些寫操作。 Docker 在 AUFS 上構建的容器也是利用了類似的原理。
5 Docker容器
簡單的說,容器是獨立運行的一個或一組應用,以及它們的運行態環境。對應的,虛擬機可以理解為模擬運行的一整套操作系統(提供了運行態環境和其他系統環境)和跑在上面的應用。
5.1.1 啟動容器
啟動容器有兩種方式:
一種是基於鏡像新建一個容器並啟動;
另外一個是將在終止狀態(stopped)的容器重新啟動;
5.1.2 新建並啟動
所需要的命令主要為 docker run
例如,下面的命令輸出一個 “Hello World”,之後終止容器。
$ sudo docker run ubuntu:14.04 /bin/echo ‘Hello world‘
Hello world
下面的命令則啟動一個 bash 終端,允許用戶進行交互:
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
或
$ sudo docker run -it ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
其中,
-t選項:讓Docker分配一個偽終端(pseudo-tty)並綁定到容器的標準輸入上;
-i選項:則讓容器的標準輸入保持打開;
在交互模式下,用戶可以通過所創建的終端來輸入命令,例如
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
當利用 docker run 來創建容器時,Docker 在後臺運行的標準操作包括:
檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載 ;
利用鏡像創建並啟動一個容器 ;
分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層;
從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去;
從地址池配置一個 ip 地址給容器 ;
執行用戶指定的應用程序 ;
執行完畢後容器被終止;
啟動已終止容器
可以利用 docker start 命令,直接將一個已經終止的容器啟動運行。
容器的核心為所執行的應用程序,所需要的資源都是應用程序運行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 ps 或 top 來查看進程信息。
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
5.2 後臺(background)運行
更多的時候,需要讓 Docker在後臺運行而不是直接把執行命令的結果輸出在當前宿主機下。此時,可以通過添加 -d 參數來實現。
下面舉兩個例子來說明一下。
如果不使用 -d 參數運行容器:
$ sudo docker run ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world
容器會把輸出的結果(STDOUT)打印到宿主機上面
如果使用了 -d 參數運行容器:
$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
此時容器會在後臺運行並不會把輸出的結果(STDOUT)打印到宿主機上面(輸出結果可以用docker logs 查看)。
註: 容器是否會長久運行,是和docker run指定的命令有關,和 -d 參數無關。
使用 -d 參數啟動後會返回一個唯一的 id,也可以通過 docker ps 命令來查看容器信息。
$ sudo docker ps
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS NAMES |
---|---|---|---|---|---|
77b2dc01fe0f | ubuntu:14.04 | /bin/sh -c ‘while tr | 2 minutes ago | Up 1 minute | agitated_wright |
要獲取容器的輸出信息,可以通過 docker logs 命令:
$ sudo docker logs [container ID or NAMES]
hello world
hello world
hello world
5.3 終止容器
$ docker stop
此外,當Docker容器中指定的應用終結時,容器也自動終止。 例如對於上一章節中只啟動了一個終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端時,所創建的容器立刻終止。
處於終止狀態的容器,可以通過 docker start 命令來重新啟動。
此外,docker restart 命令會將一個運行態的容器終止,然後再重新啟動它。
5.4 進入容器
在使用 -d 參數時,容器啟動後會進入後臺。 某些時候需要進入容器進行操作,有很多種方法,包括使用 docker attach 命令或 nsenter 工具等。
5.4.1 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 到同一個容器的時候,所有窗口都會同步顯示。當某個窗口因命令阻塞時,其他窗口也無法執行操作了。
Docker入門到實踐——簡單操作