1. 程式人生 > 其它 >Docker基本管理(2)——Docker容器操作、Docker網路

Docker基本管理(2)——Docker容器操作、Docker網路

Docker容器操作

#容器建立:就是將映象載入到容器的過程。

新建立的容器預設處於停止狀態,不執行任何程式,需要在其中發起一個程序來啟動容器。

格式: docker create [選項] 映象

常用選項:

-i:讓容器的輸入保持開啟

-t:讓Docker分配一個偽終端

docker create -it nginx:latest /bin/bash

  

#檢視容器的執行狀態

docker ps -a #-a選項可以顯示所有的容器

#啟動容器

格式: docker start 容器的ID/名稱

#建立並啟動容器

可以直接執行docker run命令, 等同於先執行docker create命令,再執行docker start命令

注意:容器是一個與其中執行的shell命令共存亡的終端,命令執行容器執行, 命令結束容器退出。

docker容器預設會把容器內部第一個程序,也就是pid-1的程式作為docker容器是否正在執行的依據,如果docker容器中pid=1的程序掛了,那麼docker容器便會直接退出,也就是說Docker容器中必須有一個前臺程序,否則認為容器已經掛掉。

當利用docker run來建立容器時, Docker在後臺的標準執行過程是:

(1)檢查本地是否存在指定的映象。當映象不存在時,會從公有倉庫下載;

(2)利用映象建立並啟動一個容器;

(3)分配一個檔案系統給容器,在只讀的映象層外面掛載一層可讀寫層;

(4)從宿主主機配置的網橋介面中橋接一個虛擬機器介面到容器中;

(5)分配一個地址池中的IP地址給容器;

(6)執行使用者指定的應用程式,執行完畢後容器被終止執行。

docker run centos:7 /usr/bin/bash -c ls /

docker ps -a #會發現建立了一個新容器並啟動執行一條shell命令,之後就停止了

#在後臺持續執行docker run建立的容器

需要在docker run命令之後新增-d選項讓Docker容器以守護形式在後臺執行。並且容器所執行的程式不能結束。

docker run -d centos:7 /usr/bin/bash -c "while true;do echo hello; done"

docker ps -a #可以看出容器始終處於UP,執行狀態

docker run -itd --name test1 centos:7 /bin/bash #建立容器並持續執行容器

#終止容器執行

格式: docker stop 容器的ID/名稱

docker stop 關閉容器,有等待時間

docker kill 強制退出,沒有等待時間

#容器的進入

需要進入容器進行命令操作時,可以使用docker exec命令進入執行著的容器。

格式: docker exec -it 容器ID/名稱 /bin/bash

-i:選項表示讓容器的輸入保持開啟;

-t:選項表示讓Docker分配一個偽終端。

docker start c94120b5d701 #進入容器前,確保容器正在執行
docker exec -it c94120b5d701 /bin/bash
ls
exit #退出容器後,容器仍在執行
docker ps -a

  

docker run -it centos:7 bash #不加-d選項會建立容器後直接進入容器,但是退出容器,容器也會停止

#複製到容器中

echo abc123 > ~/test.txt

docker cp ~/test.txt c94120b5d701:/opt/

  

#從容器複製檔案到主機

docker cp c94120b5d701:/opt/test.txt ~/abc123.txt

#容器的匯出與匯入

使用者可以將任何一個Docker容器從一臺機器遷移到另一臺機器。在遷移過程中,可以使用docker export

命令將已經建立好的容器匯出為檔案,無論這個容器是處於執行狀態還是停止狀態均可匯出。可將匯出檔案傳輸到其他機器,通過相應的匯入命令實現容器的遷移。

#匯出格式: docker export 容器ID/名稱 > 檔名

docker export c94120b5d701> centos7.tar

#匯入格式: cat 檔名 | docker import - 映象名稱:標籤

cat centos7.tar | docker import - centos7:test #匯入後會生成映象,但不會建立容器

#刪除容器

格式: docker rm [-f] 容器ID/名稱 docker stop c94120b5d701 docker rm c94120b5d701#刪除已經終止狀態的容器 docker rm -f c94120b5d701#強制刪除正在執行的容器 docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash #批量停止容器 docker ps -a | awk 'NR>=2{print $1}' | xargs docker stop docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash #批量刪除所有容器 docker ps -a | awk 'NR>=2{print $1}' | xargs docker rm docker images | awk 'NR>=2{print "docker rmi "$3}' | bash #批量刪除映象 docker images | grep none | awk '{print $3}' | xargs docker rmi #刪除none映象

docker rm -f $(docker ps -a -q)

批量刪除所有容器

Docker網路

#Docker網路實現原理

Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0) , Docker啟動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,稱為Container-IP,同時Docker網橋是每個容器的預設閘道器。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的container-IP直接通訊。

Docker網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路是無法定址到的,這也意味著外部網路無法直接通過Container-IP訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到宿主主機(埠對映) ,即dockerrun建立容器時候通過-p或-p引數來啟用,訪問容器的時候就通過[宿主機IP] : [容器埠]訪問容器。

docker run -d --name test1 -P nginx #隨機對映埠(從32768開始)
docker run -d --name test2 -p 43000:80 nginx #指定對映埠
docker ps -a

  

瀏覽器訪問: http://192.168.80.10:43000 、http://192.168.80.10:49170

#Docker的網路模式:

Host:容器將不會虛擬出自己的網絡卡,配置自己的IP等,而是使用宿主機的IP和埠。

Container:建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍。None:該模式關閉了容器的網路功能。

Bridge:預設為該模式,此模式會為每一個容器分配、設定IP等,並將容器連線到一個docker0虛擬網橋,通過docker0網橋以及iptables nat表配置與宿主機通訊。

自定義網路

安裝Docker時,它會自動建立三個網路, bridge (建立容器預設連線到此網路)、none 、host

#檢視docker網路列表

docker network ls 或 docker network list

#使用docker run建立Docker容器時,可以用 --net 或 --network選項指定容器的網路模式

host模式:使用 --net=host 指定。 none模式:使用 -net=none 指定。 container模式:使用 --net=container:NAME_or_ID 指定。 bridge模式:使用 --net=bridge 指定,預設設定,可省略。

#網路模式詳解:

1、host模式

相當於Vmware中的橋接模式,與宿主機在同一個網路中,但沒有獨立IP地址。

Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離程序, Mount Namespace隔離檔案系統, NetworkNamespace隔離網路等。

一個Network Namespace提供了一份獨立的網路環境,包括網絡卡、路由、iptable規則等都與其他的Network Namespace隔離。

一個Docker容器一般會分配一個獨立的Network Namespace。

但如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,

而是和宿主機共用一個Network Namespace,容器將不會虛擬出自己的網絡卡、配置自己的IP等,而是使用宿主機的IP和埠。

2、container模式

在理解了host模式後,這個模式也就好理解了。這個模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過lo網絡卡裝置通訊。
docker run -itd --name test1 centos:7 /bin/bash #--name選項可以給容器建立一個自定義名稱
docker ps -a

  

docker inspect -f '{{.State.Pid}}' 13bdb7aa8f3d #檢視容器程序號
ls -l /proc/10465/ns        #檢視容器的程序、網路、檔案系統等名稱空間編號

  

docker run -itd --name test2 --net=container:13bdb7aa8f3d centos:7 /bin/bash
docker ps -a

  

docker inspect -f '{{.State.Pid}}' 7edab2e0f434
ls -l /proc/10631/ns #檢視可以發現兩個容器的net namespace編號相同

  

3、none模式

使用none模式, Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。 也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。這種網路模式下容器只有lo迴環網路,沒有其他網絡卡。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。

4、bridge模式

bridge模式是docker的預設網路模式,不用 --net 引數,就是 bridge 模式。

相當於Vmware中的nat模式,容器使用獨立network Namespace,並連線到docker0虛擬網絡卡。通過docker0網橋以及iptables nat表配置與宿主機通訊,此模式會為每一個容器分配Network Namespace、設定IP等,並將一個主機上的Docker容器連線到一個虛擬網橋上

(1)當Docker程序啟動時,會在主機上建立一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。

(2)從docker0子網中分配一個I給容器使用,並設定docker0的IP地址為容器的預設閘道器。在主機上建立一對虛擬網絡卡vethpair裝置。veth裝置總是成對出現的,它們組成了一個數據的通道,資料從一個裝置進入,就會從另一個裝置出來。因此, veth裝置常用來連線兩個網路裝置

(3)Docker將veth pair裝置的一端放在新建立的容器中,並命名為eth0 (容器的網絡卡) ,另一端放在主機中, 以veth*這樣類似的名字命名,並將這個網路裝置加入到docker0網橋中。可以通過brctl show命令檢視

(4)使用docker run -p時, docker實際是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL檢視

5、自定義網路

#直接使用bridge模式,是無法支援指定IP執行docker的,例如執行以下命令就會報錯

docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash

//建立自定義網路

#可以先自定義網路,再使用指定IP執行docker

docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork

#docker1為執行 ifconfig -a 命令時,顯示的網絡卡名,如果不使用--opt引數指定此名稱,那你在使用ifconfig -a命令檢視網路資訊時,看到的是類似br-110eb56a0b22這樣的名字,這顯然不怎麼好記。

#mynetwork為執行docker network list命令時,顯示的bridge網路模式名稱。

docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash