Docker已經火了很長一段時間,最近打算在阿里雲上好好熟悉一下Docker的相關應用,爲從此的工做作準備,但願以下圖同樣,Docker技術一飛沖天。javascript
Docker是基於Go語言實現的雲開源項目,誕生於2013年初,最初發起者是dotCloud公司,其目標是「Build, Ship and Run Any App, Anywhere」,主要概念包括鏡像、容器、倉庫。Docker引擎的技術是Linux容器(Linux Containers, LXC)技術。容器有效地將由單個操做系統的資源劃分到孤立的組中,以便更好地在孤立的組之間平衡有衝突的資源使用需求。java
docker pull NAME[:TAG]
docker images
;查看某個鏡像具體信息docker inspect
docker tag xxx ubuntu:first
docker search xxx
, -s=0
指定星級docker rmi xxx
,通常狀況下會刪除鏡像的標籤,而不是文件,當刪除最後一個TAG時則會刪除文件,須要注意。-f
刪除能夠強制刪除鏡像,推薦作法爲先刪除依賴該鏡像的全部容器,以後刪除鏡像,Qdocker rm e81
docker run -ti ubuntu:14.04 /bin/bash
,任意建立一個test文件,以後建立鏡像docker commit -m "add file" -a "xionger" a9fdsfxx test
;基於本地模板建立,推薦使用OpenVZ提供的模板來建立;基於Dockerfile建立。sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
,導入鏡像docker load --input ubuntu_14.04.tar
docker push NAME[:TAG]
,默認上傳鏡像到DockerHub官方倉庫,須要登陸。容器Container:相似一個輕量級的沙箱,能夠利用容器來運行和隔離應用,容器從鏡像啓動時會在鏡像的最上層建立一個可寫層,鏡像自己保持不變。
建立容器:docker create -it ubuntu:lastest
,經過docker ps -a
查看容器,經過docker start
啓動容器
新建並啓動容器:docker run ubuntu /bin/bash
,-d
參數守護態運行,經過Ctrl+d或者exit退出容器
終止容器:docker stop xxx
,首先會發送SIGTERM信號,一段時候後發送SIGKILL,能夠經過docker kill
強行停止,docker restart
能夠關閉並重啓容器,docker ps -a -q
能夠查看處於終止態的容器信息。
進入容器:docker attach xxx
會被阻塞不推薦使用;docker exec -ti xxx /bin/bash
能夠直接在容器中運行命令;nsenter工具。
刪除容器:docker rm xxx
,須要注意區分,rmi
是刪除鏡像,rm
是刪除容器
導入和導出容器:docker export xxx
導出一個已經建立的容器到文件,不論是否在運行;docker import
,須要理解的是export
的是快照,信息少,而save
的是鏡像,信息多,包含元數據和歷史信息。node
倉庫Repository:相似於代碼倉庫,是Docker存放鏡像的場所,而Registry註冊服務器是存放倉庫的地方,其上放着不少倉庫,每一個倉庫集中存放某一類鏡像的多個文件,能夠經過tag標籤來區分。目前最大的公有倉庫是Docker Hub,而國內是Docker Pool。
Docker Pub:本地用戶目錄.dockercfg中存儲登陸信息,在倉庫中存在centos這類由Docker公司建立、驗證、支持的根鏡像,也有相似xionger/centos這類由我的提供的鏡像,能夠經過-s N
來查看高星鏡像。此外,Docker Hub還能夠經過設置追蹤相似GitHub的網站,而後根據其更行,自動執行建立。
建立和使用私有倉庫:能夠經過官方提供的registry
鏡像來簡單搭建一套本地私有倉庫環境。python
docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry docker images docker tag ubuntu:14.04 139.196.96.27:5000/test docker push 139.196.xx.xx:5000/test curl http://139.196.xx.xx:5000/v1/search docker pull 139.196.xx.xx:5000/test
Tip:
CURL(CommandLine Uniform Resource Locator):curl是利用URL語法在命令行方式下工做的開源文件傳輸工具。
安裝Docker(Ubuntu16.04),默認安裝在/var/lib/docker
mysql
sudo apt-get install apt-transport-https sudo apt-get update sudo apt-get install -y docker.io
Tip:
在用putty鏈接阿里雲時,常常會斷開,如何解決?
解決方法:在Connection裏面有個Seconds between keepaliaves。這裏就是每間隔指定的秒數,就給服務器發送一個空的數據包,來保持鏈接。以避免登陸的主機那邊在長時間沒接到數據後,會自動斷開SSH的鏈接,設置爲10。
阿里雲購買ECS, 操做系統版本Ubuntu 16.04(LTS)nginx
數據管理:在使用docker過程當中,會涉及查看容器內應用產生的數據,或者數據在多個容器間共享,此時須要管理數據的兩種方式包括數據卷Data Volumes和數據卷容器Data Volume Containers.
數據卷:是一個可供容器使用的特殊目錄,繞過文件系統,具備的特性包括數據卷能夠在容器之間共享和重用、對數據卷的修改會立刻生效、對數據卷的更新不會影響鏡像、卷會一致存在,知道沒有容器使用,相似Linux下對目錄或文件進行mount操做。
在容器內建立一個數據卷:使用training/webapp
鏡像建立一個web容器,並建立一個數據卷掛在到容器的/webapp目錄,docker run -d -P --name web -v /webapp python app.py
。
掛載一個主機目錄做爲數據卷:加載主機的/src/webapp
目錄到容器的/opt/webapp
目錄,docker run -d -P --name web - v /src/webapp:/opt/webapp training/webapp python app.py
。
Tip:編輯工具包括vi或者sed --in-place,推薦掛載目錄而不是文件,由於inode變化會形成docker容器啓動失敗。
數據卷容器:其實就是一個普通的容器,其中會掛載數據卷用戶共享,建立數據庫容器dbdata,以後其餘容器將掛載能夠掛載該數據卷容器中的數據卷。git
docker run -it -v /dbdata --name dbdata ubuntu ls docker run -it --volumes-from dbdata --name db1 ubuntu
利用數據卷容器遷移數據:能夠經過數據卷容器對其中的數據捲進行備份、回覆,以實現數據的遷移。接下來的示例利用ubuntu鏡像建立一個容器worker,使用--volumes-from dbdata
參數掛載dbdata容器的數據卷,
使用-v ${pwd}:/backup
參數來掛載本地的當前目錄到worker容器的/backup
目錄,
容器啓動後,使用tar cvf /backup/backup.tar /dbdata
來說/dbdata
下內容備份爲容器內的/backup/backup.tar
。web
docker run --volumes-from dbdata -v ${pwd}:/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata //恢復,首先建立一個帶有數據卷的容器dbdata2,以後 建立另外一個新的容器,掛載dbdata2容器,並使用untar解壓備份文件到所掛載的容器卷中便可 docker run -v /dbdata --name dbdata2 ubuntu /bin/bash docker run --volumes-from dbdata2 -v ${pwd}:/backup busybox tar xvf /backup/backup.tar
在生產環境,推薦使用分佈式文件系統Ceph、GPFS、HDFS按期對主機的本地數據進行備份。
網絡基礎配置:
端口映射實現訪問容器:在啓動容器時,若是不指定對應參數,在容器外部是沒法經過網絡來訪問容器內的網絡應用和服務的。可使用-p ip:hostPort:containerPort
映射端口,docker logs
查看應用的信息,docker port
查看端口配置。redis
docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
容器互聯實現容器間通訊:容器見的鏈接系統是除了端口映射外另外一種能夠與容器中應用進行交互的方式,它會在源和接受容器間建立一個隧道,接受容器能夠看到源容器制定的信息,好比--link
鏈接應用容器和數據庫容器,這樣能夠保證db的接口不暴露到公網。sql
docker run -d -P --name web training/webapp python app.py docker ps -l docker inspect -f xxx //容器互聯 docker run -d --name db training/postgres docker rm -f web docker run -d -P --name web --link db:db training/webapp python app.py docker ps
Docker經過兩種方式爲容器公開鏈接信息,包括環境變量env
和/etc/hosts文件,經過apt-get install -yqq inetutils-ping
安裝ping。
擴展知識:Docker已有的實現PaaS的項目有Deis、Flynn等,持續集成方面有Drone,管理工具備Citadel, Shipyard, DockerUI等。
基本結構:dockerfile由命令語句組成,支持#開頭的註釋,分爲4個部分,包括基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動執行指令,在docker hub上有不少dockerfile的demo,須要時能夠直接使用。
#基礎鏡像 FROM ubuntu #維護者信息 MAINTAINER xionger xiongere@email.com #鏡像的操做指令 RUN apt-get update && apt-get install -y nginx RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf #容器啓動時執行指令 CMD /usr/sbin/nginx
指令:通常格式爲INSTRUCTION arguments,具體以下所示。
FROM <image>:<tag>
默認的第一條指令
MAINTAINER <name>
維護者信息
RUN <command>
或者RUN ["executable", "param1", "param2"]
,前者將在shell終端中運行命令,即/bin/sh -c
,後者則使用exec
執行。
CMD ["executable", "param1", "param2"]
使用exec
執行,推薦方式。
EXPOSE <port> [<port>..]
告訴Docker服務器容器暴露的端口號,供互聯網系統使用。
ENV <key> <value>
指定一個環境變量,會被後續的RUN
指令使用
ADD <src> <dest>
該命令將複製指定到容器中的
COPY <src> <dest>
複製本地主機<src>
到容器中<dest>
,推薦使用
ENTRYPOINT ["executable", "param1", "param2"]
配置容器啓動後執行的命令,不能被docker run
提供的參數覆蓋
VOLUME ["/data"]
建立一個能夠從本地主機或其餘容器掛載的掛載點,通常用來存放數據庫和須要保持的數據。
USER daemon
指定運行容器時的UID,後續的RUN
也會使用指定用戶,如RUN group add -r postgres && useradd -r -g postgres postgres
,要獲取管理員權限時可使用gosu
而不是sudo
WORKDIR path/to/workdir
爲後續的指令配置工做目錄
ONBUILD [INSTRUCTION]
配置當所建立的鏡像做爲其餘新建立鏡像的基礎鏡像時,所執行的操做指令。
建立鏡像:編寫好dockerfile後,能夠經過docker build
命令來建立鏡像,該命令將讀取指定路徑下(包括子目錄)的dockerfile,並將該路徑下全部內容發送給docker服務端,由服務端來建立鏡像,此外能夠經過.dockerignore
文件來忽略目錄或文件,還能夠經過-t
指定鏡像的標籤信息。示例docker build -t build_repo/first_image /tmp/docker_builder/
操做系統:CentOS和Ubuntu均可以,我的喜愛ubuntu(還能夠選用debian:jessie, alpine),屬於最基礎的鏡像。
tip: 當試圖安裝軟件出現沒有相關包信息時,須要apt-get update
或編輯/etc/apt/sources.list
文件(deb, deb-src
,須要時在查詢,好比163的鏡像,阿里雲的話無需設置),能夠經過netstat -tunlp
查看當前網絡狀況。
支持SSH:當須要直接進入容器進行管理時安裝,沒必要須。
Web服務器與應用(Nginx,可使用淘寶優化的Tengine代替Nginx,Tomcat):在/usr/docker
下建立tomcat
,nginx
目錄應用存放Dockerfile文件,最終仍是選擇經過pull拉去鏡像的方式安裝應用,dockerfile比較複雜。
docker pull nginx:1.12 docker ps -a //-p 80:80:將容器的80端口映射到主機的80端口 //-name mynginx:將容器命名爲mynginx //-v $PWD/www:/www:將主機中當前目錄下的www掛載到容器的/www //-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:將主機中當前目錄下的nginx.conf掛載到容器的/etc/nginx/nginx.conf //-v $PWD/logs:/wwwlogs:將主機中當前目錄下的logs掛載到容器的/wwwlogs docker run --name nginx01 -p 80:80 -v $PWD/www:/www -v $PWD/conf:/etc/nginx -v $PWD/logs:/wwwlogs -d nginx:1.12 docker pull tomcat:8.0 docker run --name tomcat01 -p 8080:8080 -v $PWD/test:/usr/local/tomcat/webapps/test -d tomcat:8.0
tip:
有時可能須要重啓docker服務, service docker restart
,能夠選擇tomcat7.0:jdk1.8
nginx配置詳解
nginx官方文檔
數據庫應用MySQL(5.6), MongoDB(3.2), Redis(3.2)
docker pull mysql
docker run -p 3306:3306 --name mysql01 -v $PWD/conf:/etc/mysql -v $PWD/logs:/logs -v $PWD/data:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -d mysql //主從模式 docker run -p 3306:3306 --name mysql01 -v $PWD/conf01:/etc/mysql -v $PWD/logs01:/logs -v $PWD/data01:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -e REPLICATION_MASTER=true -d mysql docker run -p 3307:3306 --name mysql02 -v $PWD/conf02:/etc/mysql -v $PWD/logs02:/logs -v $PWD/data02:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -e REPLICATION_SLAVE=true --link mysql01:mysql01 -d mysql //mongodb,暫時單機,其默認提供集羣的配置 docker pull mongo:3.2 docker run -p 27017:27017 -p 28017:28017 --name mongodb01 -v $PWD/db01:/data/db -e MONGODN_PASS="123456" -d mongo:3.2 //redis docker pull redis:3.2 docker run -p 6379:6379 --name redis01 -v $PWD/data01:/data -d redis:3.2 redis-server --appendonly yes
tip:能夠進入db的容器進行操做,docker exec -ti mysql /bin/bash
其餘應用:maven, gitlab, jenkins, dubbo, cat,具體內容將在以後的文章中陸續介紹。
docker pull jenkins:2.60.1 docker run --name jenkins01 -p 9090:8080 -p 9091:50000 -v $PWD/jenkins01:/var/jenkins_home -d jenkins:2.60.1
構建Docker容器集羣:核心問題就是讓不一樣主機中的Docker容器相互訪問,簡單的方式包括兩種。使用自定義網橋鏈接跨主機容器,Docker默認的網橋是docker0,能夠經過brctl show
查看。使用Ambassador容器:當2個docker容器再贊成主機時,能夠經過--link相互訪問,若是須要跨主機實現,則須要知道其餘物理主機的IP地址。
Docker CI集成方案:在以後的Jenkins一文中將重點分析。
Tip:目前百度BAE已經在生產環境使用Docker,Airbnb,ebay已使用mesos集成docker部署應用,此外可使用apparmor對容器的能力進行限制。我的目前實踐計劃私有Docker倉庫暫時不創建,先使用DockerHub;Git相似,先使用Github;Maven須要使用Nexus創建一個私有庫;jenkins之間搭建就好。