Skip to main content

dcokerfile

Dockerfile构建镜像

首次部署CICD注意事项

//登陆docker仓库 然后赋予相应权限
chmod -R 777 /root/.docker
chmod -R 777 /var/run/docker.sock

一、常见Dockerfile指令

FROM  # 基于哪个基础镜像构建

MAINTAINER # 镜像作者的信息

RUN # 容器镜像构建的时候需要运行的命令

ADD # 在这个镜像中放置的软件压缩包,会自动解压

WORKDIR # 镜像的工作目录

VOLUME # 给镜像指定挂在卷

EXPOSE # 对外暴露的端口

CMD # 容器启动后执行的命令,可以被替代,只有最后一个会生效, (通常用于启动我们的应用)

ENTRYPOINT # 容器启动后执行的命令,可以追加

ONBUILD # 设置镜像的ONBUILD指令

COPY # 和add类似,将压缩包拷贝进镜像中

ENV # 构建时,设置环境变量,如设置mysql的用户名密码

二、编写Centos Dockerfile

2.1、编写Dockerfile
FROM centos

MAINTAINER changwu

ENV MYPATH /usr/local

WORKDIR $MYPATH

RUN yum -y install vim

EXPOSE 80

CMD /bin/bash
2.2、构建
docker build -f dockerfile1 -t 自定义镜像名:[tag] .

docker build -f Dockerfile -t delete:latest .

docker tag 67f2a45061d9 delete:latest

docker tag delete:latest harbor.yottachain.net/yt-common/delete:latest

docker push harbor.yottachain.net/yt-common/delete:latest

ps

自定义的镜像名不能出现大写字母
-t后的自定义镜像名如果没有添加TAG标签的话,默认使用latest
最后的点不能省略

2.3、查看Docker镜像
docker images
ps

Dockerfile中指定From centos,如果本地没有这个镜像的话,他会先去远程仓库拉取镜像。再基于这个镜像构建我们自己的镜像。

2.4、运行镜像
docker run -it 容器ID
ps

上面配置的workdir工作目录,就是一进入容器我们切换进去的目录

三、CMD和ENTRYPOINT

3.1、CMD的作用

ps

CMD指定容器启动后执行的命令,如果我们再编写上面的dockerfile时,没有使用CMD执行/bin/bash,然后build,构建的过程不会出错,但是当我们直接启动容器时会碰到下面的问题

这是图片

ps

没有和容器有任何交互,容器启动后会直接退出
所以我们得在启动参数中添加/bin/bash

这是图片

这是图片

3.2、CMD和ENTRYPOINT的区别

3.2.1、CMD
cmd的三种格式
CMD ["executable","param1","param2"]  # 使用exec执行

CMD command param1 param2 # 在 /bin/sh 中执行

CMD ["param1","param2"] # 给ENTRYPOINT提供默认的参数

在一个Dockerfile中的存在CMD会发生替换,比如下面的Dockerfile

Dockerfile如下
[root@VM-0-15-centos ~]# cat dockerfile2-centos

FROM centos

MAINTAINER changwu:0.6

CMD ["ls","-a"]

启动容器:

这是图片

Dockerfile如下
[root@VM-0-15-centos ~]# cat dockerfile2-centos

FROM centos

MAINTAINER changwu:0.6

CMD ["ls","-a"]

CMD ["ls","-la"]

直接启动容器:发现,只有最后一个CMD执行了。

这是图片

而且手动指定容器启动后执行的命令:可以发现指定的 ls -a 又把它前面的命令替换掉了

这是图片

ps

cmd可以指定容器启动时执行的命令,每个Dockerfile中 只能有一个CMD命令,如果写了多个CMD,只有最后一个会生效, 并且,用户在通过docker run 启动容器时添加的参数 会覆盖原CMD的命令

3.2.2、ENTRYPONIT
entrypoint两种格式
ENTRYPOINT ["executable","param1","param2"]

ENTRYPOINT command param1 param2 (shell中执行)

编写如下的dockerfile,指定启动后的命令是 ls -a

这是图片

直接启动

这是图片

携带启动参数启动:可以看到添加的参数和原来的参数同时生效

这是图片

ps

ENTRYPOINT可以指定容器启动后执行的命令,当指定多个时,同样也只有最后一个命令会生效,并且它不能被docker run中指定的参数所覆盖

(不过可以这样进行覆盖docker run命令的--entrypoint参数可以覆盖ENTRYPOINT)

小结

他们可以指定容器启动后执行的命令,并且当同时存在多个CMD或者多个ENTRYPOINT时,只有最一个会生效

当Dockerfile中同时存在CMD和ENTRYPOINT时.并且CMD又不是为了给ENTRYPOINT提供默认的参数,那么谁在最后谁生效

四、ADD or COPY

ps

ADD 和 COPY看起来很像,但是一般来说都会优先选择COPY,因为它比ADD更透明, COPY仅仅支持将本地的文件复制到容器中,使用ADD支持TAR文件和URL路径(网上文件的下载路径), 命令不能很好的却分 是从本地进行复制还是通过url从远程拉取文件

使用ADD时注意,如果是tar包的话,宿主机上的tar包拷贝到image中会被解压, 但是过URL下载链接的制作镜像时,tar包不会被自动解压, 而且容器中的目录最后需要加上/ 不然启动不起来

五、VOLUME

卷, 这个参数和我们启动容器时使用的docker run -v 宿主机目录:容器目录类似这种挂载券操作, 下面命令中的挂载点其实是容器中的目录,宿主机中的目录会被随机生成

VOLUME mountpoint # 如 VOLUME /data1

举个应用的场景,当我们想将容器中mysql数据库中的数据同步到宿主机的目录下面时,我们可以使用VOLUME,这样配置后会随机在宿主机上创建一个目录存放数据

六、EXPOSE

指定容器和外部进行通信的端口以及协议, EXPOSE 可以指个端口. 默认的协议是tcp协议

EXPOSE <port>

EXPOSE 80/tcp 9999/udp
tip

当我们运行镜像时,使用-p手动指定宿主机和容器的端口映射规则, 使用-P 的话,会自动完成-p的工作, 首先会自动的分配一个宿主机的端口, 然后将宿主机的端口映射到EXPOSE的端口上

七、FROM

tip

Dockerfile中的第一个非注释行,用来指定基础镜像,默认情况下会先尝试从本地获取基础镜像,本地没有的话就会去DockerHub中拉取,常用的书写格式 如下:

这是官方推荐的基础镜像地址 : https://hub.docker.com/_/alpine/

FROM image

FROM image:tag

FORM image:@:digest

八、MAINTAINER

用来指定作者的信息,但是在未来的版本将会被弃用

九、LABEL

现在官方推荐的使用LABEL去描述镜像的各种元数据,比如向下面这样,支持同时设置多个label

# Set one or more individual labels

LABEL com.example.version="0.0.1-beta"

LABEL vendor1="ACME Incorporated"

LABEL vendor2=ZENITH\ Incorporated

LABEL com.example.release-date="2015-02-12"

LABEL com.example.version.is-production=""
warning

注意上面的细节: 带空格的字符串必须加引号或空格必须转义。内部引用字符(")也必须转义

danger

并且官方不建议上面的书写格式(因为每一条指令都会生成一个镜像),而是建议我们向下面这样合并起来label

# Set multiple labels on one line

LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"

或者这样也行

# Set multiple labels at once, using line-continuation characters to break long lines

LABEL vendor=ACME\ Incorporated \

com.example.is-beta= \

com.example.is-production="" \

com.example.version="0.0.1-beta" \

com.example.release-date="2015-02-12"

:::

十、ENV

这是图片

类似于环境变量,在Dockerfile中通过ENV定义的环境变量,之后可以通过$variable_name 或者{variable_name}取出值使用

两种格式
ENV <key> <value> # 一次只能指定一对k-v

ENV <kay>=<value> # 一行指定多个k-v, 如果中间有空格通过\转义,或者使用""标识, 而且\还可以表示换行

十一、ARG

作用和ENV相仿,都可以类型指定环境变量,而且可以在docker build创建镜像的时候,使用 --build-arg=指定参数 来指定参数

十二、Docker 网络模型

docker允许通过外部访问容器或者容器互联的方式提供网络服务, 安装docker deamon时,会自动安装一个docker网卡,叫做Docker0 (通多 ip addr 可以查看,如下图)

这是图片