Docker 學習教程

1、Docker介紹

1.1、什麼是Docker

Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從Apache2.0協議開源。

Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後發佈到任何流行的 Linux 機器上,也可以實現虛擬化。

容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。

1.2、Docker的應用場景

Web 應用的自動化打包和發佈。

自動化測試和持續集成、發佈。

在服務型環境中部署和調整數據庫或其他的後臺應用。

從頭編譯或者擴展現有的OpenShift或Cloud Foundry平臺來搭建自己的PaaS環境。

1.3、Docker 的優點

1、簡化程序:
Docker 讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發佈到任何流行的 Linux 機器上,便可以實現虛擬化。Docker改變了虛擬化的方式,使開發者可以直接將自己的成果放入Docker中進行管理。方便快捷已經是 Docker的最大優勢,過去需要用數天乃至數週的 任務,在Docker容器的處理下,只需要數秒就能完成。

2、避免選擇恐懼症:
如果你有選擇恐懼症,還是資深患者。Docker 幫你 打包你的糾結!比如 Docker 鏡像;Docker 鏡像中包含了運行環境和配置,所以 Docker 可以簡化部署多種應用實例工作。比如 Web 應用、後臺應用、數據庫應用、大數據應用比如 Hadoop 集羣、消息隊列等等都可以打包成一個鏡像部署。

3、節省開支:
一方面,雲計算時代到來,使開發者不必爲了追求效果而配置高額的硬件,Docker 改變了高性能必然高價格的思維定勢。Docker 與雲的結合,讓雲空間得到更充分的利用。不僅解決了硬件管理的問題,也改變了虛擬化的方式。

1.4、相關連接

  1. Docker 官網
  2. Github Docker 源碼

2、Docker 架構

Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和創建Docker容器。

Docker 容器通過 Docker 鏡像來創建。

容器與鏡像的關係類似於面向對象編程中的對象與類。

Docker 面向對象
容器 對象
鏡像

在這裏插入圖片描述

名詞 解釋
Docker 鏡像(Images) Docker 鏡像是用於創建 Docker 容器的模板。
Docker 容器(Container) 容器是獨立運行的一個或一組應用。
Docker 客戶端(Client) Docker 客戶端通過命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 與 Docker 的守護進程通信。
Docker 主機(Host) 一個物理或者虛擬的機器用於執行 Docker 守護進程和容器。
Docker 倉庫(Registry) Docker 倉庫用來保存鏡像,可以理解爲代碼控制中的代碼倉庫。Docker Hub(https://hub.docker.com) 提供了龐大的鏡像集合供使用。
Docker Machine Docker Machine是一個簡化Docker安裝的命令行工具,通過一個簡單的命令行即可在相應的平臺上安裝Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

3、Docker使用

3.1、Docker Hello World

Docker 允許你在容器內運行應用程序, 使用 docker run 命令來在容器內運行一個應用程序。

3.1.1、輸出Hello world

#拉取ubuntu:15.10鏡像
docker pull ubuntu:15.10 
#在容器ubuntu:15.10中運行 /bin/echo "Hello world"
docker run ubuntu:15.10 /bin/echo "Hello world" 

在這裏插入圖片描述

3.1.2、運行交互式的容器

我們通過docker的兩個參數 -i -t,讓docker運行的容器實現"對話"的能力

#交互方式運行ubuntu:15.10
docker run -i -t ubuntu:15.10 /bin/bash

在這裏插入圖片描述

3.1.3、啓動容器(後臺模式)

使用以下命令創建一個以進程方式運行的容器

#後臺方式運行
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
#查看處於運行狀態的容器
docker ps
#查看容器內輸出
docker logs <CONTAINER ID>

在這裏插入圖片描述

3.1.4、停止容器

我們使用 docker stop 命令來停止容器

#查看運行中的容器
docker ps
#停止指定容器
docker stop <CONTAINER ID>

在這裏插入圖片描述

3.2、Docker 容器使用

3.2.1、Docker 客戶端

docker 客戶端非常簡單 ,我們可以直接輸入 docker 命令來查看到 Docker 客戶端的所有命令選項。

#可以通過以下命令查看docker命令選項
docker
docker --help
docker -h
#使用 docker command --help 更深入的瞭解指定的 Docker 命令使用方法,例如:
docker stats --help

3.2.2、運行一個web應用

前面我們運行的容器並沒有一些什麼特別的用處。

接下來讓我們嘗試使用 docker 構建一個 web 應用程序。

我們將在docker容器中運行一個 Python Flask 應用來運行一個web應用。

docker pull training/webapp  # 載入鏡像
docker run -d -P training/webapp python app.py

參數說明:

-d:讓容器在後臺運行。

-P:將容器內部使用的網絡端口映射到我們使用的主機上。
在這裏插入圖片描述

3.2.3、查看 WEB 應用容器

使用 docker ps 來查看我們正在運行的容器:
在這裏插入圖片描述
Docker 開放了 5000 端口(默認 Python Flask 端口)映射到主機端口 32768 上。

這時我們可以通過瀏覽器訪問WEB應用

在這裏插入圖片描述
我們也可以通過 -p 參數來設置不一樣的端口:

docker run -d -p 5000:5000 training/webapp python app.py

docker ps查看正在運行的容器
在這裏插入圖片描述
容器內部的 5000 端口映射到我們本地主機的 5000 端口上。
在這裏插入圖片描述

3.2.4、網絡端口的快捷方式

通過 docker ps 命令可以查看到容器的端口映射,docker 還提供了另一個快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某個確定端口映射到宿主機的端口號。

上面我們創建的 web 應用容器 ID 爲 ee8b2e70bcb3 名字爲 dazzling_babbage。

我可以使用如下命令來查看容器端口的映射情況。

docker port ee8b2e70bcb3
docker port dazzling_babbage

在這裏插入圖片描述

3.2.5、查看 WEB 應用程序日誌

docker logs [ID或者名字] 可以查看容器內部的標準輸出。
在這裏插入圖片描述

3.2.6、查看WEB應用程序容器的進程

我們還可以使用 docker top 來查看容器內部運行的進程
在這裏插入圖片描述

3.2.7、檢查 WEB 應用程序

使用 docker inspect 來查看 Docker 的底層信息。它會返回一個 JSON 文件記錄着 Docker 容器的配置和狀態信息。
在這裏插入圖片描述

3.2.8、停止 WEB 應用容器

在這裏插入圖片描述

3.2.9、重啓WEB應用容器

  • 已經停止的容器,我們可以使用命令 docker start 來啓動。
  • docker ps -l 查詢最後一次創建的容器:
  • 正在運行的容器,我們可以使用 docker restart 命令來重啓

3.2.10、移除WEB應用容器

  • 我們可以使用 docker rm 命令來刪除不需要的容器
  • 刪除容器時,容器必須是停止狀態,否則會報錯誤

3.3、Docker 鏡像使用

當運行容器時,使用的鏡像如果在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。

下面我們來學習:

1、管理和使用本地 Docker 主機鏡像
2、創建鏡像

3.3.1、列出鏡像列表

我們可以使用 docker images 來列出本地主機上的鏡像。

runoob@runoob:~$ docker images           
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              14.04               90d5884b1ee0        5 days ago          188 MB
php                 5.6                 f40e9e0f10c8        9 days ago          444.8 MB
nginx               latest              6f8d099c3adc        12 days ago         182.7 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago         324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago         194.4 MB
ubuntu              15.10               4e3b13c8a266        4 weeks ago         136.3 MB
hello-world         latest              690ed74de00f        6 months ago        960 B
training/webapp     latest              6fae60ef3446        11 months ago       348.8 MB
選項 說明
REPOSITORY 表示鏡像的倉庫源
TAG 鏡像的標籤
IMAGE ID 鏡像ID
CREATED 鏡像創建時間
SIZE 鏡像大小

同一倉庫源可以有多個 TAG,代表這個倉庫源的不同個版本,如ubuntu倉庫源裏,有15.10、14.04等多個不同的版本,我們使用 REPOSITORY:TAG 來定義不同的鏡像。

所以,我們如果要使用版本爲15.10的ubuntu系統鏡像來運行容器時,命令如下:

runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash 
root@d77ccb2e5cca:/#

如果要使用版本爲14.04的ubuntu系統鏡像來運行容器時,命令如下:

runoob@runoob:~$ docker run -t -i ubuntu:14.04 /bin/bash 
root@39e968165990:/# 

如果你不指定一個鏡像的版本標籤,例如你只使用 ubuntu,docker 將默認使用 ubuntu:latest 鏡像。

3.3.2、獲取一個新的鏡像

當我們在本地主機上使用一個不存在的鏡像時 Docker 就會自動下載這個鏡像。如果我們想預先下載這個鏡像,我們可以使用 docker pull 命令來下載它。

runoob@runoob:~$ docker pull ubuntu:13.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:13.10

下載完成後,我們可以直接使用這個鏡像來運行容器。

3.3.3、查找鏡像

我們可以從 Docker Hub 網站來搜索鏡像,Docker Hub 網址爲: https://hub.docker.com/
我們也可以使用 docker search 命令來搜索鏡像。比如我們需要一個httpd的鏡像來作爲我們的web服務。我們可以通過 docker search 命令搜索 httpd 來尋找適合我們的鏡像。

runoob@runoob:~$  docker search httpd
選項 說明
NAME 鏡像倉庫源的名稱
DESCRIPTION 鏡像的描述
OFFICIAL 是否docker官方發佈

3.3.4、拖取鏡像

我們決定使用上圖中的httpd 官方版本的鏡像,使用命令 docker pull 來下載鏡像。

3.3.5、創建鏡像

當我們從docker鏡像倉庫中下載的鏡像不能滿足我們的需求時,我們可以通過以下兩種方式對鏡像進行更改。
1.從已經創建的容器中更新鏡像,並且提交這個鏡像
2.使用 Dockerfile 指令來創建一個新的鏡像

3.3.6、更新鏡像

更新鏡像之前,我們需要使用鏡像來創建一個容器。

runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash
root@e218edb10161:/# 在運行的容器內使用 apt-get update 命令進行更新。

在完成操作之後,輸入 exit命令來退出這個容器。

此時ID爲e218edb10161的容器,是按我們的需求更改的容器。我們可以通過命令 docker commit來提交容器副本。

runoob@runoob:~$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee9545aff8

各個參數說明:

-m:提交的描述信息

-a:指定鏡像作者

e218edb10161:容器ID

runoob/ubuntu:v2:指定要創建的目標鏡像名

我們可以使用 docker images 命令來查看我們的新鏡像 runoob/ubuntu:v2:

runoob@runoob:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
runoob/ubuntu       v2                  70bf1840fd7c        15 seconds ago      158.5 MB
ubuntu              14.04               90d5884b1ee0        5 days ago          188 MB
php                 5.6                 f40e9e0f10c8        9 days ago          444.8 MB
nginx               latest              6f8d099c3adc        12 days ago         182.7 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago         324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago         194.4 MB
ubuntu              15.10               4e3b13c8a266        4 weeks ago         136.3 MB
hello-world         latest              690ed74de00f        6 months ago        960 B
training/webapp     latest              6fae60ef3446        12 months ago       348.8 MB

使用我們的新鏡像 runoob/ubuntu 來啓動一個容器

runoob@runoob:~$ docker run -t -i runoob/ubuntu:v2 /bin/bash                            
root@1a9fbdeb5da3:/#

3.3.7、構建鏡像

我們使用命令 docker build , 從零開始來創建一個新的鏡像。爲此,我們需要創建一個 Dockerfile 文件,其中包含一組指令來告訴 Docker 如何構建我們的鏡像。

runoob@runoob:~$ cat Dockerfile 
FROM    centos:6.7
MAINTAINER      Fisher "[email protected]"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd runoob
RUN     /bin/echo 'runoob:123456' |chpasswd
RUN     /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 命令來構建一個鏡像。

runoob@runoob:~$ docker build -t runoob/centos:6.7 .
Sending build context to Docker daemon 17.92 kB
Step 1 : FROM centos:6.7
 ---&gt; d95b5ca17cc3
Step 2 : MAINTAINER Fisher "[email protected]"
 ---&gt; Using cache
 ---&gt; 0c92299c6f03
Step 3 : RUN /bin/echo 'root:123456' |chpasswd
 ---&gt; Using cache
 ---&gt; 0397ce2fbd0a
Step 4 : RUN useradd runoob
......

參數說明:

-t :指定要創建的目標鏡像名

. :Dockerfile 文件所在目錄,可以指定Dockerfile 的絕對路徑

使用docker images 查看創建的鏡像已經在列表中存在,鏡像ID爲860c279d2fec

runoob@runoob:~$ docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
runoob/centos       6.7                 860c279d2fec        About a minute ago   190.6 MB
runoob/ubuntu       v2                  70bf1840fd7c        17 hours ago         158.5 MB
ubuntu              14.04               90d5884b1ee0        6 days ago           188 MB
php                 5.6                 f40e9e0f10c8        10 days ago          444.8 MB
nginx               latest              6f8d099c3adc        12 days ago          182.7 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago          324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago          194.4 MB
ubuntu              15.10               4e3b13c8a266        5 weeks ago          136.3 MB
hello-world         latest              690ed74de00f        6 months ago         960 B
centos              6.7                 d95b5ca17cc3        6 months ago         190.6 MB
training/webapp     latest              6fae60ef3446        12 months ago        348.8 MB

我們可以使用新的鏡像來創建容器

runoob@runoob:~$ docker run -t -i runoob/centos:6.7  /bin/bash
[root@41c28d18b5fb /]# id runoob
uid=500(runoob) gid=500(runoob) groups=500(runoob)

從上面看到新鏡像已經包含我們創建的用戶runoob

3.3.8、設置鏡像標籤

我們可以使用 docker tag 命令,爲鏡像添加一個新的標籤。

runoob@runoob:~$ docker tag 860c279d2fec runoob/centos:dev

docker tag 鏡像ID,這裏是 860c279d2fec ,用戶名稱、鏡像源名(repository name)和新的標籤名(tag)。

使用 docker images 命令可以看到,ID爲860c279d2fec的鏡像多一個標籤。

runoob@runoob:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
runoob/centos       6.7                 860c279d2fec        5 hours ago         190.6 MB
runoob/centos       dev                 860c279d2fec        5 hours ago         190.6 MB
runoob/ubuntu       v2                  70bf1840fd7c        22 hours ago        158.5 MB
ubuntu              14.04               90d5884b1ee0        6 days ago          188 MB
php                 5.6                 f40e9e0f10c8        10 days ago         444.8 MB
nginx               latest              6f8d099c3adc        13 days ago         182.7 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago         324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago         194.4 MB
ubuntu              15.10               4e3b13c8a266        5 weeks ago         136.3 MB
hello-world         latest              690ed74de00f        6 months ago        960 B
centos              6.7                 d95b5ca17cc3        6 months ago        190.6 MB
training/webapp     latest              6fae60ef3446        12 months ago       348.8 MB

3.4、Docker 容器連接

前面我們實現了通過網絡端口來訪問運行在 docker 容器內的服務。下面我們來實現通過端口連接到一個 docker 容器

3.4.1、網絡端口映射

我們創建了一個 python 應用的容器。

runoob@runoob:~$ docker run -d -P training/webapp python app.py
fce072cc88cee71b1cdceb57c2821d054a4a59f67da6b416fceb5593f059fc6d

我們使用 -P 參數創建一個容器,使用 docker ps 來看到端口 5000 綁定主機端口 32768。

runoob@runoob:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
fce072cc88ce        training/webapp     "python app.py"     4 minutes ago       Up 4 minutes        0.0.0.0:32768->5000/tcp   grave_hopper

我們也可以使用 -p 標識來指定容器端口綁定到主機端口。

兩種方式的區別是:

-P :是容器內部端口隨機映射到主機的高端口。
-p : 是容器內部端口綁定到指定的主機端口。

runoob@runoob:~$ docker run -d -p 5000:5000 training/webapp python app.py
33e4523d30aaf0258915c368e66e03b49535de0ef20317d3f639d40222ba6bc0
runoob@runoob:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                     NAMES
33e4523d30aa        training/webapp     "python app.py"     About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp    berserk_bartik
fce072cc88ce        training/webapp     "python app.py"     8 minutes ago        Up 8 minutes        0.0.0.0:32768->5000/tcp   grave_hopper

另外,我們可以指定容器綁定的網絡地址,比如綁定 127.0.0.1。

runoob@runoob:~$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
95c6ceef88ca3e71eaf303c2833fd6701d8d1b2572b5613b5a932dfdfe8a857c
runoob@runoob:~$ 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。

runoob@runoob:~$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
6779686f06f6204579c1d655dd8b2b31e8e809b245a97b2d3a8e35abe9dcd22a
runoob@runoob:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                NAMES
6779686f06f6        training/webapp     "python app.py"     4 seconds ago       Up 2 seconds        5000/tcp, 127.0.0.1:5000->5000/udp   drunk_visvesvaraya
95c6ceef88ca        training/webapp     "python app.py"     2 minutes ago       Up 2 minutes        5000/tcp, 127.0.0.1:5001->5000/tcp   adoring_stonebraker
33e4523d30aa        training/webapp     "python app.py"     5 minutes ago       Up 5 minutes        0.0.0.0:5000->5000/tcp               berserk_bartik
fce072cc88ce        training/webapp     "python app.py"     12 minutes ago      Up 12 minutes       0.0.0.0:32768->5000/tcp              grave_hopper

docker port 命令可以讓我們快捷地查看端口的綁定情況。

runoob@runoob:~$ docker port adoring_stonebraker 5000
127.0.0.1:5001

3.4.2、Docker容器連接

端口映射並不是唯一把 docker 連接到另一個容器的方法。

docker 有一個連接系統允許將多個容器連接在一起,共享連接信息。

docker 連接會創建一個父子關係,其中父容器可以看到子容器的信息。

3.4.3、容器命名

當我們創建一個容器的時候,docker 會自動對它進行命名。另外,我們也可以使用 --name 標識來命名容器,例如:

runoob@runoob:~$  docker run -d -P --name runoob training/webapp python app.py
43780a6eabaaf14e590b6e849235c75f3012995403f97749775e38436db9a441

我們可以使用 docker ps 命令來查看容器名稱。

runoob@runoob:~$ 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   runoob
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章