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的容器只能被调度到同一台宿主机上,这样会限制系统的可伸缩性。