一、Docker 架構
http://blog.csdn.net/u012562943/article/category/6048991/1
Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器。
Docker 容器經過 Docker 鏡像來建立。
容器與鏡像的關係相似於面向對象編程中的對象與類。
Docker 面向對象
容器 對象
鏡像 類html

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。
Docker項目的目標是實現輕量級的操做系統虛擬化解決方案。Docker的基礎是linux容器(LXC)等技術。
二、Docker的概念,安裝及鏡像管理
2.一、docker的概念:
鏡像:是一個只讀的模板,相似於安裝系統用到的那個iso文件,咱們經過鏡像來完成各類應用的部署。鏡像能夠用來建立Docker容器
容器:鏡像相似於操做系統,而容器相似於虛擬機自己。它能夠被啓動、開始、中止、刪除等操做,每一個容器都是相互隔離的。能夠把容器看作是一個簡易版的linux環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。
倉庫:存放鏡像的一個場所,倉庫分爲公開倉庫和私有倉庫。 最大的公開倉庫是Docker hub(hub.docker.com),國內公開倉庫(dockerpool.com)
2.二、docker安裝啓動:
yum install -y epel-release
yum instal -y docker
systemctl enable docker.service
systemctl start docker
2.三、鏡像管理
2.3.一、獲取鏡像
語法:docker pull NAME[:TAG]
其中,NAME是鏡像倉庫的名稱(用來區分鏡像),TAG是鏡像的標籤(用來表示版本信息)
docker pull centos:從docker.com獲取centos鏡像
2.3.二、查看鏡像
語法:docker images
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest b175e7467d66 2 days ago 109 MB

docker tag centos long:爲centos鏡像設置標籤爲long,再使用docker images查看會多出來一行,打了標籤的image id和centos的同樣
[root@localhost ~]# docker tag nginx nginx_1.12.2
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest b175e7467d66 2 days ago 109 MB
nginx_1.12.2 latest b175e7467d66 2 days ago 109 MB
docker inspect {IMAGE_ID | IMAGE_NAME}:獲取鏡像詳細信息
[root@localhost ~]# docker inspect nginx
返回的是一個JSON格式的消息,若是咱們只要其中一項內容時,可使用參數-f來指定,例如,獲取鏡像的Architecture
[root@localhost ~]# docker inspect -f {{".Architecture"}} nginx
amd64
2.3.三、搜索鏡像
docker search [image-name]:從docker倉庫搜索docker鏡像,後面是關鍵詞
[root@localhost ~]# docker search nginx
2.3.四、刪除鏡像
docker rmi centos:用來刪除指定鏡像, 其中後面的參數能夠是tag,若是是tag時,其實是刪除該tag,只要該鏡像還有其餘tag,就不會刪除該鏡像。當後面的參數爲鏡像ID時,則會完全刪除整個鏡像,連通全部標籤一同刪除
[root@localhost ~]# docker rmi nginx_1111
Untagged: nginx_1111:latest
Untagged: docker.io/nginx@sha256:37350fbb4afbb1c01b6e542fe1537dd701e4430983d6d9c673cbb5eccdbec357
docker rmi -f centos:強制刪除,通常不建議使用,會致使某些問題
[root@localhost ~]# docker rmi -f nginx_1111
Untagged: nginx_1111:latest
2.3.五、建立鏡像
建立鏡像的方法有如下3種方式:
(1)基於已有鏡像的容器建立
(2)基於本地模板導入
(3)基於Dockerfile建立python
(1)基於已有鏡像的容器建立
命令格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 主要選項: -a:做者信息 -m:提交消息 -p:提交時暫停容器運行 運行docker run後,進入到該容器中,咱們作一些變動,好比安裝一些東西,而後針對這個容器進行建立新的鏡像
[root@localhost ~]# docker ps -a //查看全部的容器
[root@localhost ~]# docker start 67d //啓動ID爲67d的容器,ID可簡寫爲前3位
[root@localhost ~]# docker exec -it 67d /bin/bash //進入67d容器
[root@67dde53e0651 /]# yum install -y net-tools wget
[root@67dde53e0651 /]# exit
[root@localhost ~]# docker commit -m "centos_with_nettools_wget" -a "long" 67d centos_with_net //建立新的鏡像
sha256:90f2a945a44d466c8a8d46dcdd4ab80f9f2aab79761482a1b5839d9ea2cf7904
tips:這個命令有點像svn的提交,-m 加一些改動信息,-a 指定做者相關信息 67d這一串爲容器id,再後面爲新鏡像的名字
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_with_net latest 90f2a945a44d 32 seconds ago 300.6MB
docker.io/centos latest 328edcd84f1b 11 days ago 192.5MB
long long 328edcd84f1b 11 days ago 192.5MB
(2)基於本地模板導入 模塊獲取,能夠直接在網上下載一個模塊
[root@izwz920g719hydx1spem46z ~]# wget https://download.openvz.org/template/precreated/contrib/centos-7-x86_64-minimal-20170709.tar.xz
http://openvz.org/Download/templates/precreated 惋惜速度並不快,若咱們下載了一個centos的模板 centos-7-x86_64-minimal-20170709.tar.xz那麼導入該鏡像的命令爲:
cat centos-7-x86_64-minimal-20170709.tar.xz |docker import - centos-5-x86
2.3.六、存出和載入鏡像以及上傳鏡像
docker save -o ***.tar IMAGE:TAG
docker load --input ***.tar 或 dokcer load < ***.tar
docker push IMAGE_NAME
把現有鏡像,導出爲一個文件,能夠做爲備份:
docker save -o long.tar long:long
咱們還能夠用該文件恢復本地鏡像:
docker load --input long.tar 或者
docker load < long.tar
docker push image_name //能夠把本身的鏡像傳到dockerhub官方網站上去,但前提是須要先註冊一個用戶,後續若是有需求再研究吧
三、操做Docker容器
3.一、建立容器
當使用docker run來建立並啓動容器時,Docker在後臺運行的標準操做:
(1)檢查本地是否存在指定的鏡像centos,不存在就從公有倉庫下載
(2)利用鏡像建立並啓動一個容器
(3)分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
(4)從宿主主機配置的橋接網絡接口中橋接一個虛擬接口到容器中去
(5)從地址池配置一個IP地址給容器
(6)執行用戶指定的應用程序
(7)執行完畢後,容器被終止mysql
語法:
建立容器:docker create -it {image_name}
docker create命令新建的容器處於中止狀態,可使用docker start命令來啓動它。
啓動容器:docker start {container_id}
新建並啓動容器:docker run -t -i centos /bin/bash
用下載到的鏡像開啓容器,-i表示讓容器的標準輸入打開,-t表示分配一個僞終端,要把-i -t 放到鏡像名字前面
[root@localhost ~]# docker run -t -i nginx /bin/bash
root@c1eff06c8501:/#
守護態運行容器:docker run -itd centos /bin/bash
3.二、終止容器
可使用docker stop來終止一個運行中的容器,改命令的格式爲docker stoop [container]
首先向容器發送SIGTERM信號,等待一段超時時間(默認爲10s)後,再發送SIGKILL信號來終止容器
docker kill
命令會直接發送SIGKILL信號來強行終止容器linux
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
402e1bd8ff16 centos "/bin/bash" 16 hours ago Up 16 hours mynginx
[root@localhost ~]# docker stop mynginx
mynginx
3.三、進入容器
進入容器有如下3種方法:
(1)attach命令
(2)exec命令(推薦方式)
(3)nsenter工具nginx
(1)attach命令
[root@localhost ~]# docker attach mynginx
[root@402e1bd8ff16 /]#
注意:使用attach命令有時候並不方便,當多個窗口同時使用attach命令連接到同一個容器的時候,全部窗口都會同步顯示。當某個窗口因命令阻塞時,其餘窗口也沒法進行操做。
(2)exec命令(推薦方式)
[root@localhost ~]# docker exec -it mynginx /bin/bash
[root@402e1bd8ff16 /]#
(3)nsenter工具
[root@localhost ~]# yum install -y util-linux #安裝nsenter工具
爲了使nsenter連接到容器,還須要找到容器進程的PID,能夠經過如下命令獲取
PID=$(docker inspect --format "{{.State.Pid}}" <container>)
經過這個pid就能夠鏈接到這個容器
nsenter -t $PID -u -i -n -p
通常狀況下,將這個工具寫成一個腳本更方便:
[root@localhost ~]# cat ns.sh
#!/bin/bash
PID=`docker inspect --format "{{.State.Pid}}" $1`
nsenter -t $PID -u -i -n -p
[root@localhost ~]# ./ns.sh mynginx
[root@402e1bd8ff16 ~]#
3.四、刪除容器
可使用docker rm 命令來刪除處於終止或退出狀態的容器,命令格式爲docker rm <container>
默認狀況下,docker rm 只能刪除處於終止或退出狀態的容器,並不能刪除還處於運行狀態的容器。若是須要直接刪除一個運行中的容器,能夠添加-f參數。Docker會先發送SIGKILL信號給容器,終止其中的應用,以後強行刪除。
選項:
-f:
強行終止並刪除在運行的一個容器
-l:
刪除容器的連接,但保留容器
-v:
刪除容器掛載的數據卷git
1
2
|
[root@localhost ~]
nginx2
|
3.五、導入和導出容器
導出容器是指導出一個已經建立的容器到一個文件,無論此時這個容器是否處於運行狀態,可使用docker export命令
格式爲:docker export CONTAINER_ID
docker export container_id > file.tar // 導出容器,能夠遷移到其餘機器上,須要導入
舉例:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c40ae00fd190 centos_1 "bash" 14 hours ago Up 14 hours 0.0.0.0:82->80/tcp mad_yonath
84acb55af1f9 nginx "bash" 14 hours ago Up 14 hours 0.0.0.0:81->80/tcp prickly_montalcini
[root@localhost ~]# docker export 84acb55af1f9 > file.tar
導出的文件file.tar又可使用docker import 命令導入,成爲鏡像
格式:cat ***.tar |docker import - IMAGENAME:TAG
[root@localhost ~]# cat /tmp/mynginx.tar |docker import - test/nginx:v1
sha256:f133989eba3b11f0b81e6976421f9510a94d8692cceb7505c4d98029870cd110
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx v1 f133989eba3b 3 seconds ago 199 MB
3.六、docker的基礎命令
[root@localhost ~]# docker -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker") #客戶端配置文件的位置
-D, --debug Enable debug mode #啓用Debug調試模式
--help Print usage #查看幫助信息
-H, --host list Daemon socket(s) to connect to (default []) #守護進程的套接字(Socket)鏈接
-l, --log-level string Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info") #設置日誌級別
-v, --version Print version information and quit #打印版本信息並退出
Commands:
attach Attach to a running container #進入一個正在運行的容器
build Build an image from a Dockerfile #經過Dockerfile建立鏡像
commit Create a new image from a container's changes #提交當前容器爲一個新的鏡像
cp Copy files/folders between a container and the local filesystem #從容器中拷貝指定文件或者目錄到宿主機中
create Create a new container #建立一個新的容器
diff Inspect changes on a container's filesystem #查看docker容器變化
events Get real time events from the server #從docker服務獲取容器實時事件
exec Run a command in a running container #在一個已經運行的容器中運行一條命令
export Export a container's filesystem as a tar archive #導出容器的內容流做爲一個tar歸檔文件
history Show the history of an image #展現一個鏡像造成歷史
images List images #列出系統當前鏡像
import Import the contents from a tarball to create a filesystem image #導入一個鏡像
info Display system-wide information #顯示系統信息
inspect Return low-level information on Docker objects #查看容器詳細信息
kill Kill one or more running containers #kill指定docker容器
load Load an image from a tar archive or STDIN #從一個tar包中加載一個鏡像(對應save)
login Log in to a Docker registry #註冊或者登錄一個docker源服務器
logout Log out from a Docker registry #從當前Docker registry退出
logs Fetch the logs of a container #輸出當前容器日誌信息
pause Pause all processes within one or more containers #暫停容器
port List port mappings or a specific mapping for the container #查看映射端口對應的容器內部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #從docker鏡像源服務器拉取指定鏡像或者庫鏡像
push Push an image or a repository to a registry #推送指定鏡像或者庫鏡像至docker源服務器
rename Rename a container #重命名容器
restart Restart one or more containers #重啓運行的容器
rm Remove one or more containers #移除一個或者多個容器
rmi Remove one or more images #移除一個或者多個鏡像
run Run a command in a new container #建立一個新的容器並運行一個命令
save Save one or more images to a tar archive (streamed to STDOUT by default) 保存一個鏡像爲一個tar包(對應load)
search Search the Docker Hub for images #在docker hub中搜索鏡像
start Start one or more stopped containers #啓動容器
stats Display a live stream of container(s) resource usage statistics #統計容器使用資源
stop Stop one or more running containers #中止容器
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE #給源中鏡像打標籤
top Display the running processes of a container #查看容器中運行的進程信息
unpause Unpause all processes within one or more containers #取消暫停容器
update Update configuration of one or more containers #更新一個或多個容器的配置信息
version Show the Docker version information #查看容器版本號
wait Block until one or more containers stop, then print their exit codes #截取容器中止時的退出狀態值
Run 'docker COMMAND --help' for more information on a command. #運行docker命令在幫助能夠獲取更多信息
四、訪問Docker倉庫
4.一、解析Docker 倉庫
倉庫(Repository)是集中存放鏡像的地方。
一個容易混淆的的概念是註冊服務器(Registry
)。實際上註冊服務器是存放倉庫的具體服務器,每一個服務器上都有不少個倉庫,而每一個倉庫下面都有多個鏡像。從這方面來講,倉庫能夠認爲是一個具體的項目或目錄。例如對於倉庫地址dl.dockerpool.com/centos
來講,dl.dockerpool.com
是註冊服務器地址,centos
是倉庫名。
倉庫又分爲公有倉庫(public)和私有倉庫(private)github
4.二、建立和使用私有倉庫
使用registry鏡像來建立私有倉庫:docker pull registry
//以registry鏡像啓動容器,-p會把容器的端口映射到宿主機上,:左邊爲宿主機監聽端口,:右邊爲容器監聽端口web
[root@localhost ~]# docker run -d -p 5000:5000 registry #這裏將自動下載registry鏡像並啓動容器,建立本地私有倉庫。
Unable to find image 'registry:latest' locally
Trying to pull repository docker.io/library/registry ...
latest: Pulling from docker.io/library/registry
49388a8c9c86: Pull complete
e4d43608dd22: Pull complete
3a41740f900c: Pull complete
e16ef4b76684: Pull complete
65f212f7c778: Pull complete
Digest: sha256:d837de65fd9bdb81d74055f1dc9cc9154ad5d8d5328f42f57f273000c402c76d
c9bba59aa7ce072b888ca8214a76211bf03cf9d3bcb55d2183183b876683f33f
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9bba59aa7ce registry "/entrypoint.sh /etc/" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp sick_wozniak
默認的狀況下,會將倉庫建立在容器的/tmp/registry
目錄下,能夠經過-v參數來將鏡像文件存放在本地的指定路徑上。redis
[root@localhost ~]# mkdir -p /opt/data/registry
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx 1.10.1 def358072817 3 hours ago 106.7 MB
[root@localhost ~]# docker tag test/nginx:1.10.1 192.168.0.134:5000/test2 //標記一下tag,必須帶有私有倉庫的ip:port
[root@localhost ~]# docker push 192.168.0.134:5000/test2
Get https://192.168.0.165:5000/v2/: http: server gave HTTP response to HTTPS client
tips:因爲客戶端採用https,docker registry未採用https服務所致。<br/>處理方法:更改配置文件:/etc/docker/daemon.json
[root@localhost ~]# vim /etc/docker/daemon.json
{"insecure-registries":["192.168.0.134:5000"]}
修改完配置文件須要進行重啓docker
[root@localhost ~]# systemctl restart docker
docker重啓後,原先運行的容器會中止掉,須要從新開啓容器
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
[root@localhost ~]# docker push 192.168.0.134:5000/test2
The push refers to a repository [192.168.0.134:5000/test2]
c4c704007df5: Pushed
latest: digest: sha256:2fa255d11989458a1f9d3173e36a911c5f40c0ba1d74b16608a27ba52fa9237a size: 528
[root@localhost ~]# curl http://192.168.0.134:5000/v2/_catalog
{"repositories":["test2"]}
在第二臺機器(192.168.0.136)上進行驗證私有倉庫是否可用
[root@backup ~]# yum install -y docker
[root@backup ~]# systemctl start docker
[root@backup ~]# curl http://192.168.0.134:5000/v2/_catalog
{"repositories":["test2"]}
[root@backup ~]# docker pull 192.168.0.134:5000/test2
Using default tag: latest
Trying to pull repository 192.168.0.134:5000/test2 ...
Get https://192.168.0.165:5000/v1/_ping: http: server gave HTTP response to HTTPS client
出如今docker私有倉庫同樣的錯誤,因而一樣修改配置文件
[root@backup ~]# vim /etc/docker/daemon.json
{"insecure-registries":["192.168.0.134:5000"]}
[root@backup ~]# systemctl restart docker
[root@backup ~]# docker pull 192.168.0.134:5000/test2
Using default tag: latest
Trying to pull repository 192.168.0.134:5000/test2 ...
latest: Pulling from 192.168.0.134:5000/test2
9ff86f02c57e: Pull complete
Digest: sha256:2fa255d11989458a1f9d3173e36a911c5f40c0ba1d74b16608a27ba52fa9237a
[root@backup ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.165:5000/test2 latest def358072817 Less than a second ago 106.7 MB
小結:
倉庫概念的引入,爲Docker鏡像文件的分發和管理提供了便捷的途徑,在企業生產環境中,則每每須要使用私有倉庫來維護內部鏡像。
五、Docker數據管理
用戶在使用Docker的過程當中,每每須要能查看容器內應用產生的數據,或者須要把容器內的數據進行備份,甚至多個容器之間進行數據共享,這必然涉及到容器的數據管理操做。
容器中管理數據主要有兩種方式:
(1)數據卷(Data Volumes
)
(2)數據卷容器(Data Volumes Dontainers
)sql
5.一、數據卷
數據卷能夠是一個可供容器使用的特殊目錄。
a.
數據卷能夠在容器中共享和重用
b.
對數據卷修改會立馬生效
c.
對數據卷更新,不會影響鏡像
d.
卷會一直存在,直到沒有容器使用
數據卷的使用,相似於Linux下對目錄或文件進行mount操做
在容器內建立一個數據卷
在使用docker run
命令的時候,使用-v
標記能夠在容器內建立一個數據卷,屢次使用-v
標記,能夠建立多個數據卷。使用-v標記也能夠指定本地的已有的目錄到容器中做爲數據卷。也就是映射宿主機目錄到容器中去。這個功能在測試的時候十分方便,好比用戶能夠放置一些程序或數據到本地目錄,而後再容器中運行和使用。另外,本地目錄的路徑必須是絕對路徑,若是目錄不存在,Docker會自行建立。
Docker掛載數據卷的默認權限是rw
,用戶也能夠經過指定權限,ro
指定可讀:
docker run -itd -P --name web2 -v /data:/data:ro centos_nginx:1.10 bash
同時,也能夠掛載本地主機的一個文件做爲數據卷
docker run -it --rm -P --name web2 -v ~/.bash_history:/.bash_history centos_nginx:1.10 bash
5.二、掛載本地的目錄到容器裏
(1)查看本地鏡像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx 1.10 3cdab9e3fdbb 19 hours ago 361.6 MB
centos_nginx latest 3cdab9e3fdbb 19 hours ago 361.6 MB
(2)建立容器,並將本地/data目錄映射到容器中
[root@localhost ~]# docker run -itd -P --name web2 -v /data:/data centos_nginx:1.10 bash
52babe20009cb2366ebe0a9e3633140bcaa2d92e2057c56e47b8377960f43d62
//-v 用來指定掛載目錄,:前面的/data/爲宿主機本地目錄,:後面的/data/爲容器裏的目錄,會在容器中自動建立
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52babe20009c centos_nginx:1.10 "bash" 3 seconds ago Up 3 seconds 0.0.0.0:32771->80/tcp web2
(3)在數據卷目錄中建立目錄123
[root@localhost ~]# docker exec -it 52babe20009c bash
[root@52babe20009c /]# mkdir /data/123
[root@52babe20009c /]# ll /data/
total 24
drwxr-xr-x 2 root root 4096 Nov 12 07:06 123
drwxr-xr-x 5 1003 1003 4096 Sep 30 03:17 logs
drwxr-xr-x 8 1003 1003 4096 Oct 19 04:16 mysql
drwxr-xr-x 3 1003 1003 4096 Sep 30 03:18 nginx
drwxr-xr-x 2 1003 1003 4096 Oct 1 13:01 oldboy
drwxr-xr-x 2 1003 1003 4096 Sep 30 03:17 web
(4)宿主機查看目錄變化
[root@localhost ~]# ll /data/
total 24
drwxr-xr-x 2 root root 4096 Nov 12 02:06 123
drwxr-xr-x 5 mysql mysql 4096 Sep 29 23:17 logs
drwxr-xr-x 8 mysql mysql 4096 Oct 19 00:16 mysql
drwxr-xr-x 3 mysql mysql 4096 Sep 29 23:18 nginx
drwxr-xr-x 2 mysql mysql 4096 Oct 1 09:01 oldboy
drwxr-xr-x 2 mysql mysql 4096 Sep 29 23:17 web
5.三、數據卷容器
若是用戶須要在容器之間共享一些持續更新的數據,最簡單的方式是試用數據卷容器。數據卷容器其實就是一個普通的容器,專門用它來提供數據卷供其餘容器掛載使用。
(1)首先建立一個數據卷容器dbdata
,並在其中建立一個數據卷掛載到/dbdata
[root@localhost ~]# docker run -it -v /dbdata --name dbdata centos
tips:這裏的/dbdata是容器裏的/dbdata目錄,並不是宿主機本地的目錄
(2)查看/dbdata
目錄,並建立文件
[root@8ee4460dccae /]# ls
anaconda-post.log bin dbdata dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@8ee4460dccae /]# touch /dbdata/long.txt
[root@8ee4460dccae /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
[root@8ee4460dccae /]# exit
(3)經過--volumes-from
來掛載dbdata
容器中的數據卷,例如建立一個db1
容器,並從dbdata
容器掛載數據卷
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ee4460dccae centos "/bin/bash" 2 minutes ago Exited (0) About a minute ago dbdata
[root@localhost ~]# docker run -it --volumes-from dbdata --name db1 centos bash
(4)查看db1容器是否存在/dbdata
目錄,並在該目錄下建立long2.txt
文件
[root@ee0f12d8023b /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
[root@ee0f12d8023b /]# touch /dbdata/long2.txt
[root@ee0f12d8023b /]# exit
(5)進入dbdata
容器查看是否有long2.txt
[root@localhost ~]# docker exec -it 8ee4460dccae bash
[root@8ee4460dccae /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
(6)屢次使用--volumes-from
參數來從多個容器掛載多個數據卷
[root@localhost ~]# docker run -itd --name db5 --volumes-from db1 --volumes-from db4 centos bash
9513d4c30a85601b8d0939e4b58e24697df6417fb0b82a5eb5dfc42ed729cc7b
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9513d4c30a85 centos "bash" 5 seconds ago Up 3 seconds db5
72ae1898a04d centos "bash" 56 seconds ago Up 55 seconds db4
ee0f12d8023b centos "/bin/bash" 51 minutes ago Up 50 minutes db1
[root@localhost ~]# docker exec -it db5 bash
[root@9513d4c30a85 /]# ls
anaconda-post.log bin dbdata dbdata4 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
(7)還能夠從其餘已經掛載了容器卷的容器來掛載容器卷:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee0f12d8023b centos "/bin/bash" 47 minutes ago Up 46 minutes db1
8ee4460dccae centos "/bin/bash" 49 minutes ago Up 45 minutes dbdata
[root@localhost ~]# docker run -it --name db2 --volumes-from db1 centos bash
[root@701a34da1cde /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
tips:使用--volumes-from參數所掛載數據卷的容器自身並不須要保持在運行狀態,若是刪除了掛載的容器(包括dbdata,db1,db2),數據卷並不會被自動刪除,
若是要刪除一個數據卷,必須在刪除最後一個還掛載着它的容器時顯示使用docker rm -v 命令來指定刪除關聯的容器
(1)中止db4
容器並刪除
[root@localhost ~]# docker stop db4
db4
[root@localhost ~]# docker rm db4
db4
(2)進入db5
容器查看數據卷dbdata4
是否存在
[root@localhost ~]# docker exec -it db5 bash
[root@9513d4c30a85 /]# ls
anaconda-post.log bin dbdata dbdata4 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
5.四、利用數據卷容器遷移數據
能夠利用數據卷容器對其中的數據捲進行備份,恢復,以實現數據的遷移。
(1)備份
[root@localhost ~]# docker run --volumes-from dbdata -v /backup:/backup --name work centos tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/
/dbdata/long.txt
/dbdata/long2.txt
[root@localhost ~]# ll /backup/
-rw-r--r-- 1 root root 10240 Nov 12 03:30 backup.tar
說明:首先利用centos鏡像建立了一個容器work,使用--volumes-from dbdata參數來讓容器掛載dbdata容器的數據卷(即dbdata數據卷);
-v /backup:/backup參數來將本地的備份目錄(/backup)掛載到work容器的/backup目錄。work容器啓動後,使用了tar cvf /backup/backup.tar /dbdata命令來將/dbdata下的內容備份爲容器內的/backup/backup.tar,
即宿主機/backup目錄下的/backup/backup.tar
(2)恢復
[root@localhost ~]# docker run -itd -v /dbdata --name db6 centos bash
bb0357aba6fcee546eda5903f40cf61b3fd46a4ad9e0962e55550caaea10e06c
[root@localhost ~]# docker run --volumes-from db6 -v /backup:/backup --name db7 centos tar xvf /backup/backup.tar
dbdata/
dbdata/long.txt
dbdata/long2.txt
[root@localhost ~]# docker exec -it db6 bash
[root@bb0357aba6fc /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
說明:首先利用centos鏡像新建一個db6的容器,而後經過--volumes-from參數掛載db6容器的數據卷(/dbdata)新建容器,
並將本地的/backup目錄映射到db7容器中。然後對/backup/backup.tar進行解壓到/dbdata目錄下,從而實現db6恢復/dbdata數據
小結:
在生產環境中,在使用數據卷或者數據卷容器以外,按期將宿主機的本地數據進行備份,或者使用支持容錯的存儲系統,包括RAID或分佈式文件系統。
六、端口映射和容器互聯
6.一、端口映射,實現外部訪問
在啓動容器的時候,若是不指定對應的參數,在容器外部是沒法經過網絡進行訪問容器內的應用和服務的。當容器中運行一些網絡應用,要讓外部訪問這些應用,能夠經過-P
或-p
參數來指定端口映射。當使用-P標記時,Docker會隨機映射一個49000~49900
的端口至容器內部開放的網絡端口。
端口映射的方式:
(1)映射全部接口地址
使用hostPort:containerPort格式,將本地的5000端口映射到容器的5000端口,能夠執行如下命令:
docker run -d -p 5000:5000 centos_nginx bash
此時默認會綁定本地全部接口上的全部地址。屢次使用-p標記能夠綁定多個端口。例如:
docker run -d -p 5000:5000 -p 8082:80 centos_nginx bash
(2)映射到指定地址的指定端口
可使用ip:hostPort:containerPort格式指定映射一個特定的地址,例如localhost的地址127.0.0.1
docker run -d -p 127.0.0.1:5000:5000 centos_nginx bash
(3)映射到指定地址的任意端口
使用ip::containerPort綁定localhost的任意端口到容器的5000端口,本地主機會任意分配一個端口
docker run -d -p 127.0.1.1::5000 centos_nginx bash
(4)查看端口映射狀況
docker port container_name/container_id
演示:
(1)以centos_nginx鏡像啓動一個容器(web_nginx),並將宿主機8081端口進行映射
[root@localhost ~]# docker run -itd --name web_nginx -p 8081:80 centos_nginx bash
c558c2a986929f280e7b1db2c46c5951fa95670dfa54de1df83f8b0335241c3c
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c558c2a98692 centos_nginx "bash" 6 seconds ago Up 4 seconds 0.0.0.0:8081->80/tcp web_nginx
(2)進入容器,啓動nginx,發現Operation not permitted報錯
[root@localhost ~]# docker exec -it web_nginx bash
[root@c558c2a98692 /]# ps -ef |grep nginx
root 26 13 0 05:59 ? 00:00:00 grep --color=auto nginx
[root@c558c2a98692 /]# systemctl start nginx
Failed to get D-Bus connection: Operation not permitted
解決:
•新建的容器,啓動nginx或者httpd服務的時候會報錯
•Failed to get D-Bus connection: Operation not permitted
• 這是由於dbus-daemon沒有啓動,解決該問題能夠這樣作
• 啓動容器時,要加上--privileged -e "container=docker",而且最後面的命令改成/usr/sbin/init
docker run -itd --privileged -e "container=docker" centos_with_nginx /usr/sbin/init
可是若是直接使用nginx命令直接啓動,nginx也是能夠的。
(3)刪除容器,使用參數--privileged -e "container=docker",bash改成/usr/sbin/init從新啓動一個容器,並查看端口映射
[root@localhost ~]# docker rm -f web_nginx
web_nginx
[root@localhost ~]# docker run -itd --privileged -e "container=docker" --name web_nginx -p 8081:80 centos_nginx /usr/sbin/init
c57f0ef025b8b61ced5b39d6cf088f6258b536eecbe05868cb8adadf3610db44
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c57f0ef025b8 centos_nginx "/usr/sbin/init" 7 seconds ago Up 6 seconds 0.0.0.0:8081->80/tcp web_nginx
(4)啓動nginx,並寫入網頁內容,查看是否實現端口映射
[root@localhost ~]# docker exec -it web_nginx bash
[root@c57f0ef025b8 /]# ps -ef |grep nginx
root 75 63 0 06:03 ? 00:00:00 grep --color=auto nginx
[root@c57f0ef025b8 /]# systemctl start nginx
[root@c57f0ef025b8 /]# ps -ef |grep nginx
root 82 1 0 06:03 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 83 82 0 06:03 ? 00:00:00 nginx: worker process
root 85 63 0 06:03 ? 00:00:00 grep --color=auto nginx
[root@c57f0ef025b8 /]# cp /usr/share/nginx/html/index.html{,.bak}
[root@c57f0ef025b8 /]# echo "<h1> www.deng.com </h1>" > /usr/share/nginx/html/index.html
七、使用Dokcerfile建立鏡像
7.一、Dockerfile基本結構
Dockerfile
是爲了快速構建鏡像
Dockerfile
由一行行命令語句組成,而且支持以#開頭的註釋行。
通常而言,Dockerfile
分爲4個部分:
基礎鏡像信息<br/>維護者信息<br/>鏡像操做指令<br/>容器啓動時執行指令
示例:
#This dockerfile uses the centos image
#VERSION 1
#Author:docker_user
#Command format:Instruction [arguments / command] ..
#第一行必須制定基於的基礎鏡像
FROM centos
#維護者信息
MAINTAINER docker_user docker_user@email.com
#鏡像的操做指令
RUN echo "hello world"
RUN yum update && yum install -y net-tools
RUN yum install -y nginx
#容器啓動時執行指令
CMD /usr/sbin/nginx
其中,一開始必須指明所基於的鏡像名稱,接下來通常會說明維護者信息。
後面則是鏡像操做指令,例如RUN
指令,RUN
指令將對鏡像執行跟隨的命令。每運行一條RUN
指令,鏡像添加新的一層,並提交。最後是CMD
指令,來指定運行容器時操做的命令。
7.二、Dockerfile指令
指令的通常格式爲INSTRUCTION arguments
(1)FROM
指定所建立鏡像的基礎鏡像,若是本地不存在,則默認會去Docker Hub下載指定鏡像。
格式:FROM <image>或 FROM <image>:<tag>
任何Dockerfile中的第一條指令必須爲FROM指令。而且在同一個Dockerfile中建立多個鏡像時,可使用多個FROM指令(每一個鏡像一次)
(2)MAINTAINER
格式:MAINTAINER <name>,指定維護者信息
該信息會寫入生成鏡像的Author屬性域中
(3)RUN
運行指定命令。
格式:RUN <command>或RUN ["executable","param1","param2"]。注意,後一個指令會被解析爲Json數組,所以必須用雙引號。
前者默認將在shell終端運行命令,即/bin/sh -c;後者則使用exec執行,不會啓動shell環境。
好比:RUN yum install httpd
RUN ["/bin/bash","-c","echo hello"]
每條RUN指令將在當前鏡像基礎上執行指定命令,並提交爲新鏡像。當命令過長時,可使用\來換行。
(4)CMD
CMD指令用來指定啓動容器時默認執行的命令。
支持3種格式:
•CMD ["executable", "param1", "param2"]<br/>•CMD command param1 param2<br/>•CMD ["param1", "param2"]
RUN和CMD看起來很像,可是CMD用來指定容器啓動時用到的命令,只能有一條。若是指定了多條命令,只有最後一條會被執行。若是用戶啓動容器時,指定了運行命令,則會覆蓋掉CMD指定的命令。
好比:CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
(5)EXPOSE
聲明鏡像內服務所監聽的端口
格式:EXPOSE <port> [<port>...]
好比:EXPOSE 22 80 443
告訴Docker服務端容器暴露的端口號,供互聯繫統使用。在啓動容器時須要經過-P,Docker主機會自動分配一個端口轉發到指定端口;使用-p,則能夠具體指定哪一個本地端口映射過來。
(6)ENV
格式:ENV <key> <value>或ENV <key>=<value>,指定一個環境變量,會被後續RUN指令使用,在鏡像啓動的容器中也會存在。
好比:ENV PATH /usr/local/mysql/bin:$PATH
(7)ADD
格式:ADD <src> <dest>
將本地的一個文件或目錄拷貝到容器的某個目錄裏。其中<src>爲Dockerfile所在目錄的相對路徑,它也能夠是一個URL;若是爲tar文件,會自動解壓到<dest>路徑下。<dest>能夠是鏡像內的絕對路徑,或者相對於工做目錄(WORKDIR)的相對路徑。
• ADD <conf/vhosts> </usr/local/nginx/conf>
(8)COPY
格式:COPY <src> <dest>
複製本地主機的<src>(爲Dockerfile所在目錄的相對路徑,文件或目錄)爲容器中的<dest>。目錄路徑不存在時,會自動建立。當使用本地目錄爲源目錄時,推薦使用COPY。
(9)ENTRYPOINT
指定鏡像的默認入口命令,該入口命令在啓動容器時做爲根命令執行,全部傳入值做爲該命令的參數
兩種格式:
ENTRYPOINT ["executable", "param1", "param2"] (exec調用執行)<br/>ENTRYPOINT command param1 param2 (shell中執行)
此時,CMD指令指定值將做爲根命令的參數
配置容器啓動後執行的命令,而且不可被docker run 提供的參數覆蓋,每一個Dockerfile中只能有一個ENTRYPOINT,當指定多個ENTRYPOINT時,只有最後一個生效。
在運行時,能夠被--entrypoint參數覆蓋掉,如docker run --entrypoint
•咱們在Dockerfile中指定以下CMD:
• CMD ["/bin/echo", "test"]
• 啓動容器的命令是 docker run aming這樣會輸出test
• 假如啓動容器的命令是 docker run -it aming /bin/bash 什麼都不會輸出
• ENTRYPOINT不會被覆蓋,並且會比CMD或者docker run指定的命令要靠前執行
• ENTRYPOINT ["echo", "test"]
• docker run -it aming 123
• 則會輸出 test 123,這至關於要執行命令 echo test 123
(10)VOLUME
建立一個數據卷掛載點
格式:VOLUME ["/data"]
建立一個能夠從本地主機或其餘容器掛載的掛載點,通常用於存放數據庫和須要保持的數據等。
(11)USER
格式:USER daemon
指定運行容器時的用戶名或UID,後續的RUN也會指定用戶。
當服務不須要管理員權限時,能夠經過該指令指定運行的用戶。而且能夠在以前建立所須要的用戶。例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres。要臨時獲取管理員權限可使用gosu,而不推薦sudo
(12)WORKDIR
格式:WORKDIR /path/to/workdir
爲後續的RUN,CMD,ENTRYPOINT指令配置工做目錄。可使用多個WORKDIR指令,後續命令若是參數是相對路徑,則會基於以前命令指定的路徑。例如:
WORKDIR /a<br/>WORKDIR b<br/>WORKDIR c<br/>RUN pwd
則最終路徑爲:/a/b/c
(13)ARG
指定一些鏡像內使用的參數(例如版本號信息等),這些參數在執行docker build命令時,才以--build-arg<varname>=<value>格式傳入
格式:ARG<name>[=<default value>]
則能夠用docker build --build-arg<name>=<value>.來指定參數值
(14)ONBUILD
配置當所建立的鏡像做爲其餘鏡像的基礎鏡像時,所執行的建立操做指令。
格式:ONBUILD [INSTRUCTION]
例如,Dockerfile使用以下的內容建立了鏡像image-A:
[...]<br/>ONBUILD ADD . /app/src<br/>ONBUILD RUN /usr/local/bin/python-build --dir /app/src<br/>[...]
若是基於image-A建立新的鏡像時,新的Dockerfile中使用FROM image-A指定基礎鏡像,會自動執行ONBUILD指令的內容
(15)STOPSIGNAL
指定所建立鏡像啓動的容器接收退出的信號值。例如:
STOPSIGNAL signal
(16)HEALTHCHECK
配置所啓動容器如何進行健康檢查(如何判斷健康與否),自docker 1.12開始支持
格式有兩種:
HEALTHCHECK [OPTIONS] CMD command:根據所執行命令返回值是否爲0來判斷;
HEALTHCHECK NONE:禁止基礎鏡像中的健康檢查。
OPTION支持:
①--interval=DURATION(默認爲:30s):過多久檢查一次;
②--timeout=DURATION(默認爲:30s):每次檢查等待結果的超時;
③--retries=N(默認爲:3):若是失敗了,重試幾回才最終肯定失敗。
(17)SHELL
指定其餘命令使用shell時的默認shell類型
SHELL ["executable","parameters"]
默認值爲["/bin/sh","-c"]
7.三、建立鏡像
編寫完Dockerfile以後,能夠經過docker build命令來建立鏡像。
格式:docker build [選項] 內容路徑
該命令將讀取指定路徑下(包括子目錄)的Dockerfile,並將該路徑下的全部內容發送給Docker服務端,有服務端來建立鏡像。所以除非生成鏡像須要,不然通常建議放置Dockerfile的目錄爲空目錄,可使用-f選項來指定其路徑。
①若是使用非內容路徑下的Dockerfile,能夠經過-f選項來指定其路徑
②要指定生成鏡像的標籤信息,可使用-t選項
例如:指定的Dockerfile所在路徑爲/tmp/docker_builder/,而且但願生成的鏡像標籤爲build_repo/frist_image,可使用:
docker build -t build_repo/first_image /tmp/docker_builder/
7.四、Dockerfile建立鏡像示例(nginx)
(1)編輯Dockerfile文件
[root@localhost ~]# vim Dockerfile
FROM centos
MAINTAINER long 442305405@qq.com
RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
ADD http://nginx.org/download/nginx-1.12.2.tar.gz .
RUN tar zxvf nginx-1.12.2.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd nginx-1.12.2 && ./configure --prefix=/usr/local/nginx && make && make install
RUN rm -fv /usr/local/nginx/conf/nginx.conf
ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf
ADD index.html /usr/local/nginx/html/index.html
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
EXPOSE 80
ENTRYPOINT /usr/local/nginx/sbin/nginx
(2)建立鏡像
[root@localhost ~]# docker build -t centos_nginx:1.12.2 .
Sending build context to Docker daemon 212.7 MB
Step 1 : FROM centos
---> d123f4e55e12
Step 2 : MAINTAINER long 442305405@qq.com
---> Using cache
---> 42a2766d5cce
Step 3 : RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
---> Running in ebd2bc43b045
Loaded plugins: fastestmirror, ovl
......
Step 8 : RUN rm -fv /usr/local/nginx/conf/nginx.conf
---> Running in eb41c1c7b39d
removed '/usr/local/nginx/conf/nginx.conf'
---> d6b0d765ca2e
Removing intermediate container eb41c1c7b39d
Step 9 : ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf
Downloading [==================================================>] 1.678 kB/1.678 kB
---> efffda0c218d
Removing intermediate container af06898e74f4
Step 10 : EXPOSE 80
---> Running in fb3905caf714
---> 6efacb9d8a12
Removing intermediate container fb3905caf714
Step 11 : ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd
---> Running in 61b617e30d2b
---> 02447e813325
Removing intermediate container 61b617e30d2b
Successfully built 02447e813325
(3)查看建立的鏡像,並經過建立的鏡像建立容器
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx 1.12.2 02447e813325 About a minute ago 350 MB
[root@localhost ~]# docker run -itd centos_nginx:1.12.2 bash
10fa28dc417e0023004f857f72537e232a63b2977fda3228a77688d33b0d7803
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
10fa28dc417e centos_nginx:1.12.2 "/bin/sh -c '/usr/loc" 3 seconds ago Up 3 seconds 80/tcp gigantic_agnesi
(4)進入容器查看nginx運行情況
[root@localhost ~]# docker exec -it gigantic_agnesi bash
[root@10fa28dc417e /]# ps -ef |grep nginx
root 1 0 0 06:37 ? 00:00:00 /bin/sh -c /usr/local/nginx/sbin/nginx
root 6 1 0 06:37 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody 7 6 0 06:37 ? 00:00:00 nginx: worker process
nobody 8 6 0 06:37 ? 00:00:00 nginx: worker process
root 24 10 0 06:38 ? 00:00:00 grep --color=auto nginx
7.5.遇到的問題
因爲以前使用過pipework進行配置橋接網絡,須要更改網絡,並開啓IPv4轉發
[root@localhost ~]# docker run -itd --name test centos_nginx bash
WARNING IPv4 forwarding is disabled. Networking will not work
a93d14f536d31b3edfd847f12c8e1115bb75bc2b202fb44f761c2e14c2018a6b
解決:
# vi /etc/sysctl.conf
或者
# vi /usr/lib/sysctl.d/00-system.conf
添加以下代碼:
net.ipv4.ip_forward=1
重啓network服務
# systemctl restart network
查看是否修改爲功
# sysctl net.ipv4.ip_forward
#################################################################################
Docker 安裝時會自動在host
上建立三個網絡,咱們可用 docker network ls
命令查看:
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0164da7ee66a bridge bridge local
a4a5d0b84564 host host local
df2c5c066a6a none null local
一、host模式
host模式,使用docker run
時,使用--net=host
指定docker
使用的網絡實際上和宿主機同樣,啓動容器的時候使用host
模式,那麼這個容器將不會得到一個獨立的Network Namespace
,而是和宿主機共用一個Network Namespace
。容器將不會虛擬出本身的網卡,配置本身的IP
等,而是使用宿主機的IP
和端口。可是,容器的其餘方面,如文件系統、進程列表等仍是和宿主機隔離的。
演示:
[root@localhost ~]# docker run -it --rm --net=host --name net1 centos_1 bash
[root@localhost /]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:5aff:fe52:25a9 prefixlen 64 scopeid 0x20<link>
ether 02:42:5a:52:25:a9 txqueuelen 0 (Ethernet)
RX packets 32541 bytes 45836190 (43.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 45025 bytes 305790826 (291.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::71bd:4770:36ed:a5df prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 690783 bytes 269935255 (257.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 164584 bytes 86989110 (82.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 5206 bytes 265735 (259.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5206 bytes 265735 (259.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

二、container模式
container
模式,使用--net=container:container_id/container_name
多個容器使用共同的網絡,這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace
,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的IP
,而是和一個指定的容器共享 IP
、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過lo
網卡設備通訊。
演示:
①建立一個net2的容器,並查看ip爲172.17.0.2
[root@localhost ~]# docker run -itd --name net2 centos_1 bash
b8a14e5e8a670d5680aae830f79267257143397c124d011fbf09b71c59b37e5d
[root@localhost ~]# docker exec -it net2 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
②建立容器net3,並指定使用container網絡模式,查看net3容器的ip爲:172.17.0.2
[root@localhost ~]# docker run -it --net=container:net2 --name net3 centos_1 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
③查看運行的net2,net3容器,二者id並不相同,但使用container網絡模式,進入到net3時,net3容器id會和net2相同
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a795f6825e1e centos_1 "bash" 6 minutes ago Up 3 seconds net3
b8a14e5e8a67 centos_1 "bash" 8 minutes ago Up 8 minutes net2
[root@localhost ~]# docker exec -it net3 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

三、none模式
non
e模式,使用--net=none
指定這種模式下,不會配置任何網絡。使用none
模式,Docker
容器擁有本身的Network Namespace
,可是,並不爲Docker
容器進行任何網絡配置。也就是說,這個Docker
容器沒有網卡、IP、路由
等信息。須要咱們本身爲Docker
容器添加網卡、配置IP等。
演示:
[root@localhost ~]# docker run -it --net=none --name net4 centos_1 bash
[root@b12e7ad03af2 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
四、bridge模式
bridge
模式,使用--net=bridge
指定默認模式,當Docker
進程啓動時,會在主機上建立一個名爲docker0
的虛擬網橋,此主機上啓動的Docker
容器會鏈接到這個虛擬網橋上。虛擬網橋的工做方式和物理交換機相似,這樣主機上的全部容器就經過交換機連在了一個二層網絡中。
從docker0
子網中分配一個IP
給容器使用,並設置docker0
的IP地址爲容器的默認網關。在主機上建立一對虛擬網卡veth pair
設備,Docker
將veth pair
設備的一端放在新建立的容器中,並命名爲eth0
(容器的網卡),另外一端放在主機中,以vethxxx
這樣相似的名字命名,並將這個網絡設備加入到docker0
網橋中。能夠經過brctl show
命令查看。
bridge
模式是docker的默認網絡模式,不寫--net
參數,就是bridge
模式。使用docker run -p
時,docker
實際是在iptables
作了DNAT規則,實現端口轉發功能。可使用iptables -t nat -vnL
查看。
演示:
①查看宿主機docker0的虛擬網橋ip爲:172.17.0.1
[root@localhost ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:5aff:fe52:25a9 prefixlen 64 scopeid 0x20<link>
ether 02:42:5a:52:25:a9 txqueuelen 0 (Ethernet)
RX packets 32557 bytes 45837262 (43.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 45025 bytes 305790826 (291.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::71bd:4770:36ed:a5df prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 702882 bytes 271309720 (258.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 166364 bytes 87203641 (83.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
②建立net5容器,並使用bridge網絡模式。查看ip和網關
[root@localhost ~]# docker run -it --name net5 --net=bridge centos_1 bash
[root@a3a6416d08c0 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 6 bytes 508 (508.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6 bytes 508 (508.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@a3a6416d08c0 /]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0

五、如何自定義docker網絡?
咱們可經過bridge
驅動建立相似前面默認的bridge
網絡,例如:
[root@localhost ~]# docker network create --driver bridge my_net #建立橋接網絡my_net
afb854fd239b26f95265002190f9df88f8b7f66c204085bfd16c6a2b4932f5d9
[root@localhost ~]# brctl show 查看一下當前 host 的網絡結構變化
bridge name bridge id STP enabled interfaces
br-afb854fd239b 8000.02422702f1bc no
docker0 8000.0242646f882f no veth211fb49
veth709c331
veth8069764
vethfa120d8
增了一個網橋 br-afb854fd239b,這裏 br-afb854fd239b 正好新建 bridge 網絡 my_net 的短 id。執行 docker network inspect 查看一下 my_net 的配置信息:
[root@localhost ~]# docker network inspect my_net
[
{
"Name": "my_net",
"Id": "afb854fd239b26f95265002190f9df88f8b7f66c204085bfd16c6a2b4932f5d9",
"Created": "2018-04-21T14:14:15.479906429+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16", #這裏 172.18.0.0/16 是 Docker 自動分配的 IP 網段。
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
指定 --subnet
和--gateway
參數自定義ip
網段:
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.100.0/24 --gateway 192.168.100.1 my_net2
889ba4ceb97290e440db559e104db2bf9273854fd789322aaea30b3c76937af6
[root@localhost ~]# docker network inspect my_net2
[
{
"Name": "my_net2",
"Id": "889ba4ceb97290e440db559e104db2bf9273854fd789322aaea30b3c76937af6",
"Created": "2018-04-21T14:19:15.730480499+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.100.0/24",
"Gateway": "192.168.100.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
建立了新的 bridge 網絡 my_net2,網段爲 192.168.100.0/24,網關爲 192.168.100.1。與前面同樣,網關在 my_net2 對應的網橋 br-889ba4ceb972 上:
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br-889ba4ceb972 8000.02424b2256df no
br-afb854fd239b 8000.02422702f1bc no
docker0 8000.0242646f882f no veth211fb49
veth709c331
veth8069764
vethfa120d8
[root@localhost ~]# ifconfig br-889ba4ceb972
br-889ba4ceb972: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.100.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 02:42:4b:22:56:df txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器要使用新的網絡,須要在啓動時經過 --network
指定,而且還可使用--ip
參數直接指定一個靜態ip
:
[root@localhost ~]# docker run -it --network=my_net2 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
116: eth0@if117: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 scope global eth0 ##容器被分配的ip爲192.168.100.2
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:6402/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# docker run -it --network=my_net2 --ip 192.168.100.100 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
118: eth0@if119: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:64:64 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.100/24 scope global eth0 ##容器被分配的ip爲192.168.100.100
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:6464/64 scope link
valid_lft forever preferred_lft forever
注:只有使用 --subnet 建立的網絡才能指定靜態 IP。
my_net 建立時沒有指定 --subnet,若是指定靜態 IP 報錯以下:
[root@localhost ~]# docker run -it --rm --network=my_net --ip 172.18.0.100 busybox
/usr/bin/docker-current: Error response from daemon: User specified IP address is supported only when connecting to networks with user configured subnets.
六、Docker使用pipework配置容器與宿主機在同一網段
爲了使本地網絡中的機器和Docker
容器更方便的通訊,咱們常常會有將Docker
容器配置到和主機同一網段的需求。這個需求其實很容易實現,咱們只要將Docker
容器和宿主機的網卡橋接起來,再給Docker
容器配上IP
就能夠了。
(1)新建橋接網卡br0,並進行修改宿主機網卡enp0s3以及br0
[root@localhost network-scripts]# cp ifcfg-enp0s3 ifcfg-br0
[root@localhost network-scripts]# vim ifcfg-br0
注:修改TYPE=Bridge,DEVICE=br0,NAME=br0
TYPE=Bridge
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=br0
#UUID=faa61166-b507-4992-b055-2c6284de3981
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.0.165
GATEWAY=192.168.0.1
NATMASK=255.255.255.0
DNS1=8.8.8.8
#NM_CONTROLLED=no
[root@localhost network-scripts]# vim ifcfg-enp0s3
注:增長BRIDGE=br0,刪除IPADDR,GATEWAY,NETMASK,DNS
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3
#UUID=faa61166-b507-4992-b055-2c6284de3981
DEVICE=enp0s3
ONBOOT=yes
#IPADDR=192.168.0.165
#GATEWAY=192.168.0.1
#NATMASK=255.255.255.0
#DNS1=8.8.8.8
#NM_CONTROLLED=no
BRIDGE=br0
(2)重啓網絡,查看br0的ip地址,以及enp0s3是否未分配ip地址,表示成功
[root@localhost network-scripts]# systemctl restart network
[root@localhost network-scripts]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::ca01:a411:fb77:c348 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 36 bytes 3485 (3.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25 bytes 2318 (2.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:7e:ec:e1:e6 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 2831 bytes 321711 (314.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1070 bytes 182494 (178.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 96 bytes 7888 (7.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 96 bytes 7888 (7.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(3)下載pipework
[root@localhost ~]# git clone https://github.com/jpetazzo/pipework
Cloning into 'pipework'...
remote: Counting objects: 501, done.
remote: Total 501 (delta 0), reused 0 (delta 0), pack-reused 501
Receiving objects: 100% (501/501), 172.97 KiB | 4.00 KiB/s, done.
Resolving deltas: 100% (264/264), done.
(4)拷貝pipework二進制文件到/usr/local/bin下,運行一個容器並使用none網絡模式
[root@localhost ~]# cp pipework/pipework /usr/local/bin/
[root@localhost ~]# docker run -itd --net=none --name pipework centos_nginx bash
ab88e2159ce32408154a776c1c62cf1af170fa8ce4d01908da6175f01b6c787d
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab88e2159ce3 centos_nginx "bash" 4 seconds ago Up 4 seconds pipework
[root@localhost ~]# docker exec -it pipework bash
[root@ab88e2159ce3 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@ab88e2159ce3 /]# exit
exit
(5)使用pipework進行配置容器pipework的ip地址,166爲容器的ip地址,@後面的ip爲容器網關,配置完畢進入容器進行查看
[root@localhost ~]# pipework br0 pipework 192.168.0.166/24@192.168.0.1
[root@localhost ~]# docker exec -it pipework bash
[root@ab88e2159ce3 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.166 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::340c:ebff:fe50:1ba3 prefixlen 64 scopeid 0x20<link>
ether 36:0c:eb:50:1b:a3 txqueuelen 1000 (Ethernet)
RX packets 62 bytes 10518 (10.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 732 (732.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(6)windows和linux下驗證容器pipework的網絡連通性
[root@ab88e2159ce3 /]# ping www.baidu.com
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data.
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=54 time=8.29 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=54 time=8.09 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=54 time=8.43 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=4 ttl=54 time=8.12 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=5 ttl=54 time=8.80 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=6 ttl=54 time=8.51 ms
^C
--- www.a.shifen.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
rtt min/avg/max/mdev = 8.094/8.378/8.805/0.249 ms
(7)經過pipework配置網絡,配置web服務
[root@localhost ~]# docker run -itd --privileged -e "container=docker" --name pipework --net=none centos_nginx /usr/sbin/init
aa85a59dc347633fcd9a2b5206eaed619451c52f299d2505c32df2b6d1ce7521
[root@localhost ~]# pipework br0 pipework 192.168.0.166/24@192.168.0.1
[root@localhost ~]# docker exec -it pipework bash
[root@aa85a59dc347 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.166 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::a00d:aff:fec2:a59d prefixlen 64 scopeid 0x20<link>
ether a2:0d:0a:c2:a5:9d txqueuelen 1000 (Ethernet)
RX packets 192 bytes 21152 (20.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 774 (774.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@aa85a59dc347 /]# systemctl start nginx
[root@aa85a59dc347 /]# netstat -tulnp |grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 86/nginx: master pr
tcp6 0 0 :::80 :::* LISTEN 86/nginx: master pr
[root@aa85a59dc347 /]# ps -ef |grep nginx
root 86 1 0 07:54 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 87 86 0 07:54 ? 00:00:00 nginx: worker process
root 98 68 0 07:54 ? 00:00:00 grep --color=auto nginx
一、docker-compose的簡介
docker-compose
做爲dokcer
的官方編排工具,它可讓用戶經過編寫一個簡單的模板文件,快速地建立和管理基於docker
容器的應用集羣。實現對docker
容器集羣的快速編排。咱們知道Dockerfile
模板文件,可讓用戶很方便地定義一個單獨的應用容器。然而在平常工做中,常常會遇到須要多個容器相互配合來完成某項任務的狀況。例如要實現一個web項目,除了web
服務器容器自己,每每還須要加上後端的數據庫服務容器,甚至還包括負載均衡容器等。
而Compose正好能夠知足這樣的需求,它容許用戶經過一個單獨的docker-compose.yml
模板文件(YAML格式
)來定義一組相關聯的應用容器做爲一個項目(project
)
Compose中有2個重要的概念:
(1)服務(service):一個應用的容器,實際上能夠包含若干運行相同鏡像的容器實例。
(2)項目(project):由一組關聯的應用容器組成的一個完成業務單元,在docker-compose.yml文件中定義。
二、docker-compose安裝
Compose
項目是用Python
語言編寫的,因此compose
能夠經過python
的pip
工具進行安裝。安裝過程以下:
[root@localhost ~]# yum install -y python-pip
[root@localhost ~]# pip install -U docker-compose
[root@localhost ~]# docker-compose version
docker-compose version 1.21.0, build 5920eb0
docker-py version: 3.2.1
CPython version: 2.7.5
OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
三、Compose命令
對於Compose
來講,大部分命令的對象既能夠是項目自己,也能夠指定爲項目中的服務或容器。若是沒有特別說明,命令對象將是項目,這意味着項目中全部的服務都會受到命令的影響。docker-compose
命令的基本使用格式以下:
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE 指定使用的Compose模板文件,默認爲docker-compose.yml,可屢次指定;
-p, --project-name NAME 指定項目名稱,默認將使用所在目錄名稱做爲項目名 ;
--verbose 輸出更多調試信息;
-v, --version 打印版本信息;
Commands:
build 構建項目中的服務容器
help 得到一個命令的幫助
images 列出全部鏡像
kill 經過發送SIGKILL信號來強制中止服務容器
logs 查看服務器容器的輸出
pause 暫停一個服務容器
port 打印某個容器的端口所映射的公共端口
ps 列出項目中目前的全部容器
pull 拉取服務依賴的鏡像
push 推送服務依賴的鏡像
restart 重啓項目中的服務
rm 刪除全部的服務器容器(中止狀態中的)
run 在指定服務上執行一個命令
scale 設置指定服務運行的容器個數
start 啓動已經存在的服務容器
stop 中止已經處於運行狀態的容器,但不刪除它
top 展現運行的進程
unpause 恢復處於暫停狀態中的服務
up 自動完成包括構建鏡像、建立服務、啓動服務並關聯服務相關容器的一系列操做
version 打印docker-compose的版本信息
四、Compose模板文件
模板文件是使用Compose
的核心,設計的指令關鍵字也有不少,默認的模板文件名稱爲docker-compose.yml
,格式爲YAML
格式。舉例:
version: "2"
service:
webapp:
image: examplses/web
ports:
- "80:80"
volumes:
- "/data"
注意,每一個服務都必須經過image
指定鏡像或build
命令(須要Dockerfile
)等來自動構建生成鏡像。若是使用build
指令,在Dockerfile
中設置的選項(例如:CMD、EXPOSE、VOLUME、ENV
等)將會自動被獲取,無需在docker-compose.yml
中再次設置。如下爲模板的主要指令和功能:
(1)build指令
指定Dockerfile
所在文件夾的路徑(能夠是絕對路勁,或相對docker-compose.yml
文件的路徑。)Compose
將會利用它自動構建這個鏡像,而後使用這個鏡像:
build: /path/to/build/dir
(2)cap_add,cap_drop
指定容器的內核能力(capacity
)分配。例如,讓容器擁有全部能力能夠指定爲:
去掉NET_ADMIN
能力能夠指定爲:
(3)command
覆蓋容器啓動後默認執行的命令:
command: echo "hello world"
(4)cgroup_parent
指定父cgroup組,意味着將繼承該組的資源限制,例如,建立了一個cgroup
組爲cgroups_1
:
(5)container_name
指定容器名稱。默認將會使用「項目名稱_服務名稱_序號」這樣的格式。例如:
container_name: docker-web-container
指定容器名稱後,該服務將沒法進行擴展,由於Docker不容許多個容器具備相同的名稱。
(6)devices
指定設備映射關係,例如:
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
(7)dns
自定義DNS服務器。能夠是一個值,也能夠是一個列表,例如:
dns: 8.8.8.8
dns:
- 8.8.8.8
- 114.114.114.114
(8)dns_search
配置DNS搜索域。能夠是一個值,也能夠是一個列表,例如:
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
(9)dockerfile
若是須要,指定額外的編譯鏡像的Dockerfile文件,能夠經過該指令來指定,例如:
該指令不能和image一塊兒使用,不然Compose不知道根據哪一個指令來生成最終的服務鏡像。
dockerfile: Dockerfile-alternate
(10)env_file
從文件中獲取環境變量,能夠爲單獨的文件路徑或列表。
若是經過docker-compose -f FILE的方式來指定Compose模板文件,則env_file中變量的路徑會基於模板文件路徑,若是有變量名稱和environment指令衝突,則按照慣例,之後者爲準:
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- ./opt/secrets.env
環境變量文件中每一行都必須符合格式,支持#開頭的註釋行:
(11)environment
設置環境變量,可使用數組或字典兩種格式。只給定名稱的變量會自動獲取運行Compose主機上對應變量的值,能夠用來防止泄露沒必要要的數據。例如:
environment:
RACK_ENV: development
SESSION_SECRET
或者:
environment:
- RACK_ENV=development
- SESSION_SECRET
(12)expose
暴露端口,但不映射到宿主機,只容許能被連接的服務訪問。僅能夠指定內部端口爲參數,以下所示:
expose:
- "3000"
- "8000"
(13)extends
基於其餘模板文件進行擴展。例如咱們已經有了一個webapp服務,定義一個基礎模板文件爲common.yml,以下所示:
# common.yml
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
再編寫一個新的development.yml文件,使用common.yml中的webapp服務進行擴展:
#development.yml
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
development.yml會自動繼承common.yml中的webapp服務及環境變量定義。使用extends須要注意如下幾點:
1.避免出現循環依賴,如A依賴B,B依賴C,C依賴A
2.extends不會繼承links和volume_from中定義的容器和數據卷資源。
通常狀況下,推薦在基礎模板中只定義一些能夠共享的鏡像和環境變量,在擴展模板中具體指定應用變量、連接、數據卷等信息。
(14)external_links
連接到docker-compose.yml外部的容器,甚至能夠是非Compose管理的外部容器。參數格式和links相似
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
相似於Docker中的–add-host參數,指定額外的host名稱映射信息,例如:
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
會在啓動後的服務容器中/etc/hosts文件中添加如下2個條目:
8.8.8.8 googledns
52.1.157.61 dockerhub
(16)image
指定爲鏡像名稱或鏡像ID,若是鏡像在本地不存在,Compose將會嘗試拉取這個鏡像。
image: centos
image: nginx
(17)labels
爲容器添加Docker元數據(metadata)信息。例如,能夠爲容器添加輔助說明信息:
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com,startupteam.release: "rc3 for v1.0"
(18)links
連接到其餘服務中的容器。使用服務名稱(同時做爲別名),或者」服務名稱:服務別名」(如SERVICE:ALIAS),這樣的格式均可以,例如:
links:
- db
- db:database
- redis
使用的別名會將自動在服務容器中的/etc/hosts裏建立。例如:
172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis
所鏈接容器中相應的環境變量也將建立
(19)log_driver
相似於Docker中的–log-driver參數,指定日誌驅動類型。目前支持三種日誌驅動類型:
log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"
(20)log_opt
日誌驅動的相關參數。例如:
log_driver: "syslog"
log_opt:
syslog-address: "tcp://192.168.0.42:123"
(21)net
設置網絡模式。參數相似於docker client的–net參數
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
(22)pid
跟主機系統共享進程命名空間。打開該選項的容器之間,以及容器和宿主機系統之間能夠經過進程ID來相互訪問和操做:
(23)ports
暴露端口信息。使用」宿主:容器「的格式,或者僅僅指定容器的端口(宿主機會隨機選擇端口):
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8081:8081"
當使用"HOST:CONTAINER"格式來映射端口時,若是你使用的容器端口小於60而且沒有放到引號裏,可能會獲得錯誤結果,由於YAML會自動解析xx:yy這種數字格式爲60進制。爲了不這種問題的出現,建議數字串都用引號包括起來的字符串格式。
(24)security_opt
指定容器模板標籤(label)機制的默認屬性(用戶、角色、類型、級別等)。例如,配置標籤的用戶名和角色名:
security_opt:
- label:user:USER
- label:role:ROLE
(25)ulimits
指定容器的ulimits限制值,例如,指定最大進程數爲65535,指定文件句柄數位20000(軟限制,應用能夠隨時修改,不能超過硬限制,只能root用戶提升)。
ulimits:
nproc:65535
nofile:
soft:20000
hard:40000
(26)volumes
數據卷所掛載的路徑設置。能夠設置宿主機路徑(HOST:CONTAINER)或加上訪問模式(HOST:CONTAINER:ro)。該指令中路徑支持相對路徑。例如:
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
(27)volumes_driver
較新版本的Docker支持數據卷的插件驅動。用戶能夠先使用第三方驅動建立一個數據卷,而後使用名稱來訪問它。此時,能夠經過volumes_driver來指定驅動:
(28)volumes_from
從另外一個服務或容器掛載它的數據卷:
volumes_from:
- service_name
- container_name
Docker-compose部署gitlab
一、安裝Docker
安裝必要工具
[root@vm_10_14_centos ~]# yum -y install yum-utils device-mapper-persistent-data lvm2
添加Docker-ce鏡像源並安裝
[root@vm_10_14_centos ~]# yum-config-manager --add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@vm_10_14_centos ~]# yum makecache fast
[root@vm_10_14_centos ~]# yum -y install docker-ce[root@gitlab ~]# yum makecache fast
[root@vm_10_14_centos ~]# yum -y install docker-ce
[root@vm_10_14_centos ~]# systemctl start docker
[root@vm_10_14_centos ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
添加Docker鏡像加速
[root@vm_10_14_centos ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://9w1hl6qt.mirror.aliyuncs.com"]
}
[root@vm_10_14_centos ~]# systemctl daemon-reload
[root@vm_10_14_centos ~]# systemctl restart docker
[root@vm_10_14_centos ~]# rpm -qa docker
[root@vm_10_14_centos ~]# rpm -qa docker-ce
docker-ce-18.09.0-3.el7.x86_64
[root@vm_10_14_centos ~]# docker --version
Docker version 18.09.0, build 4d60db4
[root@vm_10_14_centos ~]# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false
二、安裝Docker-compose
下載Docker-compose二進制文件並添加執行權限
[root@vm_10_14_centos ~]# curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 959 0 --:--:-- --:--:-- --:--:-- 958
100 11.2M 100 11.2M 0 0 1824k 0 0:00:06 0:00:06 --:--:-- 2422k
[root@vm_10_14_centos ~]# chmod +x /usr/local/bin/docker-compose
[root@vm_10_14_centos ~]# docker-compose --version
docker-compose version 1.23.2, build 1110ad01
三、安裝Gitlab
(1)編輯docker-compose的yml文件
[root@vm_10_14_centos ~]# mkdir gitlab
[root@vm_10_14_centos ~]# cd gitlab/
[root@vm_10_14_centos gitlab]# vim docker-compose.yml
version: '2'
services:
gitlab:
image: 'twang2218/gitlab-ce-zh:11.1.4'
container_name: "gitlab"
restart: unless-stopped
privileged: true
hostname: 'gitlab'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://129.204.133.242'
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.aliyun.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "kimasd102419@aliyun.com" #用本身的aliyun郵箱
gitlab_rails['smtp_password'] = "axbc1kof"
gitlab_rails['smtp_domain'] = "aliyun.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'kimasd102419@aliyun.com'
gitlab_rails['gitlab_shell_ssh_port'] = 22
ports:
- '80:80'
- '443:443'
- '22:22'
volumes:
- /opt/gitlab/config:/etc/gitlab
- /opt/gitlab/data:/var/opt/gitlab
- /opt/gitlab/logs:/var/log/gitlab
(2)建立相關目錄
[root@vm_10_14_centos gitlab]# mkdir /opt/gitlab/{config,data,logs} -p
[root@vm_10_14_centos gitlab]# ls -l /opt/gitlab/
total 12
drwxr-xr-x 2 root root 4096 Dec 8 11:35 config
drwxr-xr-x 2 root root 4096 Dec 8 11:35 data
drwxr-xr-x 2 root root 4096 Dec 8 11:35 logs
(3)拉取gitlab中文版鏡像
[root@vm_10_14_centos gitlab]# docker pull twang2218/gitlab-ce-zh:11.1.4
11.1.4: Pulling from twang2218/gitlab-ce-zh
8ee29e426c26: Pull complete
6e83b260b73b: Pull complete
e26b65fd1143: Pull complete
40dca07f8222: Pull complete
b420ae9e10b3: Pull complete
a218309dd589: Pull complete
5c60fd7ba0ce: Pull complete
659c2144b5a3: Pull complete
8289bbac0d0e: Pull complete
31bbd150e8a7: Pull complete
9114e78243fa: Pull complete
0b97fa2153bc: Pull complete
308c7e15be6a: Pull complete
b7f31b8e487d: Pull complete
cbbb6dec5000: Pull complete
0241c9ad6a16: Pull complete
7fa6f0b53edd: Pull complete
1c2861e152b2: Pull complete
0536f3466f66: Pull complete
Digest: sha256:3c2372e3285e6d6933ddebb5ee3ae0c4bbf7cb235084e54d33d7f0ddf4813c4a
Status: Downloaded newer image for twang2218/gitlab-ce-zh:11.1.4
[root@vm_10_14_centos gitlab]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
twang2218/gitlab-ce-zh 11.1.4 1935cc9f8798 4 months ago 1.61GB
(4)啓動gitlab的容器
[root@vm_10_14_centos gitlab]# docker-compose up -d
Creating network "gitlab_default" with the default driver
Creating gitlab ... error
ERROR: for gitlab Cannot start service gitlab: b'driver failed programming external connectivity on endpoint gitlab (9308ca74b8491c556263eac9fb9b0abcb25258d9e2df5733fc4d9143d6b18dcc): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use'
ERROR: for gitlab Cannot start service gitlab: b'driver failed programming external connectivity on endpoint gitlab (9308ca74b8491c556263eac9fb9b0abcb25258d9e2df5733fc4d9143d6b18dcc): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use'
ERROR: Encountered errors while bringing up the project.
[root@vm_10_14_centos gitlab]# vim /etc/ssh/sshd_config
[root@vm_10_14_centos gitlab]# systemctl restart sshd
[root@vm_10_14_centos gitlab]# netstat -tulnp |grep 22
tcp 0 0 0.0.0.0:60022 0.0.0.0:* LISTEN 4044/sshd
這裏須要注意的是,因爲gitlab容器須要用到22端口,不能與宿主機衝突,這裏須要修改宿主機的sshd服務的監聽端口
[root@vm_10_14_centos gitlab]# docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
------------------------
gitlab /assets/wrapper Up (healthy) 0.0.0.0:22->22/tcp, 0.0.0.0:443-
>443/tcp, 0.0.0.0:80->80/tcp
(5)gitlab設置開機啓動
[root@vm_10_14_centos gitlab]# chmod +x /etc/rc.local
[root@vm_10_14_centos gitlab]# ls -l /etc/rc.local
lrwxrwxrwx. 1 root root 13 Jul 7 16:43 /etc/rc.local -> rc.d/rc.local
[root@vm_10_14_centos gitlab]# echo "cd /root/gitlab && docker-compose up -d" >>
/etc/rc.local
[root@gitlab gitlab]# tail -1 /etc/rc.local
cd /root/gitlab && docker-compose up -d
(6)gitlab管理界面
地址:http://129.204.133.242
帳號:root
密碼:首次登錄設置


