这里写目录标题
- 一、Docker镜像的分层
- (一)概述
- docker镜像
- docker镜像的创建方法
- 镜像分层原则
- 镜像分层结构
- (二)dockerfile结构
- (三)dockerfile操作指令
- 二、编写ssh dockerfile
- 三、tomcat的dockerfile
- 四、nginx的dockerfile及其优化(减小镜像的大小)
- (一)常规写法
- (二)nginx —dockerfile优化
一、Docker镜像的分层
(一)概述
docker镜像
- 应用发布的标准格式
- 支撑一个docker容器的运行
docker镜像的创建方法
- 基于已有镜像创建
- 基于本地模板创建
- 基于Dockerfile创建
镜像分层原则
- Dockerfile中的每个指令都会创建一个新的镜像层
- 镜像层将被缓存和服用
- 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像是指定的变量不同了,对应的镜像镜像层就会失效
- 某一层的镜像缓存失效后它之后的镜像层缓存都会失效
- 镜像层是不可变的,如果在某一层中添加一个文件,然后再下一层中删除,则镜像中依然会包含该文件
镜像分层结构
1.(内核层):由AUFS,LXC,Bootfs(boot file system)组成为上层的镜像提供kernel内核支持
- AUFS是一个联合文件系统,它使用同一个Linux host上的多个目录,逐个堆叠起来,对外呈现出一个统一的文件系统。AUFS使用该特性,实现了Docker镜像的分层 分层的思想
- bootfs:负责与内核交互 主要是引导加载kernel,linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层时bootfs,这一层与经典的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统就会卸载bootfs
- rootfs(root file system)属于base images 在bootfs之上(base images)比如在linux系统中包含/dev,/proc,/bin,/etc等标准目录和文件,包含创建、启动操作系统的一些必要的组件,rootfs就是各个不同的操作系统的发行版本,比如Ubuntu,CentOS等等
- lxc早期的内核引擎与docker引擎对接交互,docker提供一些库文件和引导文件。现在docker自身内置了所需要的lib库
2.base image(基础/系统镜像层):构建镜像运行的操作系统环境
3.add image(run指令运行的镜像层):比如nginx镜像的yum安装模块,或者nginx编译安装的指令,使用镜像封装每一个run执行命令
4.Container(可读写执行层):将下面的镜像组合运行提供给docker client使用
总结
1.docker镜像层位于bootfs之上
2.每一层镜像成为base image/底包(操作系统环境变量)比如centos dbian
3.容器层(可读可写),在最顶层。是docker server提供给docker client
4.容器层以下都是readonly只读,docker将readonly的FS层成为image
为什么docker的centos镜像只有200M就是因为一个精简的os,rootfs可以很小,之许哟啊将基础命令,工具和程序库就可以了,因为底层直接用host的kernel,自己只需要提供rootfs继续。由此可见不同的linux发现版本,bootfs基本一致,rootfs会有差别,不同的发现版本可以公用bootfs
补充
每次图送至docker hub 公有仓库只会推送增量部分(毕竟底包比较大,增量推送/更新部分比较小)所以生产环境中只要执行镜像再推送的时候增量部分控制到比较小的范围就可以
(二)dockerfile结构
1.基础镜像信息(指定操作系统镜像是什么镜像,什么版本)
2.维护者信息
3.镜像操作指令
4.容器启动时执行的命令
dockerfile 每行支持一条指令,每条指令可以携带多个参数,支持使用以“#”开头的注释
(三)dockerfile操作指令
指令 | 含义 |
FROM 镜像 | 指定新镜像所基于的操作系统镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER + 名字 | 说明新镜像的维护人信息 |
RUN + 命令 | 在所基于的镜像执行命令,并提交到新的镜像中(每写一条指令都会创建一个镜像层) |
CMD + [“要运行的程序”,“参数1”、“参数2”] | 指令启动容器时要运行的命令或者脚本(例如 CMD [“run.sh”]),Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条 |
EXPOSE + 端口号 | 指定新镜像加载到Docker时要开启的端口 |
ENV + 环境变量 + 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ADD + 源文件/目录 + 目标文件/目录 | 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩 |
COPY + 源文件/目录 + 目标文件/目录 | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
VOLUME + [“目录”] | 在容器中创建一个挂载点(VOLUME ["/目录"] ) |
USER + 用户名/UID | 指定运行容器时的用户(在编写mysql es mg数据库镜像文件时可能需要时用对用户授权) |
WORKDIR + 路径 | 为下一步的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径 |
ONBUILD + 命令 | 指定所生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK | 健康检查 |
CMD与ENTRYPOINT的区别
ENTRYPOINT类似于 CMD 指令,但其不会被 docker run 运行容器并且执行的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程,CMD相反,会被docker run指定命令覆盖
CMD和ENTRYPOINT可以联合使用
COPY与ADD的区别
- 在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>,ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定
二、编写ssh dockerfile
mkdir ssh
cd sshd
vim Dockerfile
FROM centos:7
RUN yum -y update
RUN yum -y install openssh* net-tool lsof telnet passwd
RUN echo '123456' | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
#生成镜像
docker build -t sshd:v1 。
#启动容器并修改root密码
dockers run -d -P sshd:v1
ssh localhost -p 端口
三、tomcat的dockerfile
FROM centos:7
ADD apache-tomcat-9.0.16.tar.gz /opt
ADD jdk-8u201-linux-x64.rpm /opt
WORKDIR /opt
RUN rpm -ivh jdk-8u201-linux-x64.rpm
ENV JAVA_HOME /usr/java/jdk1.8.0_201-amd64
ENV CLASSPATH $JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
ENV PATH /usr/java/jdk1.8.0_201-amd64/bin:$PATH
RUN mv apache-tomcat-9.0.16 /opt/tomcat
CMD ["/opt/tomcat/bin/catalina.sh","run"]
docker -d run -p 8080:8080 tomcat:v1 #开启容器
四、nginx的dockerfile及其优化(减小镜像的大小)
(一)常规写法
方法一:
[root@localhost ~]#cd nginx
[root@localhost nginx]#ls
Dockerfile nginx-1.12.0.tar.gz
[root@localhost nginx]#vim Dockerfile
FROM centos:7
ADD nginx-1.12.0.tar.gz /opt
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null
RUN useradd -M -s /sbin/nologin nginx
WORKDIR /opt/nginx-1.12.0
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
RUN make &> /dev/null && make install &> /dev/null
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
方法二:
FROM centos:7
MAINTAINER gt
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.0.tar.gz /opt/
WORKDIR /opt/nginx-1.12.0
WORKDIR nginx-1.12.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"] #调用脚本
#编写CMD中的nginx启动命令脚本
[root@localhost nginx1]#ls
Dockerfile nginx-1.12.0.tar.gz run.sh
[root@localhost nginx1]#vim run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
(二)nginx —dockerfile优化
1.将不需要输出的指令放入/dev/null文件黑洞中
2.减少RUN指令
3.多阶段构建
[root@localhost ~]#cd nginx3
[root@localhost nginx3]#ls
Dockerfile nginx-1.12.0.tar.gz
[root@localhost nginx3]#vim Dockerfile
[root@localhost nginx3]#vim Dockerfile
FROM centos:7
ADD nginx-1.12.0.tar.gz /opt
WORKDIR /opt/nginx-1.12.0
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null \
&& yum clean all &>/dev/null \
&& useradd -M -s /sbin/nologin nginx &> /dev/null \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx &> /dev/null \
&& make &> /dev/null && make install &> /dev/null \
&& rm -rf /mnt/nginx-1.12.0
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
多阶段构建
FROM centos:7 as build
ADD nginx-1.12.0.tar.gz /opt
WORKDIR /opt/nginx-1.12.0
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null \
&& yum clean all &>/dev/null \
&& useradd -M -s /sbin/nologin nginx &> /dev/null \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx &> /dev/null \
&& make &> /dev/null && make install &> /dev/null \
&& rm -rf /mnt/nginx-1.12.0
FROM centos:7
EXPOSE 80
COPY --from=build /usr/local/nginx /usr/local/nginx #使用之前构建的环境
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]