Docker 是一個開源的應用容器引擎,讓開發者能夠打包他們的應用以及依賴包到一個可移植的容器中,而後發佈到任何流行的 Linux 機器上。html
Docker是一個從新定義了程序開發測試、交付和部署過程的開放平臺,Docker則能夠稱爲構建一次,處處運行,這就是docker提出的「Build once,Run anywhere」java
備註:java提出的是」 compile Once,Run Anywhere」python
docker與linux內核的關係mysql
Cgroup: 對資源進行限制(如對物理資源CPU、內存、I/O的限制)linux
Namespace:對進程進行隔離web
Chroot: 能改變當前運行的進程和子進程的根目錄redis
AUFS:聯合文件系統,Docker利用AUFS將不一樣的Layer結合到1個image中去sql
Docker採用C/S架構,客戶端與服務器端不必定要在一塊兒。客戶端能夠運行在windows、linux等機器上,而後服務器端必須運行在linux 64bit的操做系統上。docker
ü 主機:運行容器的機器json
ü 鏡像:文件的層次結構,以及包含如何運行容器的元數據, Dockerfile中的每條命令都會在文件系統中建立一個新的層次結構,文件系統在這些層次上構建起來,鏡像就構建於這些聯合的文件系統之上
ü 容器:一個從鏡像中啓動,包含正在運行的程序的進程
ü Registry(鏡像倉庫):存放鏡像的地方,如Docker Hub
ü Volumn(卷):將物理機的文件夾掛載到容器內部.與openstack的volumn不同,openstack中的卷是塊存儲,不能共享。而這裏的volumn能夠共享。
ü Dockerfile:用於建立鏡像的腳本
主要體如今三個方面:
ü 代碼一致:
在沒有docker以前,開發、測試、生成環境可能不同,如發佈某個服務的端口時,開發是1000,而生產是2000,這就致使配置文件不一致。然而使用docker後,我在容器內的端口都是同樣的,而容器對外暴露的端口可能不同。
ü 開發環境與生產環境的一致性
咱們知道,在生產環境的部署比較複雜,服務很是繁多。經過docker,咱們能夠單機版上經過容器來模擬生產環境的分佈式環境。從而讓開發人員的開發更有效率。
ü 快速部署
能夠將docker理解爲輕量級的虛擬機,啓動docker容器速度很快,啓動虛擬機很慢。
ü 節約安裝各類軟件的時間。
在沒有docker以前,在部署程序以前,勢必要搭建環境,而搭建環境很花費時間,還要解決環境的各類依賴,而docker經過鏡像機制,將你的代碼和運行環境直接打包成鏡像,扔到容器啓動便可。
ü 下降運維成本。
在沒有docker以前,因爲技術不斷髮展,運維也要不停的學習各類軟件的使用技能,如Node.js、redis等。有了docker,根本不用關係這些技術(或者少關心),只須要關注容器就能夠了,可以正常的發佈容器,中止容器、刪除容器、遷移容器就能夠了。
Coding.net、Oschina這些代碼託管平臺,有個功能即提供給用戶程序的演示環境,我不知道他們底層到底採用的什麼技術,可是若是Iaas層的openstack,給用戶直接提供虛擬機,先得太「笨重」,由於虛擬機自己對物理機的開銷就比較大,若是採用Docker,我1臺物理機能夠部署多個容器,能夠下降企業的採購物理機的費用,並且運行效率上應該比採用Iaas層的方案快。
參考: https://docs.docker.com/installation/ubuntulinux/
這裏以在unbuntu14.04上安裝爲例:
Ø 建立docker用戶並將其歸入docker這個用戶組
#useradd docker -g docker
Ø 更新源
#sudo apt-get update
Ø 安裝依賴包
#sudo apt-getinstall linux-image-generic-lts-trusty
Ø 重啓
#sudo reboot
Ø 安裝docker
#sudo apt-getinstall wget // 能夠經過命令which wget是否已安裝
#wget -qO-https://get.docker.com/ | sh //獲取最新版本
Ø 驗證安裝是否成功
#sudo docker runhello-world
#service docker start //啓動
#service docker restart //重啓
#service docker stop //中止
# sudo docker version
#sudo docker info
Containers: 5
Images: 129
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 139
Execution Driver: native-0.2
Kernel Version:3.13.0-32-generic
Operating System: Ubuntu14.04.1 LTS
CPUs: 2
Total Memory: 3.673 GiB
Name: docker
ID: OWRW:DDDW:MQZD:CCKM:JDKM:5ZEP:LTBB:YG3H:QI7G:EMDE:MSMR:XDFK
Username: ningyougang
Registry:[https://index.docker.io/v1/]
WARNING: No swap limit support
#sudo docker //查看docker的全部命令
#sudo docker command --help //查看單個docker命令的幫助,如docker ru--help
入門級例子:從ubuntu:14.04鏡像啓動一個容器,成功後在容器內部執行/bin/echo ‘hello world’命令,若是當前物理機沒有該鏡像,則執行docker pull從Docker Hub獲取鏡像,執行成功後,容器立馬中止
#sudo docker runubuntu:14.04 /bin/echo 'Hello world'
參數解釋
dockerrun:docker中的啓動容器命令
Ubuntu:鏡像名稱
14:04:鏡像TAG,若是不指定TAG,docker使用最新的發行版TAG:latest
/bin/echo ‘Helloworld’:在容器內執行的命令
該命令執行過程
l 若是本地有ubuntu這個image就從它建立容器,不然從公有倉庫下載
l 從image建立容器
l 分配一個文件系統,並在只讀的image層外面掛載一層可讀寫的層
l 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
l 從地址池配置1個ip地址給容器
l 執行你指定的程序,在這裏啓動一個/bin/bash
以交互模式啓動一個容器(具體參數意義請執行dockerrun --help)
$ sudo docker run -t-i ubuntu:14.04 /bin/bash
參數解釋
-t:開啓一個終端
-i:以交互模式運行
之後臺模式運行一個容器
#sudo docker run -dubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1;done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
參數解釋
-d:之後臺Daemon方式運行,執行成功後會返回一個該容器的ID
# sudo docker run -d -P training/webapp Python app.py
參數解釋
-d:之後臺Daemon方式運行,執行成功後會返回一個該容器的ID
-P:端口映射,外部端口到容器端口的映射規則由docker負責
-p:本身指定端口映射規則,格式爲:-p 外部端口:容器端口
經過docker ps -l,能夠查看到其PORTS列的端口映射規則
固然你也能夠,手工指定端口映射規則來啓動Web容器
#sudo docker run -d -p 5000:5000 training/webapp pythonapp.py
備註:-p 完整的參數爲:-p ip:hostport:port,將當前物理機的ip的端口映射到容器的端口
若是你想經過很快捷的方式查看容器的端口
#sudo docker port 容器ID或容器名稱
以JSON的格式返回容器的具體信息
#sudo docker inspect容器ID或容器名稱
#sudo docker exec -it 容器ID /bin/bash
備註:通常對運行着的後臺容器,執行該命令。查看其容器內部的狀況。
$sudo docker logs 容器ID或容器名稱
參數解釋
-f:以滾動的形式查看日誌,相似於linux的tail -f XXX.log
$sudo exit //在容器內部執行該命令(或crtl+D),通常在交互模式下退出當前容器
備註:容器仍然運行着
# sudo docker create--name ubuntContainer ubuntu:14.04 /bin/echo 'Hello world'
#sudo docker restart 容器ID
#sudo docker pause 容器ID //暫停
#sudo docker unpause 容器ID //解除暫停
$sudo docker stop 容器ID或容器名稱
#docker stop $(docker ps -q -a) //一次性中止全部容器,慎用
$sudo docker kill 容器ID或容器名稱
$sudo docker rm 容器ID或容器名稱 //刪除容器,正在運行的容器不能刪除
#sudo docker rm $(docker ps -q -a) //一次性刪除全部容器,慎用
下面咱們經過mysql_server容器與mysql_client容器的互聯來了解link
Ø 建立mysql_server鏡像,並生成一個容器
#cd /
#mkdir mysql_server
#vi Dockerfile
FROM centos:centos6
MAINTAINER ningyougang "xxxx@qq.com"
RUN yum install -y MySQL-server mysql
RUN /etc/init.d/mysqld start &&\
mysql -e"grant all privileges on *.* to 'root'@'%' identified by'mysql';"&&\
mysql -e"grant all privileges on *.* to 'root'@'localhost' identified by'mysql';"&&\
mysql -u root-pmysql -e "show databases;"
EXPOSE 3306
CMD ["/usr/bin/mysqld_safe"]
# sudo docker build -t ningyougang/mysql_server . //生成鏡像
#sudo docker run --name=mysql_server -d -Pningyougang/mysql_server //生成mysql_server容器
Ø 建立mysql_client鏡像,並生成一個link到mysql_server的client容器
#cd /
#mkdir mysql_client
#vi Dockerfile
FROM centos:centos6
MAINTAINER ningyougang "xxxx@qq.com"
RUN yum install -y mysql
#sudo docker build -t ningyougang/mysql_client . //生成鏡像
#sudo dockerrun --name=mysql_client1 --link=mysql_server:db -t -i ningyougang/mysql_client/usr/bin/mysql -h db -u root -pmysq //生成mysql_client容器
參數解釋
--link:<name or id>:alias
經過上面的命令,link中的別名(alias)db便是mysql_client鏈接mysql_server的鏈接串
Ø 進入mysql_client研究其link的實現細節
#sudo docker exec-it bfc6cb037165 /bin/bash //以交互模式進入mysql_client容器內部
[root@bfc6cb037165/]# env | grep DB //查看與DB(也就是alias)相關的環境變量
DB_NAME=/mysql_client2/db
DB_PORT=tcp://172.17.0.25:3306
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_PORT_3306_TCP_ADDR=172.17.0.25
DB_PORT_3306_TCP=tcp://172.17.0.25:3306
[root@bfc6cb037165 /]#vi /etc/hosts
172.17.0.27 bfc6cb037165 #docker生成的mysql_client的IP、域名
172.17.0.25 db #docker生成的mysql_server的IP、域名
總結:能夠發現docker在mysql_client內經過生成別名的環境變量和profile相關的主機和域名的配置,打通了客戶端到服務器端的tcp鏈接通道,而對於上層的應用,不須要關注IP、端口這些細節,只須要經過別名來訪問便可
Docker網絡
參考: http://www.open-open.com/doc/view/f720084681bb434bbed132d2bc1493ac
Ø 使用自定義網橋鏈接跨主機容器
N/A,待寫
Ø 使用Ambassador實現跨主機容器
N/A, 待寫
Ø kubernetes
N/A, 待寫
Ø 把物理機的目錄掛載到容器裏
以交互模式啓動一個容器,將物理機的/src/webapp掛載到/opt/webapp下
#sudodocker run -t -i -v /src/webapp:/opt/webappubuntu:14.04 /bin/bash
參數解釋
-v 物理機目錄:容器目錄:讀寫權限
其中默認的權限爲可讀寫, ro:只讀
Ø 把物理機的文件掛載到容器裏
#sudo dockerrun -t -i -v/src/webapp/test.html:/opt/webapp/test.html ubuntu:14.04 /bin/bash
Ø 把容器掛載到另一個容器
#sudo docker create -v /dbdata --name dbdata ubuntu:14.04 //建立容器
#sudodocker run -it --volumes-from dbdata ubuntu:12.04 /bin/bash //啓動容器捲來自dbdata
參數解釋
-volumn-from:捲來自哪一個容器
Ø 把容器掛載做爲數據備份
#sudo docker run --volumes-from dbdata -v $(pwd):/backup--name worker ubuntu tar cvf /backup/backup.tar /dbdata
命令解釋
首先利用ubuntu鏡像建立一個容器worker.使用—volumes-from dbdata參數來讓容器掛載dbdata容器的數據卷;使用 –v $(pwd):/backup參數來掛載本機的當前目錄到worker容器的/backup目錄
Woker容器啓動後,執行tar命令將/dbdata壓縮到/backup/backup.tar,這樣就到物理機的當前目錄了
Ø 把容器掛載做爲數據遷移
#sudo docker run -v/dbdata --name dbdata2 ubuntu /bin/bash
#sudo docker run--volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/.tar
#sudo docker attach 容器ID
#sudo docker top 容器ID
#sudo docker cp cd0f61fb8256:/opt/a.html /
#sudo docker diff 容器ID
列表解釋
list列表會顯示出三種事件,A 增長的,D 刪除的,C 被改變的
#sudo docker images //在本機進行鏡像查看
#sudo docker inspect 鏡像ID //查看單個鏡像的具體信息,以JSON格式返回
# sudo docker pull centos //從DockerHub獲取鏡像
#sudo docker search 鏡像名稱 //從DockerHub按照鏡像名稱模擬查詢鏡像
ü 經過Dockerfile構建鏡像
#sudo cd / //來到根「/」下
#sudo mkdir redis //建立redis文件夾
#touch Dockerfile //建立Dockerfile文件,文件內容見以下灰色部分
FROM ubuntu:14.04
RUN apt-get update && apt-getinstall -y redis-server
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
#sudo docker build -t ningyougang/redis . //經過dockerbuild製做鏡像
參數解釋
-t:tag名稱
.:當前Dockerfile的路徑,在此處表示當前文件夾下
ü 對運行着的容器commit鏡像
# sudo docker commit -m "Added json gem" -a"Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2
參數解釋
-m:提交註釋,如此處你加了什麼特別的功能
-a:做者
0b2616b0e5a8:運行着的容器ID
ouruser/sinatra:v2:給當前提交的鏡像起名字並打標籤
備註:從上面能夠看出,咱們能夠經過dockercommit來建立鏡像,可是這種方式有點凌亂並且很難複製,更好的方式是經過Dockerfile來構建鏡像,由於它步驟清晰而且容易複製
#sudo docker tag 5db5f8471261 ouruser/sinatra:devel //當commit or build後,對鏡像打標籤
參數解釋
5db5f8471261:此處的id爲鏡像ID
備註:向私有倉庫push鏡像也要打標籤
#sudo docker push ouruser/sinatra
下面介紹下DockerHub
DockerHub是存放鏡像的遠程倉庫,這裏簡單介紹下,如何使用
Ø 註冊
首先在https://hub.docker.com/account/signup/完成賬號註冊
Ø 登陸
賬號註冊成功後,在https://hub.docker.com/account/login/,便可登陸
除了經過登陸頁面,您也能夠經過命令行,經過指令sudo docker login登陸
Ø 查詢鏡像
點擊「Browse Repos」(或輸入https://registry.hub.docker.com/),進入鏡像查詢頁面
在此頁面,您能夠錄入你感興趣的鏡像名稱,進行模糊查詢
固然你也能夠經過docker search XXX進行鏡像查詢
Ø 使用Docker賬號綁定GitHub賬號,進行自動化構建
須要細化,沒有來得及研究
ü 下載私有倉庫鏡像
# docker pull registry #從DockerHub下載registry鏡像,裏面含私庫的運行環境,#固然你也能夠本身下載源碼包,本身安裝
ü 推送以前打tag
# docker tag 704ca5ad68c5 192.168.202.213:5000/newtouch/activemq #打標籤(必須先打標籤,#在推送)
該命令格式爲:docker tag $ID $IP:$port/$name。push到私庫上必須先打個tag,而tag名稱的格式爲:$IP:$port/$name, 我的感受此處設計不太好或我本身沒有找到更好的辦法。若是設計良好應該能夠直接push,不用打標籤.
ü Push tag到鏡像
#docker push 192.168.202.213:5000/newtouch/activemq #將此tag推送到私有庫
ü Push到倉庫後,遠程查看
#curl http://192.168.202.213:5000/v1/search #push以後,遠程查看
ü 在另一個docker客戶端,從私有倉庫下載
#docker pull 192.168.202.213:5000/newtouch/activemq
Docker tag報https錯誤問題解決:
vi /etc/default/docker #紅色部分是添加的部分,重啓docker服務
# Docker Upstart and SysVinitconfiguration file
# Customize location of Dockerbinary (especially for development testing).
#DOCKER="/usr/local/bin/docker"
# Use DOCKER_OPTS to modify thedaemon startup options.
#DOCKER_OPTS="--dns8.8.8.8 --dns 8.8.4.4"
DOCKER_OPTS="--insecure-registry 192.168.202.213:5000"
# If you need Docker to use anHTTP proxy, it can also be specified here.
#exporthttp_proxy="http://127.0.0.1:3128/"
# This is also a handy place totweak where Docker's temporary files go.
#exportTMPDIR="/mnt/bigdrive/docker-tmp"
#sudo docker rmi 鏡像ID
# docker history
$ sudo docker ps //查看有那些正在運行着的容器
參數解釋
-l:最近的一個容器,有可能沒有運行
-a:查看全部的容器,包含運行和沒有運行的容器
#sudo docker events