目录
通过已有的镜像容器来创建镜像
docker commit [选项] 容器id/容器名 仓库名:标签
常用选项
通过导入操作系统模板文件生成新的镜像,模板可以从开源项目中下载
wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
下载后导入镜像
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:标签
通过编写dockerfile文件来创建镜像
UnionFS( 联合文件系统):Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。
Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
在docher镜像的最底层是bootfs,这一层与我们典型的Linu/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, Centos等等。
我们可以理解成一开始内核里什么都没有,操作一个命令下载debin,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在nocer 的体系里把这些rootis叫lhcocker的镜像。但是,此时的每一层srotfe都是read-onlty的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将ocker镜像进行实例化,系统会在一层或是多层read-only的rotis之上分配一层空的read-write的rootfs。
dockerfile结构大致分为:基础镜像信息、维护者信息、镜像操作指令和容器启动指令。dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以#开头的注释
在编写Dockerfile时,有严格的格式需要遵循: ·第一行必须使用FROM指令指明所基于的镜像名称; 之后使用 MAINTAINER指令说明维护该镜像的用户信息;
然后是镜像操作相关指令,如 RUN指令。每运行一条指令,都会给基础镜像添加新的一层。
最后使用 CMD指令指定启动容器时要运行的命令操作。
dockerfile的镜像分层
镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上i面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果则除了容器,也就融除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。
dockerfile常用指令
| 指令 | 含义 |
|---|---|
| FROM [镜像] | 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
| MAINTAINER [名字] | 说明新镜像的维护人信息 |
| RUN [命令] | 在所基于的镜像执行命令,并提交到新的镜像中 |
| CMD [“要运行的程序”,“参数1”、“参数2”] | 指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条 |
| EXPOSE [端口号] | 指定新镜像加载到Docker时要开启的端口 |
| ENV [环境变量] [变量值] | 设置一个环境变量的值,会被后面的RUN使用 |
| ADD [源文件/目录] [目标文件/目录] | 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩 |
| COPY [源文件/目录] [目标文件/目录] | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
| VOLUME [“目录”] | 在容器中创建一个挂载点 |
| USER [用户名/UID] | 指定运行容器时的用户 |
| WORKDIR [路径] | 为后续的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径 |
| ONBUILD [命令] | 指定所生成的镜像作为一个基础镜像时所要运行的命令(是一种优化) |
| HEALTHCHECK | 健康检查 |
使用dockerfile创建ssh镜像
- -----------------------构建SSH镜像-------------------------
- mkdir /opt/sshd
- cd /opt/sshd
-
- vim Dockerfile
- #第一行必须指明基于的基础镜像
- FROM centos:7
- #作者信息
- MAINTAINER this is ssh image <wl>
- #镜像的操作指令
- RUN yum -y update
- RUN yum -y install openssh* net-tools lsof telnet passwd
- RUN echo 'abc1234' | passwd --stdin root
- RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config #不使用PAM认证
- RUN sed -ri '/^session\s+required\s+pam_loginuid.so/ s/^/#/' /etc/pam.d/sshd #取消pam限制
- RUN ssh-keygen -t rsa -A #生成密钥认证文件
- RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
- EXPOSE 22
- CMD ["/usr/sbin/sshd" , "-D"] #/usr/sbin/sshd -D 用于前台启动sshd服务
-
-
- //生成镜像
- docker build -t sshd:centos .
CMD指令可以指定容器启动时要执行的命令,但它可以被docker run命令的参数覆盖掉。
ENTRYPOINT指令也可指定容器启动时要执行的命令。如果dockerfile中也有CMD指令,CMD中的参数会被附加到ENTRYPOINT 指令的后面。 如果这时docker run命令带了参数,这个参数会覆盖掉CMD指令的参数,并也会附加到ENTRYPOINT 指令的后面。
ADD和COPY都是复制宿主机文件到镜像内部,但是ADD复制tar包时可以自动解压,COPY命令不行
ADD支持从网络源下载文件到镜像内,COPY不支持。当ADD下载tar包时,不会进行解压。