Docker系列:02.Docker基礎使用
- 獲取鏡像:
docker pull ubuntu
- 查找鏡像:
docker search ubuntu
- 查看鏡像:
docker images
- 刪除鏡像:
docker rmi ubuntu
,也可以用id,取前幾位就行。 - 創建鏡像:
docker commit CONTAINER self:ubuntu
CONTAINER為容器id - 導出鏡像:
docker export xxxid > xxx.tar
- 導入鏡像:
docker import xxx.tar test/ubuntu
- 創建容器:
docker create ubuntu
- 啟動容器:
docker run ubuntu
- 查看容器:
docker ps -a
- 停止容器:
docker stop xxxid
- 進入容器:
docker attach xxxid
- 刪除容器:
docker rm xxxid
02.1.Docker鏡像使用
當運行容器時,使用的鏡像如果在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。
下面我們來學習:
- 1、管理和使用本地 Docker 主機鏡像
- 2、創建鏡像
02.1.1、獲取一個新的鏡像
當我們在本地主機上使用一個不存在的鏡像時 Docker 就會自動下載這個鏡像。如果我們想預先下載這個鏡像,我們可以使用 docker pull 命令來下載它。之前我們提到過 Docker 官方提供了一個公共的鏡像倉庫:Docker Hub,我們就可以從這上面獲取鏡像,獲取鏡像的命令:docker pull,格式為:
docker pull [選項][Docker Registry 地址[:端口]/]倉庫名[:標簽]
Docker 鏡像倉庫地址:地址的格式一般是 <域名/IP>[:端口號],默認地址是 Docker Hub。
倉庫名:這裏的倉庫名是兩段式名稱,即 <用戶名>/<軟件名>。對於 Docker Hub,如果不給出用戶名,則默認為 library,也就是官方鏡像。
$ docker pull ubuntu:16.10 13.10: Pulling from library/ubuntu 6599cadaf950: Pull complete 23eda618d451: Pull complete # 可見容器基本上都是分層的 f0be3084efe9: Pull complete 52de432f084b: Pull complete a3ed95caeb02: Pull complete Digest: sha256:15b79a6654811c8d992ebacdfbd5152fcf3d165e374e264076aa435214a947a3 # 保證容器和倉庫一致性 Status: Downloaded newer image for ubuntu:16.10
上面的命令中沒有給出 Docker 鏡像倉庫地址,因此將會從 Docker Hub 獲取鏡像。而鏡像名稱是 ubuntu:16.04,因此將會獲取官方鏡像 library/ubuntu 倉庫中標簽為 16.04 的鏡像。從下載過程中可以看到我們之前提及的分層存儲的概念,鏡像是由多層存儲所構成。下載也是一層層的去下載,並非單一文件。下載過程中給出了每一層的 ID 的前 12 位。並且下載結束後,給出該鏡像完整的 sha256 的摘要,以確保下載一致性。
下載完成後,我們可以直接使用這個鏡像來運行容器。
02.1.2、查找鏡像
我們可以從 Docker Hub 網站來搜索鏡像,Docker Hub 網址為: https://hub.docker.com/
我們也可以使用 docker search 命令來搜索鏡像。比如我們需要一個httpd的鏡像來作為我們的web服務。我們可以通過 docker search 命令搜索 httpd 來尋找適合我們的鏡像。
$ docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 1855 [OK]
hypriot/rpi-busybox-httpd Raspberry Pi compatible Docker Image with a … 41
centos/httpd 18 [OK]
NAME:鏡像倉庫源的名稱
DESCRIPTION:鏡像的描述
OFFICIAL:是否docker官方發布
02.1.3、列出鏡像列表
我們可以使用 docker images 來列出本地主機上的鏡像。
[zhanghe@MacBook-Pro ~ ]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 7aa3602ab41e 3 days ago 115MB
各個選項說明:
- REPOSITORY:表示鏡像的倉庫源
- TAG:鏡像的標簽
- IMAGE ID:鏡像ID
- CREATED:鏡像創建時間
- SIZE:鏡像大小
同一倉庫源可以有多個 TAG,代表這個倉庫源的不同個版本,如ubuntu倉庫源裏,有15.10、14.04等多個不同的版本,我們使用 REPOSITORY:TAG 來定義不同的鏡像。
所以,我們如果要使用版本為15.10的ubuntu系統鏡像來運行容器時,命令如下:
$ docker run -it ubuntu:16.10 /bin/bash
root@d3a54b505c0c:/#
如果要使用版本為14.04的ubuntu系統鏡像來運行容器時,命令如下:
$ docker run -it ubuntu:14.04 /bin/bash
root@39e968165990:/#
如果你不指定一個鏡像的版本標簽,例如你只使用 ubuntu,docker 將默認使用 ubuntu:latest 鏡像。
鏡像大小
如果仔細觀察,會註意到,這裏標識的所占用空間和在 Docker Hub 上看到的鏡像大小不同。比如,ubuntu:16.04 鏡像大小,在這裏是 127 MB,但是在 Docker Hub 顯示的卻是 43 MB。這是因為 Docker Hub 中顯示的體積是壓縮後的體積。在鏡像下載和上傳過程中鏡像是保持著壓縮狀態的,因此 Docker Hub 所顯示的大小是網絡傳輸中更關心的流量大小。而 docker image ls 顯示的是鏡像下載到本地後,展開的大小,準確說,是展開後的各層所占空間的總和,因為鏡像到本地後,查看空間的時候,更關心的是本地磁盤空間占用的大小。
另外一個需要註意的問題是,docker image ls 列表中的鏡像體積總和並非是所有鏡像實際硬盤消耗。由於 Docker 鏡像是多層存儲結構,並且可以繼承、復用,因此不同鏡像可能會因為使用相同的基礎鏡像,從而擁有共同的層。由於 Docker 使用 Union FS,相同的層只需要保存一份即可,因此實際鏡像硬盤占用空間很可能要比這個列表鏡像大小的總和要小的多。
你可以通過以下命令來便捷的查看鏡像、容器、數據卷所占用的空間。
02.1.3、創建鏡像
當我們從docker鏡像倉庫中下載的鏡像不能滿足我們的需求時,我們可以通過以下兩種方式對鏡像進行更改。
- 1.從已經創建的容器中更新鏡像,並且提交這個鏡像
- 2.使用 Dockerfile 指令來創建一個新的鏡像
02.1.3.1、更新鏡像
更新鏡像之前,我們需要使用鏡像來創建一個容器。
$ docker run -ti ubuntu:15.10 /bin/bash
root@e218edb10161:/#
在運行的容器內使用 apt-get update 命令進行更新。
在完成操作之後,輸入 exit命令來退出這個容器。
此時ID為e218edb10161的容器,是按我們的需求更改的容器。我們可以通過命令 docker commit來提交容器副本。
[zhanghe@MacBook-Pro ~ ]$ docker commit -m="update" -a="Zhanghe" e218edb10161 os/ubuntu:v2
sha256:52430d685485aaf4faa5f6d3d48dedc5960bb7f9ea4bf56e24240d52cc28adae
各個參數說明:
- -m:提交的描述信息
- -a:指定鏡像作者
- e218edb10161:容器ID
- os/ubuntu:v2:指定要創建的目標鏡像名
我們可以使用 docker images 命令來查看我們的新鏡像 os/ubuntu:v2:
[zhanghe@MacBook-Pro ~ ]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
os/ubuntu v2 52430d685485 5 seconds ago 155MB
ubuntu 16.04 7aa3602ab41e 3 days ago 115MB
使用我們的新鏡像 os/ubuntu:v2 來啟動一個容器
[zhanghe@MacBook-Pro ~ ]$ docker run -it os/ubuntu:v2 /bin/bash
root@cbd28ae20d6a:/#
02.1.3.2、構建鏡像
我們使用命令 docker build , 從零開始來創建一個新的鏡像。為此,我們需要創建一個 Dockerfile 文件,其中包含一組指令來告訴 Docker 如何構建我們的鏡像。
[zhanghe@MacBook-Pro centos6.7 ]$ cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "Zhanghe"
RUN /bin/echo ‘root:123456‘ |chpasswd && useradd zhanghe && /bin/echo ‘zhanghe:123456‘ |chpasswd && /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD [ "/usr/sbin/sshd -D" ]%
每一個指令都會在鏡像上創建一個新的層,每一個指令的前綴都必須是大寫的。
第一條FROM,指定使用哪個鏡像源
RUN 指令告訴docker 在鏡像內執行命令,安裝了什麽。。。
然後,我們使用 Dockerfile 文件,通過 docker build 命令來構建一個鏡像。
[zhanghe@MacBook-Pro centos6.7 ]$ docker build -t os/centos:v2 .
Sending build context to Docker daemon 2.048kB
Step 1/6 : FROM centos:6.7
6.7: Pulling from library/centos
cbddbc0189a0: Pull complete
Digest: sha256:7248c96de4648749c7936f203d983530e7ebdd83c3db6d47278392f18bcd7baf
Status: Downloaded newer image for centos:6.7
---> 000c5746fa52
........
Successfully tagged os/centos:v2
參數說明:
- -t :指定要創建的目標鏡像名
- . :Dockerfile 文件所在目錄,可以指定Dockerfile 的絕對路徑
使用docker images 查看創建的鏡像已經在列表中存在,鏡像ID為d9501ed3472c
[zhanghe@MacBook-Pro centos6.7 ]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
os/centos v2 d9501ed3472c 48 seconds ago 191MB
os/ubuntu v2 52430d685485 13 minutes ago 155MB
ubuntu 16.04 7aa3602ab41e 3 days ago 115MB
centos 6.7 000c5746fa52 8 months ago 191MB
我們可以使用新的鏡像來創建容器
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -it os/centos:v2 /bin/bash
[root@af05ba66b2e0 /]# id zhanghe
uid=500(zhanghe) gid=500(zhanghe) groups=500(zhanghe)
從上面看到新鏡像已經包含我們創建的用戶zhanghe
02.1.3.3、設置鏡像標簽
我們可以使用 docker tag 命令,為鏡像添加一個新的標簽。
[zhanghe@MacBook-Pro centos6.7 ]$ docker tag d9501ed3472c os/centos:dev
docker tag 鏡像ID,這裏是 d9501ed3472c ,用戶名稱、鏡像源名(repository name)和新的標簽名(tag)。
使用 docker images 命令可以看到,ID為d9501ed3472c的鏡像多一個標簽。
[zhanghe@MacBook-Pro centos6.7 ]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
os/centos dev d9501ed3472c 2 minutes ago 191MB
os/centos v2 d9501ed3472c 2 minutes ago 191MB
os/ubuntu v2 52430d685485 15 minutes ago 155MB
ubuntu 16.04 7aa3602ab41e 3 days ago 115MB
centos 6.7 000c5746fa52 8 months ago 191MB
02.2.Docker 容器使用
02.2.1、Docker 客戶端
docker 客戶端非常簡單 ,我們可以直接輸入 docker 命令來查看到 Docker 客戶端的所有命令選項。
$ docker
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/Users/zhanghe/.docker")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
......
可以通過命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。
例如我們要查看 docker stats 指令的具體使用方法:
$ docker start --help
Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]
Start one or more stopped containers
Options:
-a, --attach Attach STDOUT/STDERR and forward signals
--checkpoint string Restore from this checkpoint
--checkpoint-dir string Use a custom checkpoint storage directory
--detach-keys string Override the key sequence for detaching a container
-i, --interactive Attach container‘s STDIN
02.2.2、運行一個web應用
前面我們運行的容器並沒有一些什麽特別的用處。
接下來讓我們嘗試使用 docker 構建一個 web 應用程序。
我們將在docker容器中運行一個 Python Flask 應用來運行一個web應用。
[zhanghe@MacBook-Pro centos6.7 ]$ docker pull training/webapp # 載入鏡像
[zhanghe@MacBook-Pro centos6.7 ]$ cat app.py
#!/bin/env python
print "hello world"% [zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -P training/webapp python app.py
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -it --rm ubuntu:16.04 /bin/bash
參數說明:
- -d:讓容器在後臺運行。
- -P:將容器內部使用的網絡端口映射到我們使用的主機上。
- docker run 就是運行容器的命令,具體格式我們會在後面的課程中進行詳細講解,我們這裏簡要的說明一下上面用到的參數。
- -it:這是兩個參數,一個是 -i:交互式操作,一個是 -t 終端。我們這裏打算進入 bash 執行一些命令並查看返回結果,因此我們需要交互式終端。
- --rm:這個參數是說容器退出後隨之將其刪除。默認情況下,為了排障需求,退出的容器並不會立即刪除,除非手動 docker rm。我們這裏只是隨便執行個命令,看看結果,不需要排障和保留結果,因此使用 --rm 可以避免浪費空間。
- ubuntu:16.04:這是指用 ubuntu:16.04 鏡像為基礎來啟動容器。
- bash:放在鏡像名後的是命令,這裏我們希望有個交互式 Shell,因此用的是 bash。
最後我們通過 exit 退出了這個容器。
當利用 docker run 來創建容器時,Docker 在後臺運行的標準操作包括:
- 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
- 利用鏡像創建並啟動一個容器
- 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
- 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
- 從地址池配置一個 ip 地址給容器
- 執行用戶指定的應用程序
- 執行完畢後容器被終止
02.2.3、查看 WEB 應用容器
使用 docker ps 來查看我們正在運行的容器
[zhanghe@MacBook-Pro centos6.7 ]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3ecd4489f5c training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32770->5000/tcp distracted_curran
這裏多了端口信息。
PORTS
0.0.0.0:32770->5000/tcp
Docker 開放了 5000 端口(默認 Python Flask 端口)映射到主機端口 32770 上。
這時我們可以通過瀏覽器訪問WEB應用
我們也可以通過 -p 參數來設置不一樣的端口:
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -p 5000:5000 training/webapp python app.py
02.2.4、網絡端口的快捷方式
通過docker ps 命令可以查看到容器的端口映射,docker還提供了另一個快捷方式:docker port,使用 docker port 可以查看指定 (ID或者名字)容器的某個確定端口映射到宿主機的端口號。
上面我們創建的web應用容器ID為:c3ecd4489f5c 名字為:determined_swanson
我可以使用docker port c3ecd4489f5c 或docker port determined_swanson來查看容器端口的映射情況
[zhanghe@MacBook-Pro centos6.7 ]$ docker port distracted_curran
5000/tcp -> 0.0.0.0:32770
02.2.5、查看WEB應用程序日誌
docker logs [ID或者名字] 可以查看容器內部的標準輸出。
[zhanghe@MacBook-Pro centos6.7 ]$ docker logs -f distracted_curran
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
172.17.0.1 - - [30/Jul/2018 17:33:29] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [30/Jul/2018 17:33:29] "GET /favicon.ico HTTP/1.1" 404 -
-f:讓 docker logs 像使用 tail -f 一樣來輸出容器內部的標準輸出。
從上面,我們可以看到應用程序使用的是 5000 端口並且能夠查看到應用程序的訪問日誌。
02.2.6、查看WEB應用程序容器的進程
我們還可以使用 docker top 來查看容器內部運行的進程
[zhanghe@MacBook-Pro centos6.7 ]$ docker top distracted_curran
PID USER TIME COMMAND
3961 root 0:00 python app.py
02.2.7、檢查WEB應用程序
使用 docker inspect 來查看Docker的底層信息。它會返回一個 JSON 文件記錄著 Docker 容器的配置和狀態信息。
[zhanghe@MacBook-Pro centos6.7 ]$docker inspect determined_swanson
[
{
"Id": "7a38a1ad55c6914b360b565819604733db751d86afd2575236a70a2519527361",
"Created": "2016-05-09T16:20:45.427996598Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
......
02.2.8、停止WEB應用容器
[zhanghe@MacBook-Pro centos6.7 ]$ docker stop determined_swanson
determined_swanson
02.2.9、重啟WEB應用容器
已經停止的容器,我們可以使用命令 docker start 來啟動。
[zhanghe@MacBook-Pro centos6.7 ]$ docker stop distracted_curran
distracted_curran
正在運行的容器,我們可以使用 docker restart 命令來重啟
02.2.10、移除WEB應用容器
我們可以使用 docker rm 命令來刪除不需要的容器
[zhanghe@MacBook-Pro centos6.7 ]$ docker rm distracted_curran
distracted_curran
刪除容器時,容器必須是停止狀態,否則會報如下錯誤
[zhanghe@MacBook-Pro centos6.7 ]$ docker rm determined_swanson
Error response from daemon: You cannot remove a running container 7a38a1ad55c6914b360b565819604733db751d86afd2575236a70a2519527361. Stop the container before attempting removal or use -f
02.3.Docker 容器連接
前面我們實現了通過網絡端口來訪問運行在docker容器內的服務。下面我們來實現通過端口連接到一個docker容器
02.3.1、網絡端口映射
我們創建了一個 python 應用的容器。
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -P training/webapp python app.py
8f70eb93b061840d77005c37e29758b9f13a121c5a49f53c87c304b19ca77a3b
另外,我們可以指定容器綁定的網絡地址,比如綁定 127.0.0.1。
我們使用 -P 參數創建一個容器,使用 docker ps 來看到端口5000綁定主機端口32768。
[zhanghe@MacBook-Pro centos6.7 ]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f70eb93b061 training/webapp "python app.py" 14 seconds ago Up 13 seconds 0.0.0.0:32771->5000/tcp pedantic_wiles
我們也可以使用 -p 標識來指定容器端口綁定到主機端口。
兩種方式的區別是:
- -P :是容器內部端口隨機映射到主機的高端口。
- -p : 是容器內部端口綁定到指定的主機端口。
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -p 5000:5000 training/webapp python app.py
76bd91c12ca78bc305fc684e315d406f25eaecb0af8b8bccb4db19c733f46ae6
[zhanghe@MacBook-Pro centos6.7 ]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76bd91c12ca7 training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp objective_kapitsa
8f70eb93b061 training/webapp "python app.py" 47 seconds ago Up 46 seconds 0.0.0.0:32771->5000/tcp pedantic_wiles
另外,我們可以指定容器綁定的網絡地址,比如綁定127.0.0.1。
$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
95c6ceef88ca3e71eaf303c2833fd6701d8d1b2572b5613b5a932dfdfe8a857c
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95c6ceef88ca training/webapp "python app.py" 6 seconds ago Up 6 seconds 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker
33e4523d30aa training/webapp "python app.py" 3 minutes ago Up 3 minutes 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" 10 minutes ago Up 10 minutes 0.0.0.0:32768->5000/tcp grave_hopper
這樣我們就可以通過訪問127.0.0.1:5001來訪問容器的5000端口。
上面的例子中,默認都是綁定 tcp 端口,如果要綁定 UDP 端口,可以在端口後面加上 /udp。
[zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
48d58aaa44ec0310286ab209bcca3f58056061f7e41f7c0d777102aa46b60cf3
[zhanghe@MacBook-Pro centos6.7 ]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48d58aaa44ec training/webapp "python app.py" 16 seconds ago Up 15 seconds 127.0.0.1:5001->5000/tcp pedantic_liskov
76bd91c12ca7 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp objective_kapitsa
8f70eb93b061 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32771->5000/tcp pedantic_wiles
docker port 命令可以讓我們快捷地查看端口的綁定情況。
zhanghe@MacBook-Pro centos6.7 ]$ docker port pedantic_liskov 5000
127.0.0.1:5001
02.3.2、Docker容器連接
端口映射並不是唯一把 docker 連接到另一個容器的方法。
docker有一個連接系統允許將多個容器連接在一起,共享連接信息。
docker連接會創建一個父子關系,其中父容器可以看到子容器的信息。
02.3.2.1、容器命名
當我們創建一個容器的時候,docker會自動對它進行命名。另外,我們也可以使用--name標識來命名容器,例如:
zhanghe@MacBook-Pro centos6.7 ]$ docker run -d -P --name zhanghe training/webapp python app.py
43780a6eabaaf14e590b6e849235c75f3012995403f97749775e38436db9a441
我們可以使用 docker ps 命令來查看容器名稱。
zhanghe@MacBook-Pro centos6.7 ]$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
43780a6eabaa training/webapp "python app.py" 3 minutes ago Up 3 minutes 0.0.0.0:32769->5000/tcp zhanghe
Docker系列:02.Docker基礎使用