Docker是一個開源的引擎,能夠輕鬆的爲任何應用建立一個輕量級的、可移植的、自給自足的容器。開發者在筆記本上編譯測試經過的容器能夠批量地在生產環境中部署,包括VMs(虛擬機)、bare metal、OpenStack 集羣和其餘的基礎應用平臺。mysql
web應用的自動化打包和發佈;nginx
自動化測試和持續集成、發佈;web
在服務型環境中部署和調整數據庫或其餘的後臺應用;sql
從頭編譯或者擴展示有的OpenShift或Cloud Foundry平臺來搭建本身的PaaS環境。docker
# yum install docker-io
# systemctl start docker.service
# systemctl enable docker.service
# ifconfigshell
宿主機出現 docker0 的虛擬網絡接口。
docker 代理網絡設置
# vim /etc/sysconfig/docker數據庫
HTTPS_PROXY=http://proxy.sinaabc.com:3128 HTTP_PROXY=http://proxy.sinaabc.com:3128
# docker version //查看docker的版本號,包括客戶端、服務端、依賴的Go等apache
# docker info //查看系統(docker)層面信息,包括管理的images, containers數等ubuntu
鏡像能夠看做是包含有某些軟件的容器系統,好比ubuntu就是一個官方的基礎鏡像,不少鏡像都是基於這個鏡像「衍生」,該鏡像包含基本的ubuntu系統。再好比,hipache是一個官方的鏡像容器,運行後能夠支持http和websocket的代理服務,而這個鏡像自己又基於ubuntu。
搜索鏡像
# docker search ubuntu12.10
下載鏡像
# docker pull ubuntu12.10x64
查看鏡像
# docker images 列出images
# docker images -a 列出全部的images(包含歷史)
# docker images --tree 顯示鏡像的全部層(layer)
# docker rmi <image ID> 刪除一個或多個image
建立容器
# docker run chug/ubuntu12.10x64 /bin/echo hello world
hello worldvim
建立運行不進入交互
# docker run -itd <image> /bin/bash
查看容器
docker ps :列出當前全部正在運行的容器
docker ps -l :只顯示最新建立的容器,包括非運行的。
docker ps -a :顯示全部容器。 默認只顯示運行容器。
docker ps -q :列出最近一次運行的container I D
再次啓動容器
docker start/stop/restart <container> 開啓/中止/重啓container
docker start [container_id] 再次運行某個container (包括歷史container)
docker attach [container_id] 鏈接一個正在運行的container實例(即實例必須爲start狀態,能夠多個窗口同時attach 一個container實例)
docker start -i <container> 啓動一個container並進入交互模式(至關於先start,在attach)
進入容器 (進入前首先要啓動容器)
docker exec -it 19ee6bc10189 /bin/bash
映射 HOST 端口到容器
方便外部訪問容器內服務,host_port 能夠省略,省略表示把 container_port 映射到一個動態端口。
docker run -i -t -p <host_port:container_port>
docker run -i -t -d -p 1200:11211 niexiaohu/centos-memcached
刪除容器
docker rm <container...> 刪除一個或多個container
docker rm `docker ps -a -q` 刪除全部的container
docker ps -a -q | xargs docker rm 同上, 刪除全部的container
檢查運行中的鏡像
docker inspect container_id
發佈docker鏡像
docker push docker.sinaabc.com/centos6
保存對容器的修改
docker commit [container_id] chug/nginx
經過容器生成新的鏡像
使用docker commit <container-id> <image-name> 命令能夠把一個正在運行的容器變成一個新的鏡像, repo:tag可選。
# docker commit d0fd23b8d3ac chug/ubuntu12.10x64_2 daa11948e23d970c18ad89c9e5d8972157fb6f0733f4742db04219b9bb6d063b # docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE chug/ubuntu12.10x64_2 latest daa11948e23d 6 seconds ago 270.3 MB chug/ubuntu12.10x64 latest 0b96c14dafcd 4 months ago 270.3 MB
持久化容器
export命令用於持久化容器
docker export <container_id> > /tmp/export.tar
持久化鏡像
Save命令用於持久化鏡像
docker save image_id > /tmp/save.tar
導入持久化container
# cat /tmp/export.tar | docker import - export:latest
導入持久化image
# docker load < /tmp/save.tar
對image打tag
# docker tag daa11948e23d load:tag
docker logs $CONTAINER_ID 查看docker實例運行日誌,確保正常運行
docker inspect <image|container> 查看image或container的底層信息
docker build <path> 尋找path路徑下名爲的Dockerfile的配置文件,使用此配置生成新的image
docker build -t repo[:tag] 能夠指定repo和可選的tag
docker build - < <dockerfile> 使用指定的dockerfile配置文件,docker以stdin方式獲取內容,使用此配置生成新的image
docker port <container> <container port> 查看本地哪一個端口映射到container的指定端口,其實用docker ps 也能夠看到
docker文件存放目錄
Docker實際上把全部東西都放到 /var/lib/docker路徑下了。
# ls -F
containers/ devicemapper/ execdriver/ graph/ init/ linkgraph.db repositories-devicemapper volumes/
containers目錄固然就是存放容器(container)了,graph目錄存放鏡像,文件層(file system layer)存放在graph/imageid/layer路徑下,這樣咱們就能夠看看文件層裏到底有哪些東西,利用這種層級結構能夠 清楚的看到文件層是如何一層一層疊加起來的。
查看root密碼
docker容器啓動時的root用戶的密碼是隨機分配的。因此,經過這種方式就能夠獲得容器的root用戶的密碼了。
docker logs 5817938c3f6e 2>&1 | grep 'User: ' | tail -n1
Dockerfile 是一個鏡像的表示用來描述構建鏡像的步驟,Docker能夠從文本Dockerfile讀取指令做爲構建步驟並自動生成最終鏡像
指定一個存儲庫和標籤 -t shykes/myapp .
$ sudo docker build -t shykes/myapp .
INSTRUCTION arguments (指令 參數 )
指令是不區分大小寫的,建議指令都大寫,更容易區別於參數, 第一個指令必須「FROM」 以指定構建的基礎鏡像。
以 '#' 開始做爲一個註釋。如:
# Comment RUN echo 'we are running some # of cool things'
FROM
,
MAINTAINER
,
RUN
,
ENTRYPOINT
,
USER
,
ESPOSE
,
ADD
語法: FROM <image> 或 FROM <image>:<tag>
Dockerfile第一個指令必須是 FROM,FROM 能夠出現屢次在單個Dockerfile爲了建立多個鏡像,FROM 後面爲基礎鏡像, 如:
FROM ubuntu
語法: MAINTAINER <name>
MAINTAINER命令用來指定維護者的信息說明:
MAINTAINER Guillaume J. Charmes <guillaume@dotcloud.com>
RUN命令會在上面FROM
指定的鏡像裏執行任何命令,而後提交(commit)結果,生成新的圖層,提交的鏡像會在後面繼續用到。
RUN兩種格式:
一、RUN <command> # 運行一個shell命令
RUN apt-get install -y openssh-server
RUN命令會在上面FROM
指定的鏡像裏執行任何命令,而後提交(commit)結果,生成新的圖層,提交的鏡像會在後面繼續用到。
RUN兩種格式:
一、RUN <command> # 運行一個shell命令
RUN apt-get install -y openssh-server
二、exec 執行方式
語法:RUN ["executable", "param1", "param2" ... ]
RUN ["/bin/bash", "-c", "echo hello"]
CMD主要用於容器啓動時執行啓動服務的命令。Dockerfile 只能有一個CMD,若是有多個CMD則最後的CMD生效。
CMD有三種方式:
一、CMD ["executable","param1","param2"] (使用 exec
執行,推薦方式)
CMD ["/bin/bash", "-c", "echo hello"]
二、 CMD ["param1","param2"] (給 ENTRYPOINT
提供參數 ) 如:
FROM ubuntu CMD ["-D","--help"]
三、 CMD command param1 param2 ( 以」/bin/sh -c」方法執行命令) 如:
CMD echo "This is a test." | wc -
語法:EXPOSE <port> [<port>...]
如:Nginx使用80端口,把這個端口暴露在外,這樣容器外能夠看到這個端口並與其通訊。
EXPOSE 80
ENV指令設置環境變量值
語法: ENV <key> <value>
ENV LANG en_US.UTF-8 ENV APP_DIR /app
複製新文件,並將它們添加到容器的文件系統路徑
語法: ADD <src> <dest>
ADD ./start.sh /root/start.sh
<src>
是相對被構建的源目錄的相對路徑
,能夠是文件或目錄的路徑,也能夠是一個遠程的文件url
<dest>
是container中的絕對路徑.
COPY 做用相似於ADD
語法: COPY <src> <dest>
。
複製本地主機的 <src>
(爲Dockerfile所在目錄的相對路徑)到容器中的 <dest>
。
當使用本地目錄爲源目錄時,推薦使用 COPY
。
意思是進入點,容器啓動時執行命令,一個Dockerfile中只能有一條ENTRYPOINT命令,若是多條則只執行最後一條ENTRYPOINT.
ENTRYPOINT、CMD,通常二者能夠配合使用,CMD提供默認參數,好比:
ENTRYPOINT ["/usr/sbin/sshd"] CMD ["-D"]
ENTRYPOINT 和 CMD的不一樣點在於執行docker run時參數傳遞方式,CMD指定的命令能夠被docker run傳遞的命令覆蓋:
一、CMD 指令:
CMD ["echo"]
運行 :
# docker run container_name echo foo
結果打印出: foo
二、ENTRYPOINT指令:
ENTRYPOINT ["echo"]
運行 :
# docker run container_name echo foo
結果打印出:echo foo
建立一個能夠從本地主機或其餘容器掛載的掛載點,通常用來存放數據庫或須要保存的數據
VOLUME ["/data"]
指定使用哪一個用戶或uid運行鏡像
USER daemon
配置RUN
, CMD
, ENTRYPOINT
命令設置當前工做路徑
WORKDIR /path/to/workdir
語法: ONBUILD [INSTRUCTION]
ONBUILD ADD . /app
ONBUILD 在生成當前docker鏡像的時候不生效,在子鏡像生效;ONBUILD 在產品發佈時起着很是重要的做用。
如:
A鏡像中有ONBUILD指令,在構建A鏡像時ONBUILD指令不執行;B鏡像FROM A ,在構建B鏡像時 ONBUILD 指令開始執行;
1.官方實例:
'#' 爲註釋符,這裏Dockerfile構建4個鏡像,寫好Dockerfile文件後就能夠在該目錄下運行 docker build . 命令了(能夠用 -t 參數指定tag)
# Nginx # # VERSION 0.0.1 FROM ubuntu MAINTAINER Guillaume J. Charmes <guillaume@dotcloud.com> # make sure the package repository is up to date RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update RUN apt-get install -y inotify-tools nginx apache2 openssh-server # Firefox over VNC # # VERSION 0.3 FROM ubuntu # make sure the package repository is up to date RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update # Install vnc, xvfb in order to create a 'fake' display and firefox RUN apt-get install -y x11vnc xvfb firefox RUN mkdir /.vnc # Setup a password RUN x11vnc -storepasswd 1234 ~/.vnc/passwd # Autostart firefox (might not be the best way, but it does the trick) RUN bash -c 'echo "firefox" >> /.bashrc' EXPOSE 5900 CMD ["x11vnc", "-forever", "-usepw", "-create"] # Multiple images example # # VERSION 0.1 FROM ubuntu RUN echo foo > bar # Will output something like ===> 907ad6c2736f FROM ubuntu RUN echo moo > oink # Will output something like ===> 695d7793cbe4 # You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with # /oink. 示例2: 建立 一個運行ssh server鏡像 FROM centos6 # build ssh MAINTAINER niexiaohu niexiaohu@yolo24.com RUN echo "root:123456" | chpasswd RUN yum install openssh-server RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key ENTRYPOINT ["/usr/sbin/sshd"] CMD ["-D"] # CMD /usr/sbin/sshd -D EXPOSE 22
在一個 container中部署兩個以上服務程序的狀況和需求上,由於Dockerfile只容許執行一個CMD,這種狀況下須要藉助supervisor進程監控管理程序來啓動和管理container 內的多個程序。
一、建立Dockerfile:
FROM centos:centos6 MAINTAINER xxx xxxx "xxxx@hotmail.com" RUN rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm RUN yum install -y openssh-server sudo mysql-server mysql supervisor RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config RUN useradd admin RUN echo "admin:admin" | chpasswd RUN echo "admin ALL=(ALL) ALL" >> /etc/sudoers RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key RUN mkdir /var/run/sshd RUN /etc/init.d/mysqld start &&\ mysql -e "grant all privileges on *.* to 'root'@'%' identified by 'letmein';"&&\ mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by 'letmein';"&&\ mysql -u root -pletmein -e "show databases;" RUN mkdir -p /var/log/supervisor COPY supervisord.conf /etc/supervisord.conf EXPOSE 22 3306 CMD ["/usr/bin/supervisord"]
二、在Dockerfile所在目錄下建立supervisord.conf文件
[supervisord] nodaemon=true [program:sshd] command=/usr/sbin/sshd -D [program:mysqld] command=/usr/bin/mysqld_safe
3.在Dockerfile 當前目錄執行命令生成image.
# sudo docker build -t myserver .
一、建立maven-demo和maven-repo目錄用做docker volume,這樣Maven建立的項目會持久化在maven-demo目錄下,maven的local repository持久話在maven-repo目錄下。
$ mkdir maven-demo maven-repo
二、運行maven docker新建一個Maven項目
$ docker run -it --rm --name maven-demo -v "$PWD"/maven-demo:/usr/src/maven-demo -v "$PWD"/maven-repo/:/root/.m2/repository -w /usr/src/maven-demo maven:3 mvn -B archetype:generate -DgroupId=com.aliyun.demo -DartifactId=hello-world -DarchetypeArtifactId=maven-archetype-webapp
運行成功後,能夠看到項目目錄結構以下:
hello-world
|---pom.xml
|---src
|---main
|---resource
|---webapp
|---WEB-INF
| |---web.xml
|---index.jsp
三、構建Maven項目
$ docker run -it --rm --name maven-demo -v "$PWD"/maven-demo/:/usr/src/maven-demo -v "$PWD"/maven-repo/:/root/.m2/repository -w /usr/src/maven-demo/hello-world maven mvn package
構建成功後,hello-world目錄下多了一個target目錄,包含hello-world.war文件。
四、Docker鏡像打包:使用Docker運行Java Web應用,推薦基於Tomcat的Docker容器來打包、運行您的Java應用,選擇Tomcat的Docker基礎鏡像上構建應用鏡像。
Dockerfile以下所示:
FROM tomcat:8 ADD maven-demo/hello-world/target/hello-world.war /usr/local/tomcat/webapps/ CMD ["catalina.sh", "run"]
五、打包鏡像
$ docker build -t docker.sinaabc.com/maven-demo-hello-world .
六、上傳到registry
$ docker push docker.sinaabc.com/maven-demo-hello-world
七、另一臺機器上獲取鏡像
$ docker pull docker.sinaabc.com/maven-demo-hello-world
八、運行Docker鏡像
$ docker run -d -p 8080:8080 docker.sinaabc.com/maven-demo-hello-world
打開瀏覽器訪問 http://hostip:8080/hello-world/ 將會看到 Hello World! 的輸出,表示編譯的hello-world war 包已經成功使用 Docker 運行起來了。
FROM tomcat:8 ADD your.war /usr/local/tomcat/webapps/
使用這樣的Dockerfile構建出數據容器,並將它的volume與Tomcat容器共享。
$ docker build -t app-image . $ docker create -d -v /usr/local/tomcat/webapps/ --name app app-image true $ docker run -d --volumes-from app tomcat:8
因爲系統必定會把共享volume的容器調度運行在同一臺宿主機上,這樣能夠保證正確運行。然而,因爲共享volume的容器只能被調度到同一臺宿主機上,這樣會限制系統的可伸縮性。