1.docker架構html
http://www.infoq.com/cn/articles/docker-source-code-analysis-part1/java
Docker架構內各模塊:Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainerpython
以及Docker container。linux
2.下載docker工具網址git
https://www.docker.com/docker-toolboxgithub
3.下載dockerp_w_picpath模板網址web
http://download.openvz.org/template/precreated/redis
4.dockerfile的做用docker
Dockerfile用來建立一個自定義的p_w_picpathubuntu
http://blog.csdn.net/wsscy2004/article/details/25878223
基於Dockerfile搭建JAVA Tomcat運行環境:http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html
阿里雲服務器:
120.25.223.73:4200
120.25.88.150:4200
112.74.22.173:4200
sudo HTTP_PROXY=http://proxyx.com.cn:80 docker -d
sudo docker pull ubuntu # 下載最新ubuntu鏡像
Docker 主站點: https://www.docker.io
Docker 註冊中心API: http://docs.docker.com/reference/api/registry_api/
Docker Hub API: http://docs.docker.com/reference/api/docker-io_api/
Docker 迖端應用API: http://docs.docker.com/reference/api/docker_remote_api/
Dockerfile 參考:https://docs.docker.com/reference/builder/
Dockerfile 最佳實踐:https://docs.docker.com/articles/dockerfile_best-practices/
docker參數詳解
useage of docker
-D 默認false 容許調試模式(debugmode)
-H 默認是unix:///var/run/docker.sock tcp://[host[:port]]來綁定 或者unix://[/path/to/socket]來使用(二進制文件的時候),當主機ip host=[0.0.0.0],(端口)port=[4243] 或者 path=[/var/run/docker.sock]是缺省值,作爲默認值來使用
-api-enable-cors 默認flase 容許CORS header遠程api
-b 默認是空,附加在已存在的網橋上,若是是用’none’參數,就禁用了容器的網絡
-bip 默認是空,使用提供的CIDR(ClasslessInter-Domain Routing-無類型域間選路)標記地址動態建立網橋(dcoker0),和-b參數衝突
-d 默認false 容許進程模式(daemonmode)
-dns 默認是空,使docker使用指定的DNS服務器
-g 默認是」/var/lib/docker」:做爲docker使用的根路徑
-icc 默認true,容許inter-container來通訊
-ip 默認」0.0.0.0″:綁定容器端口的默認Ip地址
-iptables 默認true 禁用docker添加iptables規則
-mtu 默認1500 : 設置容器網絡傳輸的最大單元(mtu)
-p 默認是/var/run/docker.pid進程pid使用的文件路徑
-r 默認是true 重啓以前運行的容器
-s 默認是空 ,這個是docker運行是使用一個指定的存儲驅動器
-v 默認false 打印版本信息和退出
docker run命令詳解
Usage: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]
Run a command in a new container
-a=map[]: 附加標準輸入、輸出或者錯誤輸出
-c=0: 共享CPU格式(相對重要)
-cidfile=」」: 將容器的ID標識寫入文件
-d=false: 分離模式,在後臺運行容器,而且打印出容器ID
-e=[]:設置環境變量
-h=」」: 容器的主機名稱
-i=false: 保持輸入流開放即便沒有附加輸入流
-privileged=false: 給容器擴展的權限
-m=」」: 內存限制 (格式:<number><optional unit>, unit單位 = b, k, m or g)
-n=true: 容許鏡像使用網絡
-p=[]: 匹配鏡像內的網絡端口號
-rm=false:當容器退出時自動刪除容器 (不能跟 -d一塊兒使用)
-t=false: 分配一個僞造的終端輸入
-u=」」: 用戶名或者ID
-dns=[]: 自定義容器的DNS服務器
-v=[]: 建立一個掛載綁定:[host-dir]:[container-dir]:[rw|ro].若是容器目錄丟失,docker會
建立一個新的卷
-volumes-from=」」: 掛載容器全部的卷
-entrypoint=」」: 覆蓋鏡像設置默認的入口點
-w=」」: 工做目錄內的容器
-lxc-conf=[]: 添加自定義-lxc-conf=」lxc.cgroup.cpuset.cpus = 0,1″
-sig-proxy=true: 代理接收全部進程信號(even in non-tty mode)
-expose=[]: 讓你主機沒有開放的端口
-link=」」: 鏈接到另外一個容器(name:alias)
-name=」」: 分配容器的名稱,若是沒有指定就會隨機生成一個
-P=false: Publish all exposed ports to thehost interfaces 公佈全部顯示的端口主機接口
docker經常使用命令總結
docker pull <鏡像名:tag> #從官網拉取鏡像
docker search <鏡像名> #搜索在線可用鏡像名
查詢容器、鏡像、日誌
docker top <container> #顯示容器內運行的進程
docker p_w_picpaths #查詢全部的鏡像,默認是最近建立的排在最上。
docker ps #查看正在運行的容器
docker ps -l #查看最後退出的容器的ID
docker ps -a #查看全部的容器,包括退出的。
docker logs {容器ID|容器名稱} #查詢某個容器的全部操做記錄。
docker logs -f {容器ID|容器名稱} #實時查看容易的操做記錄。
刪除容器與鏡像
docker rm$(docker ps -a -q) #刪除全部容器
docker rm <容器名or ID> #刪除單個容器
docker rmi <ID> #刪除單個鏡像
docker rmi$(docker p_w_picpaths | grep none | awk ‘{print $3}’ | sort -r)#刪除全部鏡像
啓動中止容器
docker stop <容器名or ID> #中止某個容器
docker start <容器名or ID> #啓動某個容器
docker kill <容器名or ID> #殺掉某個容器
容器遷移
docker export <CONTAINER ID> > /home/export.tar #導出
cat /home/export.tar | sudo docker import – busybox-1-export:latest# 導入export.tar文件
docker save debian> /home/save.tar #將debian容器打包
docker load< /home/save.tar #在另外一臺服務器上加載打包文件
save和export的對比參考地址:http://www.fanli7.net/a/bianchengyuyan/C__/20140423/452256.html
運行一個新容器
#運行一個新容器,同時爲它命名、端口映射。以debian02鏡像爲例
docker run -h=」redis-test」 –name redis-test -d -p 51000:22 -p51001:3306 -p
51003:6379 -p 51004:6381 -p 51005:80 -p 51006:8000 -p 51007:8888 debian02 /etc/rc.local
#從container中拷貝文件,當container已經關閉後,在裏面的文件還能夠拷貝出來。
sudo docker cp 7bb0e258aefe:/etc/debian_version . #把容器中的/etc/debian_version拷貝到
當前目錄下。
2.映像操做
cat layer.tar | sudo docker import - ubuntu:3.0#從本地文件系統導入鏡像
docker p_w_picpaths
docker pull ubuntu:12.04 <=> docker pull registry.hub.docker.com/ubuntu:12.04#從docker hub下載鏡像
docker rmi <p_w_picpath id> #刪除p_w_picpath
docker rmi `docker p_w_picpaths -a | awk '{if($2==0.0) print $3;}'`#刪除tag==0.1的映像
docker rmi -f `docker p_w_picpaths -a -q`#強制刪除全部映像
docker commit [-m "..." -a "..."] containerID rep:tag#將容器導出爲映像
sudo docker save -o ubuntu_14.04.tar ubuntu:14.04#將映像ubuntu:14.04保存到本地當前目錄下的ubuntu_14.04.tar(要用.tar後綴)
sudo docker load --input ubuntu_14.04.tar
或 sudo docker load < ubuntu_14.04.tar#載入save保存的鏡像,也可使用 docker import
docker tag p_w_picpathid 10.9.111.221:5000/ubuntu:12.0
docker pull 10.9.111.221:5000/ubuntu #在私有庫中拉取最新的ubuntu
docker search 10.9.111.221:5000/ubuntu#搜索私有庫中的ubuntu庫
curl http://104.131.173.242:5000/v1/search #查詢私有倉庫
3.容器操做
docker run -i ubuntu:3.0 /usr/bin/bash #啓動容器,而且進入到Ubuntu容器的bash命令 -t僞造一個虛擬終端,當執行腳本時不能用-t選項
docker run -i -t --name mycontainer ubuntu:3.0 echo "liujidngd"#-i打開標準輸出;-t容許僞終端;--name容器名字;--rm容器退出時強制刪除容器
docker run -i -t --rm ubuntu:3.0 echo "liujidngd" #運行完該命令後,刪除容器
docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
docker ps #列出當前全部正在運行的container
docker ps -l #列出最近一次啓動的,且正在運行的container
docker ps -a #列出全部的container
docker rm `docker ps -a -q`#刪除全部容器
docker rm $CONTAINER_ID#刪除容器id爲CONTAINER_ID的容器
docker stop CONTAINER_ID #中止docker實例
docker logs containerName#查看後臺運行的容器的日誌
ctrl +p+q 將容器推入後臺運行
docker attach containerName#從新進入容器,或將容器提到前臺
docker export CONTAINER_ID > ubuntu.tar#導出容器快照到本地當前文件夾下
cat layer.tar | docker import - ubuntu:3.0#從本地文件系統導入容器快照爲鏡像
docker commit containerID p_w_picpathname #將容器導出爲映像
4.Docker 數據管理 (數據卷的使用,相似亍 Linux 下對目錄戒文件迕行 mount)
docker run -d -v /webapp ubuntu:0.1 echo "lk"#運行容器時在根目錄下加載一個數據卷(建立了一個數據卷容器)
docker run -d -v /src/webapp:/opt/webapp ubuntu:0.1 echo "lk" #掛載本地主機目錄/src/webapp到容器目錄/opt/webapp
docker run -d -v /src/webapp:/opt/webapp:ro ubuntu:0.1 echo "lk"#掛載時指定只讀權限
docker run -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash #將本地文件~/.bash_history掛載到主機文件/.bash_history
docker run -d -v /data --name dbdata ubuntu:0.1 echo "lk"#建立了一個數據卷容器
docker run -d --volumes-from dbdata --name db1 ubuntu:0.1 echo "lk"#掛載數據卷dbdata下全部的數據卷,用於容器目錄共享
docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata#將數據卷容器的數據備份到本地目錄
5.Docker 中的網絡功能
容器中能夠運行一些網絡應用,要讓外部也能夠訪問這些應用,能夠經過 -P 或 -p 參數來指定端口映射。
當使用 -P 標記時,Docker 會映射一個 本地49000~49900 的隨機端口到內部容器被開放使用的網絡端口。
docker run -d -P training/webapp python app.py#使用隨機端口綁定到容器在使用的端口
docker run -d -p 5000:5000 training/webapp python app.py#使用固定端口綁定到容器
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
docker run -d -p 127.0.0.1::5000 training/webapp python app.py#映射到指定地址的任意端口
docker run --link db:dbalias --name web training/webapp env#將容器的db的隨機端口與容器web使用的端口相連
docker port CONTAINER_ID portnum #查看容器中的端口port對應主機的端口號
6.命令
Docker 的命令能夠採用 docker-CMD 戒者 docker CMD 的方式執行。二者一致。
docker-attach依附到一個正在運行的容器中。
docker-build從一個 Dockerfile 建立一個鏡像
docker-commit從一個容器的修改中建立一個新的鏡像
docker-cp(1)從容器中複製文件到宿主系統中
docker-diff(1)檢查一個容器文件系統的修改
docker-events從服務端獲取實時的事件
docker-export導出容器內容爲一個 tar 包
docker-history顯示一個鏡像的歷叱
docker-p_w_picpaths列出存在的鏡像
docker-import導入一個文件(典型爲 tar 包)路徑戒目錄來建立一個鏡像
docker-info顯示一些相關的系統信息
docker-inspect顯示一個容器的底層具體信息。
docker-kill關閉一個運行中的容器 (包括迕程和全部資源)
docker-load從一個 tar 包中加載一個鏡像
docker-login註冊戒登陸到一個 Docker 的仏庫服務器
docker-logout從 Docker 的仏庫服務器登出
docker-logs獲取容器的 log 信息
docker-pause暫停一個容器中的全部迕程
docker-port查找一個 nat 到一個私有網口的公共口
docker-ps列出容器
docker-pull從一個Docker的仏庫服務器下拉一個鏡像戒仏庫
docker-push將一個鏡像戒者仏庫推送到一個 Docker 的註冊服務器
docker-restart重吪一個運行中的容器
docker-rm刪除給定的若干個容器
docker-rmi刪除給定的若干個鏡像
docker-run建立一個新容器,幵在其中運行給定命令
docker-save保存一個鏡像爲 tar 包文件
docker-search在 Docker index 中搜索一個鏡像
docker-start啓動一個容器
docker-stop終止一個運行中的容器
docker-tag爲一個鏡像打標籤
docker-top查看一個容器中的正在運行的迕程信息
docker-unpause將一個容器內全部的迕程從暫停狀態中恢復
docker-version輸出 Docker 的版本信息
docker-wait阻塞直到一個容器終止,而後輸出它的退出符
7.dockerfile 文件建立分層映像
第一步:在本地的當前目錄下建立Dockerfile
FROM ubuntu:test3 //使用ubuntu:test3做爲基礎映像
RUN mkdir work
RUN echo "Hello docker!" >/work/lj //在該映像上加一層
第二步:編譯生成一個新的映像
docker build -t="ubuntu:v1" /home/mepa/test //使用/home/mepa/test目錄(該目錄下最好只有一個Dockerfile文件)下的Dockerfile生成一個新的映像ubuntu:v1
第三步:運行新的映像ubuntu:v1
docker run -d -v /home/mapa/work:/work1 ubuntu:v1 //使用dockerfile生成的映像能夠沒有/bin/sh命令
1.docker與傳統虛擬機的優點
a.啓動快:docker的啓動能夠在秒級實現,而傳統虛擬機須要分級
b.對系統資源的利用率高:一臺主機能夠同時容許數千個docker容器,而傳統虛擬機通常只能運行幾十個。傳統的虛擬機運行10個不一樣的應用須要啓動10個不一樣的虛擬機,而docker只須要啓動10個隔離的應用便可。
c.運行效率高:Docker容器的運行不須要額外的hypervisor(中間件)支持,它是內核級的虛擬化,所以能夠實現更高的性能和效率。
d.更簡單的管理:使用Docker,只須要小小的修改,就能夠替代以往大量的更新工做。全部的修改都以增量的方式被分發和更新,從而實現自動化而且高效的管理。
e.一次建立,隨處運行
Docker底層的核心技術包括Linux上的名字空間( Namespaces)、控制組( Control groups)、Union文件系統( Union file systems)和容器格式( Container format)。傳統的虛擬機經過在宿主主機中運行hypervisor來模擬一整套完整的硬件環境提供給虛擬機的
操做系統,實現了操做系統級的隔離,而docker是在操做系統的基礎上實現的是進程級的隔離。
2.容器之間的網絡鏈接
a.系統外部訪問容器內部
容器中能夠運行一些網絡應用,要讓外部也能夠訪問這些應用,能夠經過 -P或-p參數來指定端口映射。
從而可使得互聯網經過訪問主機端口來訪問容器
b.容器之間的訪問
--link=CONTAINER_NAME:ALIAS選項會在建立容器的時候,添加一個其餘容器的主機名到/etc/hosts文件中, 讓新容器的進程可使用主機名ALIAS就能夠鏈接它。(容器在建立的時候,默認就已經經過docker0網橋互聯了,--link只是給容器ip取一個別名)
如:
$sudo docker run -d --name db training/postgres 不用向外映射任何端口
$sudo docker run -d -P--name web --link db:mydb ubuntu /bin/bash
>ping mydb
>cat /etc/hosts
當Docker服務器啓動時,會自動在主機上建立一個docker0虛擬網橋,至關於一個軟件交換機,能夠在掛載到它的網口之間進行數據轉發。
該軟交換機有一個ip好比172.17.42.1/16,啓動的每個容器也有一個同一網段的ip。經過這種方式,主機能夠跟容器通訊,容器之間也能夠相互通訊。 Docker就建立了在主機和全部容器之間一個虛擬共享網絡。
docker自動創建的網絡模型以下:!()[https://github.com/liujin123/sundry/blob/master/docker_soft_switch.png?raw=true]
>docker run -it --link pedantic_borg:myubunutu ubuntu /bin/sh
#ping myubunutu
PING myubunutu (172.17.0.3): 56 data bytes #能夠看到myubunutu的ip地址
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.187 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.165 ms
其實不須要--link選項容器與容器之間也是能夠ping通的,只是要先知道另一個容器的ip,這個能夠attach到容器中,而後在/etc/hosts文件中查看。
或者在本容器/etc/hosts中添加一個其它容器ip與主機名的映射,也能夠經過主機名訪問其它容器。
c.經常使用的與網絡相關的命令
-bBRIDGEor--bridge=BRIDGE--指定容器掛載的網橋
--bip=CIDR--定製docker0的掩碼
-HSOCKET...or--host=SOCKET...--Docker服務端接收命令的通道
--icc=true|false--是否支持容器之間進行通訊
--ip-forward=true|false--本地linux系統轉發本容器數據本
--iptables=true|false--禁止Docker添加本地系統的iptables規則
--mtu=BYTES--容器網絡中的MTU
下面2個命令選項既能夠在啓動服務時指定,也能夠Docker容器啓動( dockerrun) 時候指定。在
Docker服務啓動的時候指定則會成爲默認值,後面執行 dockerrun時能夠覆蓋設置的默認值。
--dns=IP_ADDRESS...--使用指定的DNS服務器
--dns-search=DOMAIN...--指定DNS搜索域
最後這些選項只有在 dockerrun執行時使用,由於它是針對容器的特性內容。
-hHOSTNAMEor--hostname=HOSTNAME--配置容器主機名
--link=CONTAINER_NAME:ALIAS--添加到另外一個容器的鏈接
--net=bridge|none|container:NAME_or_ID|host--配置容器的橋接模式
-pSPECor--publish=SPEC--映射容器端口到宿主主機
-Por--publish-all=true|false--映射容器全部端口到宿主主機
3.容器的訪問控制
容器的訪問控制主要經過linux的防火牆軟件iptables進行管理實現。每一個容器的虛擬網卡veth都須要鏈接到linux系統建立的docker0網橋上才能工做。
a.容器訪問外部網絡
容器訪問外部網絡須要本地linux系統的支持:網卡設置容許網絡轉發
$sysctlnet.ipv4.ip_forward #查看
net.ipv4.ip_forward=0
$sysctl-wnet.ipv4.ip_forward=1 #設置
/etc/init.d/procps.sh restart #生效
默認狀況下,容器能夠主動訪問到外部網絡的鏈接,可是外部網絡沒法訪問到容器。
容器全部到外部網絡的鏈接,源地址都會被NAT成本地系統的IP地址。 這是使用 iptables的源地址假裝操做實現的。
$sudo iptables -t nat -nL #查看主機的NAT(網絡地址轉換)規則。
...
ChainPOSTROUTING(policyACCEPT)
targetprotoptsourcedestination
MASQUERADEall--172.17.0.0/16!172.17.0.0/16
...
其中,上述規則將全部源地址在 172.17.0.0/16網段,目標地址爲其餘網段(外部網絡)的流量動態假裝爲從系統網卡發出。 MASQUERADE跟傳統SNAT的好處是它能動態從網卡獲取地址。容器容許外部訪問,能夠在 dockerrun時候經過 -p或 -P參數來啓用。
無論用那種辦法,其實也是在本地的 iptable的nat表中添加相應的規則。
$sudo iptables -t nat -nL
...
ChainDOCKER(2references)
target protopt source destination
DNATtcp--0.0.0.0/0 0.0.0.0 tcpdpt:49153to:172.17.0.2:80
b.容器之間的訪問 (默認互聯)
** 容器的網絡拓撲是否已經互聯。默認狀況下,全部容器都會被鏈接到docker0網橋上。
** 本地系統的防火牆軟件--iptables是否容許經過。
* c.網橋
每一個容器都有虛擬網卡ceth,而docker網橋只是將這些虛擬網卡橋接。
c1.默認網橋docker0
Docker服務默認會建立一個 docker0網橋。在內核層連通了全部的虛擬網卡,可是並無鏈接到物理網卡,而且docker0網橋沒有配置文件,要想橋接物理網卡,只能從新新建一個虛擬網橋。
每次建立一個新容器的時候, Docker從可用的地址段中選擇一個空閒的IP地址分配給容器的eth0端口。使用本地主機上docker0接口的IP做爲全部容器的默認網關。
>brctl show #顯示網橋橋接了那些網卡
c2.自定義網橋 《docker技術入門與實踐pdf》
在啓動Docker服務的時候,使用-b BRIDGE或--bridge=BRIDGE 來指定使用的網橋,也能夠修改配置文件。
自定義網橋是linux系統的功能,若是docker服務已經運行,那須要先中止服務,並刪除舊的網橋。
[root@opnvz~]#brctl show #顯示linux主機上的網橋
bridgenamebridgeidSTPenabledinterfaces
docker08000.56847afe9799noveth0889
$sudo service docker stop
$sudo iplink set dev docker0 down
$sudo brctl del br docker0
而後建立一個網橋 bridge0。
$sudo brctl add br bridge0
$sudo ipaddr add 192.168.5.1/24 dev bridge0
$sudo iplink set dev bridge0 up
查看確認網橋建立並啓動。
$ipaddr show bridge0
配置Docker服務,默認橋接到建立的網橋上。
$echo'DOCKER_OPTS="-b=bridge0"'>>/etc/default/docker
$sudo service docker start
c3.跨物理網絡的容器爲何能通訊?
本地系統上運行的虛擬機或容器在訪問外網時與本地進程使用相同的一套主機端口,於是數據準確送達容器進程或本地主機進程。
容器全部到外部網絡的鏈接,源地址都會被NAT成本地系統的IP地址。 這是使用iptables的源地址假裝操做實現的。互聯網訪問容器也是經過端口一一映射實現的。
d.ambassador 容器實現跨物理主機的容器間通訊
《docker技術入門與實踐pdf》
ambassador 容器提供C/S模型,可讓容器只存在本機的局域網,而使用ambassador 容器來提供網絡互聯。
4.聯合文件系統 UnionFS
聯合文件系統( UnionFS)是一種分層、 輕量級而且高性能的文件系統,它支持對文件系統的修改做爲一次提交來一層層的疊加,同時能夠將不一樣目錄掛載到同一個虛擬文件系統下(uniteseveraldirectoriesintoa
singlevirtualfilesystem)。聯合文件系統是Docker鏡像的基礎。 鏡像能夠經過分層來進行繼承,基於基礎鏡像(沒有父鏡像),能夠製做各類具體的應用鏡像。
5.數據卷
在容器中管理數據主要有兩種方式:數據卷和數據卷容器
數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過UFS,能夠提供不少有用的特性:
*數據卷能夠在容器之間共享和重用
*對數據卷的修改會立馬生效
*對數據卷的更新,不會影響鏡像
*卷會一直存在,直到沒有容器使用
在用docker run命令的時候,使用-v標記來建立一個數據卷並掛載到容器裏。在一次run中屢次使用能夠掛載多個數據卷
$sudo docker run -d --name web -v /webapp training/webapp python app.py 在容器中掛載一個數據卷
$sudo docker run -d --name web -v /src/webapp:/opt/webapp training/webapp python app.py 掛載一個主機目錄做爲數據卷
$sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash 掛載一個主機文件做爲數據卷
數據卷容器:其實就是一個正常的容器, 專門用來提供數據卷供其它容器掛載的。
$sudo docker run -d --name web -v /dbdata --name dbdatatraining/db 專門被其它容器掛載:凡是存在數據卷的容器均可以被其它容器掛載
$sudo docker run -d --volumes-from dbdata --name db1training/postgres 掛載其它容器的數據卷
$sudo docker run -d --volumes-from db1 --name db2training/postgres 從db1掛載
從數據卷中遷移數據:
$sudo docker run --volumes-fromdbdata-v $(pwd):/backup ubuntu tar cvf /backup/backup.tar 新建一個容器從而能夠將數據備份到主機目錄