资讯专栏INFORMATION COLUMN

Flux7 Docker 系列教程(三):使用 Dockerfile 实现自动化

wemall / 3264人阅读

摘要:更多的内容可以参考深入理解一命令参考的用法咧实例的写法已经讲述完毕,这儿有一个示例的指定系统我抄的他的创建私钥修复登录,否则登陆后的用户会被秒退。

  

本系列教程翻译自 Flux7 Docker Tutorial Series,系列共有九篇,本文译自第三篇 Part 3: Automation is the Word Using DockerFile。
该系列所有文章将参考其他学习资料翻译,也会加入自己的学习作为部分注解。如有错误,欢迎指正。

上篇文章介绍的是 15 个 Docker 基础命令,在手动创建镜像的时候会有用到,例如 pull,commit,push,但是当需要执行的命令很多时,是不太可能逐一执行 Docker 命令进行镜像初始化的,于是就此产生了 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 ,例如 FROM ubuntu

所有的 Dockerfile 都用该以 FROM 开头,FROM 命令指明 Dockerfile 所创建的镜像文件以什么镜像为基础,FROM 以后的所有指令都会在 FROM 的基础上进行创建镜像;可以在同一个 Dockerfile 中多次使用 FROM 命令用于创建多个镜像。

MAINTAINER 命令

MAINTAINER 用于指定镜像创建者和联系方式。

例如

MAINTAINER Victor Coisne victor.coisne@dotcloud.com
RUN 命令

RUN 用于容器内部执行命令。每个 RUN 命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。

ADD 命令

ADD 用于从将 文件复制到 文件: 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件 url, 是容器中的绝对路径。

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,如果有多个,则最后一个生效。

关于 CMDENTRYPOINT 的联系请看下面的例子
仅仅使用 ENTRYPOINT

FROM ubuntu
ENTRYPOINT ls -l

执行 docker run 306cd7e8408b /etc/fstabdocker 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 作为容器的入口,使用 CMDENTRYPOINT 增加默认选项

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 [...] 命令用来指定对外开放的端口。
例如 EXPOSE 80 3306,开放 803306 端口。

WORKDIR命令

WORKDIR /path/to/work/dir 配合 RUNCMDENTRYPOINT 命令设置当前工作路径。
可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认路径为/

例如:

FROM ubuntu
WORKDIR /etc
WORKDIR ..
WORKDIR usr
WORKDIR lib
ENTRYPOINT pwd

docker run ID 得到的结果为:/usr/lib

USER命令

USER 为容器内指定 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 
#我抄的他的 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@sessions*requireds*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 形式的 CMDENTRYPOINT

  

注:映射端口并不属于 Dockerfile 的工作范围。

下篇文章将会介绍 Docker Registry 和 Workflows。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26394.html

相关文章

  • Flux7 Docker 系列教程):使用 Dockerfile 实现动化

    摘要:更多的内容可以参考深入理解一命令参考的用法咧实例的写法已经讲述完毕,这儿有一个示例的指定系统我抄的他的创建私钥修复登录,否则登陆后的用户会被秒退。 本系列教程翻译自 Flux7 Docker Tutorial Series,系列共有九篇,本文译自第三篇 Part 3: Automation is the Word Using DockerFile。 该系列所有文章将参考其他学...

    CoffeX 评论0 收藏0
  • Flux7 Docker 系列教程(九):用于镜像操作的 10 个 Docker Remote AP

    摘要:本系列教程翻译自,系列共有九篇,本文译自原教程最后一篇。本文介绍十个专门用于操作镜像的。用法获取名叫的镜像。操作中带有的情况下,是需要非常小心的。或者不传入,而是用参数指定一个,这种情况下不要求格式。 本系列教程翻译自 Flux7 Docker Tutorial Series,系列共有九篇,本文译自原教程最后一篇 Part 9: 10 Docker Remote API Comm...

    inapt 评论0 收藏0
  • Flux7 Docker 系列教程(九):用于镜像操作的 10 个 Docker Remote AP

    摘要:本系列教程翻译自,系列共有九篇,本文译自原教程最后一篇。本文介绍十个专门用于操作镜像的。用法获取名叫的镜像。操作中带有的情况下,是需要非常小心的。或者不传入,而是用参数指定一个,这种情况下不要求格式。 本系列教程翻译自 Flux7 Docker Tutorial Series,系列共有九篇,本文译自原教程最后一篇 Part 9: 10 Docker Remote API Comm...

    SmallBoyO 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<