随着容器技術的發展,微服務架構被許多網際網路公司推崇。docker作為一種容器的傳遞方式,可以實作快速傳遞,應用隔離,保持環境一緻性等多方面的優點。這裡對docker的操作做簡單的介紹。
安裝部署
docker的安裝和配置非常簡單,如果對版本沒有要求在系統的預設鏡像源中就有,可直接安裝即可。
1
<code>yum </code><code>install</code> <code>docker -y</code>
<code>vim </code><code>/usr/lib/systemd/system/docker</code><code>.service</code>
添加一行--registry-mirror的
<code>ExecStart=</code><code>/usr/bin/dockerd-current</code> <code>--registry-mirror=https:</code><code>//qxx96o44</code><code>.mirror.aliyuncs.com \</code>
啟動docker:
2
<code> </code><code>systemctl daemon-reload</code>
<code> </code><code>systemctl start docker</code>
使用docker daemon --help 可以檢視背景啟動程序的一些可配置參數。
Docker 常用管理指令
鏡像管理
對于docker我們可以通過本地導入鏡像的方式,或者直接從網絡上的鏡像倉庫進行下載下傳。
顯示鏡像 docker images
搜尋鏡像 docker search nginx
下載下傳鏡像 docker pull nginx
導出鏡像 docker save nginx > /tmp/nginx.tar.gz
導入鏡像 docker load < /tmp/nginx.tar.gz
删除鏡像 docker rmi nginx
命名鏡像 docker tag image-id name:tag
容器管理
當下載下傳好一個鏡像之後,下一步就是使用這個鏡像來啟動一個容器,啟動容器我們使用docker run 指令,這裡會自動建立并啟動。
啟動一個容器,并進入終端, 退出後容器停止
<code>docker run -it nginx sh </code><code># -i -t 打開一個僞終端,打開标準輸入, sh 執行的指令</code>
如果要想退出終端後容器不停止,可以使用 組合鍵:ctrl + p + q
或者登入容器使用 exec 指令(登出後容器不終止):
<code>docker </code><code>exec</code> <code>-it con-name sh</code>
也可以使用如下指令登入容器,但是與其他的登入者共享一個終端,能看到實時操作(退出會終止):
<code>docker attach Con-name</code>
如果你看不見shell提示符,按鍵盤方向鍵的上箭頭。
啟動容器,命名為test,并讓其在背景運作:
<code>docker run -d --name </code><code>test</code> <code>centos </code><code>bash</code> <code>-c </code><code>"for n in {1..10};do echo up;sleep 1;done"</code>
可以使用docker logs 檢視容器的運作狀态資訊:
<code>docker logs </code><code>test</code>
<code>docker logs </code><code>test</code> <code>-f </code><code>#實時檢視日志</code>
啟動一個容器,命名為mynginx,退出後容器删除:
<code>docker run -it --</code><code>rm</code> <code>--name mynginx nginx </code><code>bash</code>
背景啟動一個mynginx的容器
<code>docker run -d --name mynginx nginx</code>
檢視容器的具體資訊:
<code>docker inspect Docker-Name</code>
進入一個正在運作的容器,可以使用如下腳本(退出時需要注意,直接退出會終止容器):
3
<code>#!/bin/bash</code>
<code>pid=`docker inspect --</code><code>format</code> <code>"``.`State`.`Pid`"</code> <code>$1` </code>
<code>nsenter -t $pid -m -u -i -n -p </code><code># nsenter的參數不能少</code>
如果沒有這個指令可以采用yum install util-linux -y進行安裝。
停止一個容器:
<code>docker stop mynginx</code>
或者使用kill ID 的方式:
<code>docker </code><code>kill</code> <code>Docker-ID</code>
殺死所有運作的容器:
<code>docker </code><code>kill</code> <code>$(docker </code><code>ps</code> <code>-a -q)</code>
檢視所有容器(包含未運作的容器):
<code>docker </code><code>ps</code> <code>-a</code>
删除所有的容器(強制删除正在運作的容器加-f 參數):
<code>docker </code><code>rm</code> <code>`docker </code><code>ps</code> <code>--all|</code><code>awk</code> <code>'{print $1}'</code><code>|</code><code>grep</code> <code>-</code><code>v</code> <code>"CONTAINER"</code><code>`</code>
容器端口管理
在啟動容器的時候,如果不指定對應的參數,在容器外部是無法通過網絡來通路容器内的網 絡應用和服務的。當容器中運作一些網絡應用,要讓外部通路這些應用時,可以通過P或 者p參數來指定容器端口映射。當使用P(大寫)時,docker會随機映射一個端口到容器内 部開放的端口
随機端口映射:
<code>docker run --</code><code>rm</code> <code>-it -P nginx</code>
<code>docker run --</code><code>rm</code> <code>-it -p 127.0.0.1::80 nginx</code>
指定端口:
<code>docker run -it --</code><code>rm</code> <code>-p 80:80 nginx </code><code># 第一個端口為主控端端口,第二個為容器内部端口</code>
綁定多個端口:
<code>docker run --</code><code>rm</code> <code>-it -p 82:80 -p 822:22 nginx</code>
指定IP綁定端口:
<code>docker run –</code><code>rm</code> <code>it p 127.0.0.1:80:80 nginx</code>
預設使用的是TCP協定,也可指定協定:
<code>docker run –</code><code>rm</code> <code>it p 127.0.0.1:80:80</code><code>/udp</code> <code>nginx</code>
網絡功能
docker建立的容器預設是使用的Bridge進行網絡通信的,預設情況下建立的容器都在172.17.0.0/16的bridge網絡中。
docker會在主控端建立一個docker0的網卡,預設情況下自帶三種網絡:
4
5
6
<code># docker network ls</code>
<code>NETWORK ID NAME DRIVER SCOPE</code>
<code>19d6580ec589 bridge bridge </code><code>local</code>
<code>7d48677c86bc host host </code><code>local</code>
<code>01b58b1cb415 none null </code><code>local</code>
host網絡是在主機的網絡堆棧上添加一個容器,使用host網絡,主機和容器之間沒有隔離。 例如,如果您使用主機網絡運作在端口80上運作Web伺服器的容器,則Web伺服器可在主機端口80上使用。
host網絡和none網絡是無法直接配置的,我們可以配置和自定義bridge網絡。
檢視網絡類型的具體說明:
docker network inspect bridge
内容會顯示目前配置設定的容器網絡位址。
當我們要建立一個基于某個網絡的容器時,使用 docker run --net=<NETWORK> 指定
容器互聯
您可以使用Docker連結功能來允許容器互相發現,并将有關一個容器的資訊安全地傳輸到另一個容器。 通過引入Docker網絡功能,您仍然可以建立連結,但它們在預設網橋和使用者定義網絡之間的行為方式不同,容器的互聯需要通過容器的name來指定。
建立一個名為web的容器,将它與test容器互聯:
<code>docker run -d --link </code><code>test</code> <code>--name web nginx</code>
這樣兩個容器在預設的docker0中網絡就打通了,其實也是利用DNS的主機和IP解析,在test容器中的/etc/hosts檔案添加了web容器主機名解析配置。不過官方不推薦這樣做,更好的做法是自定義一個bridge網絡。
由于預設容器是以bridge方式接入主控端網絡的,是以這種方式如果不添加路由隻支援在同一台主控端上的容器互聯。
自定義網絡
建議使用使用者定義的bridge網絡來控制哪些容器可以互相通信,還可以使用自動DNS解析容器名稱到IP位址。 Docker提供了建立這些網絡的預設網絡驅動程式。 您可以建立一個新的橋接網絡,覆寫網絡或MACVLAN網絡。 您還可以建立一個網絡插件或遠端網絡進行完整的自定義和控制。
您可以根據需要建立任意數量的網絡,并且可以在任何給定時間将容器連接配接到這些網絡中的零個或多個網絡。 此外,您可以連接配接并斷開網絡中的運作容器,而無需重新啟動容器。 當容器連接配接到多個網絡時,其外部連接配接通過第一個非内部網絡以字母順序提供網絡連接配接。
Bridge 網絡
Bridge網絡是Docker中最常見的網絡類型。 Bridge網絡類似于橋接網絡,但是與傳統的橋接網絡不通,docker的bridge網絡添加了一些新功能并删除一些舊的功能。 以下示例建立一些橋接網絡,并對這些網絡上的容器執行一些實驗。
系統預設的是172.17.0.1/16網段的,如果我們想要修改這個網段(即docker0位址)需要修改啟動檔案:
在ExecStart=區域,加上參數:
<code>--bip=10.10.0.1</code><code>/24</code> <code>\</code>
這裡指定的網段必須以1結尾,不能使用0表示一個網段,否則服務無法啟動。
檢視預設的docker0網絡:
7
8
9
10
11
12
13
14
15
16
17
<code># ip a</code>
<code>1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN </code>
<code> </code><code>link</code><code>/loopback</code> <code>00:00:00:00:00:00 brd 00:00:00:00:00:00</code>
<code> </code><code>inet 127.0.0.1</code><code>/8</code> <code>scope host lo</code>
<code> </code><code>valid_lft forever preferred_lft forever</code>
<code>2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000</code>
<code> </code><code>link</code><code>/ether</code> <code>52:54:00:7f:52:5a brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 192.168.20.231</code><code>/24</code> <code>brd 192.168.20.255 scope global ens3</code>
<code>3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN </code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:3d:be:20:1d brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 10.10.0.1</code><code>/24</code> <code>scope global docker0</code>
<code>76: br-0d7cff84eda0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN </code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:98:d5:cf:bf brd ff:ff:ff:ff:ff:ff</code>
<code> </code><code>inet 172.18.0.1</code><code>/16</code> <code>scope global br-0d7cff84eda0</code>
建立一個自定義的bridge網絡:
<code>docker network create backend </code><code>#預設會使用bridge驅動</code>
18
19
20
21
22
23
24
<code># docker network inspect backend</code>
<code>[</code>
<code> </code><code>{</code>
<code> </code><code>"Name"</code><code>: </code><code>"backend"</code><code>,</code>
<code> </code><code>"Id"</code><code>: </code><code>"0d7cff84eda06d5648a9ec3b079b4f41dfad836a7ea15dbdd2e1521318d93478"</code><code>,</code>
<code> </code><code>"Scope"</code><code>: </code><code>"local"</code><code>,</code>
<code> </code><code>"Driver"</code><code>: </code><code>"bridge"</code><code>,</code>
<code> </code><code>"EnableIPv6"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"IPAM"</code><code>: {</code>
<code> </code><code>"Driver"</code><code>: </code><code>"default"</code><code>,</code>
<code> </code><code>"Options"</code><code>: {},</code>
<code> </code><code>"Config"</code><code>: [</code>
<code> </code><code>{</code>
<code> </code><code>"Subnet"</code><code>: </code><code>"172.18.0.0/16"</code><code>,</code>
<code> </code><code>"Gateway"</code><code>: </code><code>"172.18.0.1/16"</code>
<code> </code><code>}</code>
<code> </code><code>]</code>
<code> </code><code>},</code>
<code> </code><code>"Internal"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"Containers"</code><code>: {},</code>
<code> </code><code>"Options"</code><code>: {},</code>
<code> </code><code>"Labels"</code><code>: {}</code>
<code> </code><code>}</code>
<code>]</code>
<code>0d7cff84eda0 backend bridge </code><code>local</code>
<code>239f46f2ac1c bridge bridge </code><code>local</code>
建立一個容器,并指定backend網絡:
<code># docker run --network=backend -itd --name=ts-net centos</code>
<code>04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c</code>
檢視自定義的網絡狀态:
25
26
27
28
29
30
31
32
<code> </code><code>"Containers"</code><code>: {</code>
<code> </code><code>"04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"ts-net"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"0b9d8cdf461a4a623693b86cb465c624573ff466453e6a0d202bd40937bf23c4"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:ac:12:00:02"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"172.18.0.2/16"</code><code>,</code>
<code> </code><code>"IPv6Address"</code><code>: </code><code>""</code>
<code> </code><code>}</code>
啟動到此網絡的容器必須駐留在相同的Docker主控端上。 網絡中的每個容器都可以立即與網絡中的其他容器進行通信。 雖然網絡本身将容器與外部網絡隔離開來。
使用者自定義的bridge網絡不支援link方式。可以使用之前介紹的端口映射或者使用expose的方式。
如果兩個不同網絡的容器要互相通信那應該怎麼辦呢? 其實很簡單,容器也可以配置多個網絡,就像實體機的多網卡一樣,添加容器到其它網絡可以給它再增加一個虛拟機網卡即可:
給容器test1添加網絡backend,無論容器是否開啟此指令都能生效。這樣容器test1中就會有兩個網段的IP位址。
本文轉自 酥心糖 51CTO部落格,原文連結:http://blog.51cto.com/tryingstuff/1945403