使用 Dockerfile 实现自动化
2016-07-19 11:38
956 查看
转载自:https://segmentfault.com/a/1190000002711357
Docker 提供的 Dockerfile 是一个类似
注:原文 不太直观,而且很多细节没有讲清楚,因此只取原文中有用的部分,参考其他文章总结出本文。
贴一个 Dockerfile 的实例然后开始正文:
指令(INSTRUCTION)不分大小写,但是推荐大写。
所有的 Dockerfile 都用该以
例如
一个 Dockerfile 中只能有一个
一个 Dockerfile 中只能有一个
关于
仅仅使用
执行
但是我们通常使用
然后执行这个容器:
不加参数便会默认有
加了
例如
可以设置多次,如果是相对路径,则相对前一个
例如:
更多的内容可以参考
深入理解 Docker Volume(一)
把维护者和更新系统的命令依次写在最上方
使用标签管理 Dockerfile
避免映射公共端口
使用类似
注:映射端口并不属于 Dockerfile 的工作范围。
Docker 提供的 Dockerfile 是一个类似
Makefile的工具,主要用来自动化构建镜像。既然能自动化创建镜像,那么我们何必去手动创建镜像呢。本文用来讲解 Dockerfile 的用法、语法,并且提供一个实例用以更深入地了解 Dockerfile。
注:原文 不太直观,而且很多细节没有讲清楚,因此只取原文中有用的部分,参考其他文章总结出本文。
贴一个 Dockerfile 的实例然后开始正文:
# Memcached # # VERSION 2.2 # use the ubuntu base image provided by dotCloud FROM ubuntu MAINTAINER Victor Coisne victor.coisne@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 # install memcached RUN apt-get install -y memcached # Launch memcached when launching the container ENTRYPOINT ["memcached"] # run memcached as the daemon user USER daemon # expose memcached port EXPOSE 11211
格式
Dockerfile 中所有的命令都是以下格式:INSTRUCTION argument
指令(INSTRUCTION)不分大小写,但是推荐大写。
FROM 命令
FROM <image name>,例如
FROM ubuntu
所有的 Dockerfile 都用该以
FROM开头,
FROM命令指明 Dockerfile 所创建的镜像文件以什么镜像为基础,
FROM以后的所有指令都会在
FROM的基础上进行创建镜像;可以在同一个 Dockerfile 中多次使用
FROM命令用于创建多个镜像。
MAINTAINER 命令
MAINTAINER <author name>用于指定镜像创建者和联系方式。
例如
MAINTAINER Victor Coisne victor.coisne@dotcloud.com
RUN 命令
RUN <command>用于容器内部执行命令。每个
RUN命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。
ADD 命令
ADD <src> <dst>用于从将
<src>文件复制到
<dst>文件:
<src>是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件 url,
<dst>是容器中的绝对路径。
CMD 命令
CMD命令有三种格式:
CMD ["executable","param1","param2"]:推荐使用的 exec 形式。
CMD ["param1","param2"]:无可执行程序形式
CMD command param1 param2:shell 形式。
CMD命令用于启动容器时默认执行的命令,
CMD命令可以包含可执行文件,也可以不包含可执行文件:不包含可执行文件的情况下就要用
ENTRYPOINT指定一个,然后
CMD命令的参数就会作为
ENTRYPOINT的参数。
一个 Dockerfile 中只能有一个
CMD,如果有多个,则最后一个生效。
CMD的 shell 形式默认调用
/bin/sh -c执行命令。
CMD命令会被 Docker 命令行传入的参数覆盖:
docker run busybox /bin/echo Hello Docker会把
CMD里的命令覆盖。
ENTRYPOINT 命令
ENTRYPOINT命令的字面意思是进入点,而功能也恰如其意:他可以让你的容器表现得像一个可执行程序一样。
ENTRYPOINT命令也有两种格式:
ENTRYPOINT ["executable", "param1", "param2"]:推荐使用的 exec 形式
ENTRYPOINT command param1 param2:shell 形式
一个 Dockerfile 中只能有一个
ENTRYPOINT,如果有多个,则最后一个生效。
关于
CMD和
ENTRYPOINT的联系请看下面的例子
仅仅使用
ENTRYPOINT:
FROM ubuntu ENTRYPOINT ls -l
执行
docker run 306cd7e8408b /etc/fstab和
docker run 306cd7e8408b结果并不会有什么差别:
命令 # docker run 306cd7e8408b /etc/fstab total 64 drwxr-xr-x 2 root root 4096 Mar 20 05:22 bin drwxr-xr-x 2 root root 4096 Apr 10 2014 boot drwxr-xr-x 5 root root 360 Apr 24 02:52 dev drwxr-xr-x 64 root root 4096 Apr 24 02:52 etc drwxr-xr-x 2 root root 4096 Apr 10 2014 home ……
但是我们通常使用
ENTRYPOINT作为容器的入口,使用
CMD给
ENTRYPOINT增加默认选项:
FROM ubuntu CMD ["-l"] ENTRYPOINT ["ls"]
然后执行这个容器:
不加参数便会默认有
-l参数:
命令 # docker run 89dc7e6d0ac1 total 64 drwxr-xr-x 2 root root 4096 Mar 20 05:22 bin drwxr-xr-x 2 root root 4096 Apr 10 2014 boot drwxr-xr-x 5 root root 360 Apr 24 02:47 dev drwxr-xr-x 64 root root 4096 Apr 24 02:47 etc drwxr-xr-x 2 root root 4096 Apr 10 2014 home drwxr-xr-x 12 root root 4096 Mar 20 05:21 lib drwxr-xr-x 2 root root 4096 Mar 20 05:20 lib64 drwxr-xr-x 2 root root 4096 Mar 20 05:19 media drwxr-xr-x 2 root root 4096 Apr 10 2014 mnt drwxr-xr-x 2 root root 4096 Mar 20 05:19 opt dr-xr-xr-x 386 root root 0 Apr 24 02:47 proc drwx------ 2 root root 4096 Mar 20 05:22 root drwxr-xr-x 7 root root 4096 Mar 20 05:21 run drwxr-xr-x 2 root root 4096 Apr 21 22:18 sbin drwxr-xr-x 2 root root 4096 Mar 20 05:19 srv dr-xr-xr-x 13 root root 0 Apr 24 02:47 sys drwxrwxrwt 2 root root 4096 Mar 20 05:22 tmp drwxr-xr-x 11 root root 4096 Apr 21 22:18 usr drwxr-xr-x 12 root root 4096 Apr 21 22:18 var
加了
/etc/fstab参数便会覆盖原有的
-l参数:
命令 # docker run 89dc7e6d0ac1 /etc/fstab /etc/fstab
EXPOSE 命令
EXPOSE <port> [<port>...]命令用来指定对外开放的端口。
例如
EXPOSE 80 3306,开放
80和
3306端口。
WORKDIR命令
WORKDIR /path/to/work/dir配合
RUN,
CMD,
ENTRYPOINT命令设置当前工作路径。
可以设置多次,如果是相对路径,则相对前一个
WORKDIR命令。默认路径为
/。
例如:
FROM ubuntu WORKDIR /etc WORKDIR .. WORKDIR usr WORKDIR lib ENTRYPOINT pwd
docker run ID得到的结果为:
/usr/lib
USER命令
USER <UID/Username>为容器内指定
CMD
RUN
ENTRYPOINT命令运行时的用户名或UID。
VLOUME 命令
VOLUME ['/data']允许容器访问容器的目录、允许容器之间互相访问目录。
VOLUME仅仅是允许将某一个目录暴露在外面,更多的操作还需要依赖
Docker命令实现。
更多的内容可以参考
深入理解 Docker Volume(一)
ENV 命令
参考export的用法咧:
ENV LC_ALL en_US.UTF-8
实例
Dockerfile 的写法已经讲述完毕,这儿有一个示例的 Dockerfile:#Dockerfile FROM centos6-base #指定centos6系统 MAINTAINER zhou_mfk <zhou_mfk@163.com> #我抄的他的 Dockerfile RUN ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key #创建私钥 RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd #修复SSH登录,否则登陆后的用户会被秒退。 RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh #创建root用户的ssh文件夹 EXPOSE 22 #开放端口 RUN echo 'root:redhat' | chpasswd #root用户改密码为redhat RUN yum install -y yum-priorities && rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 RUN yum install tar gzip gcc vim wget screen -y #安装epel和安装一些软件 ENV LANG en_US.UTF-8 ENV LC_ALL en_US.UTF-8 #系统环境变量 CMD ["/usr/sbin/sshd", "-D"] #启动sshd #End
最佳实践
所有应用都会有个最佳的方式,Dockerfile 也不例外,下面是我们总结出的最佳实现方式:把维护者和更新系统的命令依次写在最上方
使用标签管理 Dockerfile
避免映射公共端口
使用类似
array形式的
CMD和
ENTRYPOINT
注:映射端口并不属于 Dockerfile 的工作范围。
相关文章推荐
- Dockerfile详解
- 10张图带你深入理解Docker容器和镜像
- Docker化运维方式讲解
- docker 初步
- Dockerfile指令
- docker 集群
- consul docker register
- Docker 之 cgroup篇
- 利用dockerize模板为容器内应用生成配置文件和环境变量
- Docker Tips: 在windows 上Dockerfile 参数中路径问题
- Docker有什么好处?
- Play with docker 1.12
- 企业级云应用平台的实践和思考
- 解决普通用户无法使用docker命令的问题
- Jenkins+Docker搭建持续集成测试环境
- docker最初版本源码分析
- docker启动虚拟机、启动服务
- docker(4):coreos+docker+rancher真厉害
- DOCKER学习笔记(MAC)
- Docker 简介