在学习这个之前,其实有一个mysql主从复制,但是主从复制这些偏离了渗透测试的范畴。暂时不学。
暂时记住一句话就好:平常我们在开发的时候,不可能仅仅是一台数据库服务器,最低的标配就是一主一从。
0x00 背景复习
我们在创建一个新的镜像的时候,是用的docker commit功能。新的ubuntu不含有一些功能,我们就需要安装一些新的功能,然后再commit出新的镜像。
docker commit -m="vim ubuntu" -a="sukusec" 容器ID u1/ubuntu:18.04
但是我们在实战的时候,都是随时变化的标准,能不能给我个list?让我一次性都安装?好比点菜,一会儿点一个一会儿点一个,不麻烦吗?How?
0x01 Dockerfile简介
是什么?
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本,可类比Linux的shell脚本。
在哪里能学习?
https://docs/docker.com/enginie/reference/builder/
Dockerfile内容基础知识
1、每条保留字指令都必须为大写字母且后面要跟随至少一个参数。下图画红框的就是保留字指令。
2、指令按照从上到下,顺序执行
3、#表示注释
4、每条指令都会创建一个新的镜像层并对镜像进行提交
小总结
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
1、Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何涉及namespace的权限控制)等等;
2、Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时会真正开始提供服务;
3、Docker容器,容器是直接提供服务的。
0x02 Docker常用保留字指令
参考tomcat8
的dockerfile
入门——https://github.com/docker-library/tomcat
镜像反过来解析,其实就是dockerfile
,docker run
就相当于执行下方的CMD
1、FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模版,第一条必须是from
2、MAINTAINER(维护者)
镜像维护者的姓名和邮箱地址
3、RUN
容器构建时需要运行的命令
shell格式
RUN yum -y install vim
exec格式
4、EXPOSE
容器暴露的端口,这也就是为什么我们可以通过-p
来指定端口
5、WORKDIR
指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点。
这就是为什么有时候我们exec
到tomcat
的落脚点和ubunutu
的不一样
6、USER
指定该镜像以什么样的用户去执行,如果都不指定,默认就是root
。没必要在容器里面创建什么用户来搞权限,没必要。
7、ENV
用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何run指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量。如:WORKDIR $MY_PATH
8、volume
容器数据卷,用于数据保存和持久化工作,相当于-v
9、ADD、COPY
这两个命令字基本一样,习惯用ADD就行。
ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
COPY:类似于ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置,相当于docker cp
10、CMD
指定容器启动后要干的事情。可以有多个CMD指令,但是只有最后一个生效,CMD会被docker run之后的参数替换。
在tomcat官方的dockerfile中,CMD
启动了tomcat。如果我们在启动tomcat后面加上/bin/bash
即下图这样子,那么就相当于添加了个CMD ["/bin/bash","run]
,那么就相当于替换了之前的命令。就无法正常启动tomcat了。
与RUN命令的区别
CMD是在docker run时运行,RUN是在docker build时运行。
11、ENTRYPOINT
命令格式:ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
。ENTRYPOINT
可以和CMD一起用,一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT
传参。当指定了ENTRYPOINT
后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成<ENTRYPOINT>"<CMD>"
也是用来指定一个容器启动时要运行的命令。类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令的程序。
案例如下:假设已经通过Dockerfile构建了nginx:test镜像
FROM nginx
ENTRYPOINT ["nginx","-c"] #定参
CMD ["/etc/nginx/nginx.conf"] #变参
是否传参 | 按照dockerfile编写执行 | 传参执行 |
---|---|---|
Docker命令 | docker run nginx:test | dcoker run nginx:test -c /etc/nginx/new.conf |
衍生出的实际命令 | nginx -c /etc/nginx/nginx.conf | nginx -c /etc/nginx/new.conf |
0x03 Dockerfile构建解析
1、定义需求
2、编写Dockerfile文件
3、docker build命令构建镜像
4、docker run运行新构建的镜像
我们pull的centos中肯定不具有一些功能,例如vim,ifconfig,java8之类的。
相当于我们在电脑上安装了一个什么软件都没有的新系统,然后安装了微信,qq等之后,我们再将安装好的微信和qq的版本制作成一个系统。
1、需求
Centos7
镜像具备vim+ifconfig+jdk8
2、编写
准备编写Dockerfile
文件,注意Dockerfile
的D
一定要大写。新建一个Dockerfile
文件
vim Dockerfile
然后直接复制下段代码粘贴到文件中
#继承镜像
FROM centos
#指定作者邮箱
MAINTAINER zzyy<zzyybs@126.com>
#登陆后进入/usr/local路径
ENV MYPATH /usr/local
WORKDIR $MYPAYTH
#安装vim编辑器,shell格式,等同于在linux终端操作的shell命令
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8以及lib库,标准的java安装,glibc.i686可以认为是gcc的加强包
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置。ADD的意思就是将文件打入系统并且自动解压tar文件在/usr/local/java/下
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
#暴露端口,可写可不写
EXPOSE 80
CMD echo $MYPATH
CMD echo "success----------------------ok"
CMD /bin/bash
3、构建
准备好之后,时间可能会很长
docker build -t 新镜像名字:TAG .
#注意,TAG空格后面有一个点
#-t 可以通过docker build --help 查看,这里是target的意思
docker build -t centosjava8:1.5 .
docker images
4、运行
docker run -it centosjava8:1.5 /bin/bash
vim
ifconfig
java -version
#进行检验
5、发布
随后可以自行发布到阿里云或者私有库,这样研发出一个新的研发平台,这是对新员工非常友好的一件事情。只需要拉取即可。
0x04 回顾UnionFS(联合文件系统)
通过刚才build Dockerfile文件,可以看出来是一层一层的堆叠起来了。
0x05 虚悬镜像
1、是什么?
仓库名、标签都是<none>
的镜像,俗称dangling image
。就是在构建或者删除镜像时出现的一些错误,导致仓库和标签都是none
的镜像。
这玩意儿可能会在系统中出现,所以要及时的查看docker images
。它的存在会使得系统出现风险,还是占据空间,本身就是错乱的。
2、Dockerfile写一个?
vim Dockerfile
=============================
from ubuntu
CMD echo 'action is success'
=============================
docker build .
docker images
3、查看
docker images
#或者
docker image ls -f dangling=true#注意这里没有s
4、删除
虚悬镜像已经失去存在价值,可以删除。
docker image prune
0x06 小总结
Dockerfile
BUILD | BOTH | RUN |
---|---|---|
FROM | WORKDIR | CMD |
MAINTAINER | USER | ENV |
COPY | EXPOSE | |
RUN | VOLUME | |
ONBUILD | ENTRYPOINT | |
.dockerignore |
0x07 练习 自定义镜像myubuntu
FROM ubuntu
MAINTAINER sukusec<sukusec@bb.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN apt-get update
RUN apt-get -y install net-tools
RUN apt-get -y install ssh
RUN apt-get -y install vim
RUN apt-get -y install apache2
RUN apt-get -y install iproute2
RUN apt-get -y install inetutils-ping
EXPOSE 80
CMD echo $MYPATH
CMD echo "install ipconfig cmd into ubuntu success--------------ok!"
CMD /bin/bash
ENV #剩下的还没编写完毕,暂时留存