Dockerfile定制镜像、Dockerfile应用示例、CMD 与 ENTRYPOINT

Dockfile简介

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

  Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
  

Dockerfile 常用指令:

1. 指定容器运行的用户

该用户将作为后续的 RUN 命令执行的用户。这个命令本实验不需要,但在一些需要指定用
户来运行的应用部署时非常关键,比如提供 hadoop 服务的容器通常会使用 hadoop 用户来启
动服务。
命令使用方式,例如使用 shiyanlou 用户来执行后续命令:
USER shiyanlou

2. 指定后续命令的执行目录

由于我们需要运行的是一个静态网站,将启动后的工作目录切换到/var/www/html 目录:WORKDIR /var/www/html

3. 对外连接端口号

由于内部服务会启动 Web 服务,我们需要把对应的 80 端口暴露出来,可以提供给容器间互联使用,可以使用 EXPOSE 命令。
在镜像操作部分增加下面一句:
EXPOSE 80

4. 设置容器主机名

ENV 命令能够对容器内的环境变量进行设置:
ENV HOSTNAME sevrer1.example.com

5. 向镜像中增加文件

向镜像中添加文件有两种命令:COPY 和 ADD。
COPY 命令可以复制本地文件夹到镜像中:
COPY website /var/www/html
ADD 命令支持添加本地的 tar 压缩包到容器中指定目录,压缩包会被自动解压为目录,也
可以自动下载 URL 并拷贝到镜像,例如:
ADD html.tar /var/www
ADD http://www.westos.org/html.tar /var/www
根据实验需求,我们把需要的一个网站放到镜像里,需要把一个 tar 包添加到 apache 的
/var/www 目录下,因此选择使用 ADD 命令:
ADD html.tar /var/www

6. CMD 与 ENTRYPOINT(下面有实验说明)

ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与
CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给
ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,
只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递 给
ENTRYPOINT。在本实验中两种方式都可以选择。

7. 挂载数据卷

将 apache 访问的日志数据存储到宿主机可以访问的数据卷中:
VOLUME [“/var/log/apche2”]

8. 设置容器内的环境变量

使用 ENV 设置一些 apache 启动的环境变量:
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apche2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apche2

以下为Dockfile的3个实例

注:创建镜像过程中如果有错想重新创建,可以删除然后重新创建

删除镜像
[root@foundation10 docker]# docker rmi rhel7:v3
查看是否删除
[root@foundation10 docker]# docker images

1、Dockerfile 编写:Web服务

[root@foundation10 ns]# cd /tmp/docker/
[root@foundation10 docker]# vim Dockerfile
FROM rhel7                         ##指定基础镜像
ENV HOSTNAME server1               ##设定容器主机名
MAINTAINER 573245320@qq.com        ##作者信息
EXPOSE 80                          ##暴露容器端口
COPY dvd.repo /etc/yum.repos.d/dvd.repo   ##复制yum源,不然无法下载
RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all  ##镜像操作命令
VOLUME ["/var/www/html"]           ##挂载数据卷到此目录下
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]  ##镜像启动命令,默认只能启动一条

创建镜像rhel7:v1

[root@foundation10 docker]# docker build -t rhel7:v1 .

查看镜像rhel7:v1

查看本地镜像
[root@foundation10 docker]# docker images rhel7
查看rhel:v1信息
[root@foundation10 docker]# docker history rhel7:v1

这里写图片描述
检验:
运行docker挂载数据卷到新创建的容器上

[root@foundation10 docker]# docker run -d --name vm3 -v /tmp/docker/web:/var/www/html rhel7:v1
查看vm3的IP
[root@foundation10 docker]# docker inspect vm3
浏览器访问172.17.0.3

这里写图片描述

2、Dockerfile 自启动 SSH 服务

先打开另一个Shell连接本机,将要写入Dockerfile的指令执行一遍,将遇到的问题解决,无误后再写入Dockerfile

[root@foundation10 ~]# docker run -it --name vm1 rhel7 bash
bash-4.2# yum install -y openssh-server openssh-clients
bash-4.2# ls -l  /usr/sbin/sshd
执行提示没有钥匙
bash-4.2# /usr/sbin/sshd
创建钥匙
bash-4.2# ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
bash-4.2# ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ""
bash-4.2# ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
bash-4.2# /usr/sbin/sshd
bash-4.2# ssh localhost
修改密码
bash-4.2# echo root:westos | chpasswd   
bash-4.2# ssh localhost
bash-4.2# logout

这里写图片描述
编写Dockerfile:自启动 SSH 服务

[root@foundation10 docker]# mkdir ssh
[root@foundation10 docker]# cp Dockerfile ssh/
[root@foundation10 docker]# cp dvd.repo ssh/
[root@foundation10 docker]# cd ssh/
[root@foundation10 ssh]# vim Dockerfile
FROM rhel7
ENV HOSTNAME server2
MAINTAINER 573245320@qq.com
EXPOSE 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server openssh-clients && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
CMD ["/usr/sbin/sshd", "-D"]

创建镜像rhel7:v2

[root@foundation10 ssh]# docker build -t rhel7:v2 .
查看本地镜像
[root@foundation10 ssh]# docker images rhel7

这里写图片描述
检验

运行docker
[root@foundation10 ssh]# docker run -d --name vm4 rhel7:v2
查看运行的docker
[root@foundation10 ssh]# docker ps
检验
[root@foundation10 ssh]# ssh root@172.17.0.2
-bash-4.2# logout

3、Dockerfile 在镜像里封装2个应用,将以上2个服务结合

运行容器

[root@foundation10 ~]# docker run -d --name vm1 nginx

编辑Dockerfile

将之前本机的Yum源配置发送至vm1的yum源目录下
[root@foundation10 ~]# cd /tmp/docker
[root@foundation10 docker]# docker cp dvd.repo vm1:/etc/yum.repo
编辑Dockerfile
[root@foundation10 docker]# vim Dockerfile 
FROM rhel7
EXPOSE 80 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y httpd openssh-server openssh-clients supervisor && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]

随即编辑yum源文件,应用supervisor-3.1.3-3.el7.noarch.rpm

[root@foundation10 docker]# vim dvd.repo 
[rhel7.3]
name=rhel7.3
baseurl=http://172.25.254.10/rhel7.3
gpgcheck=0

[docker]
name=docker
baseurl=http://172.25.254.10/pub/docker   ##本机存放supervisor-3.1.3-3.el7.noarch.rpm的目录
gpgcheck=0

编辑supervisord.conf 文件

[root@foundation10 docker]# vim supervisord.conf 
[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:httpd]
command=/usr/sbin/httpd

创建镜像、挂载运行

创建镜像rhel7:v3
[root@foundation10 docker]# docker build -t rhel7:v3 .
挂载运行
[root@foundation10 docker]# docker run -d --name vm1 -v /tmp/docker/web:/var/www/html rhel7:v3

检测:

查看IP
[root@foundation10 Desktop]# docker inspect vm1
查看是否有默认发布内容
[root@foundation10 docker]# curl 172.17.0.2
查看是否能连接
[root@foundation10 docker]# ssh -l root 172.17.0.2

这里写图片描述
这里写图片描述

4、RUN CMD ENTRYPOINT的区别

ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与
CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给
ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,
只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递
给ENTRYPOINT。在实验中两种方式都可以选择。

编辑Dockerfile测试

[root@foundation10 ~]# cd /tmp/docker/
[root@foundation10 docker]# mkdir test
[root@foundation10 docker]# cd test/
CMD容器启动时,docker run执行后可被覆盖
[root@foundation10 test]# vim Dockerfile
FROM rhel7
CMD echo "hello world!"
创建镜像
[root@foundation10 test]# docker build -t rhel7:v4 .   
运行镜像查看
[root@foundation10 test]# docker run --rm rhel7:v4
加参数运行查看
[root@foundation10 test]# docker run --rm rhel7:v4 westos
[root@foundation10 test]# docker run --rm rhel7:v4 echo westos
删除镜像
[root@foundation10 test]# docker rmi rhel7:v4

这里写图片描述
以上操作在镜像删除后再重新编辑Dockfile,重新创建rhel7:v4,然后测试,测试完后再执行以上操作,只改变测试内容。以下是其他测试内容和结果:

ENTRYPOINT 容器启动后不可以被 docker run 覆盖
[root@foundation10 test]# vim Dockerfile
FROM rhel7
ENTRYPOINT echo "hello world!"

这里写图片描述

CMDENTRYPOINT结合时 CMDENT 传参
[root@foundation10 test]# vim Dockerfile
FROM rhel7
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]

这里写图片描述
ENTRYPOINT的2种表达方式:

[root@foundation10 test]# vim Dockerfile
FROM rhel7
ENV name westos
ENTRYPOINT echo "hello $name"

这里写图片描述

[root@foundation10 test]# vim Dockerfile
FROM rhel7
ENV name westos
ENTRYPOINT ["/bin/sh","-c","echo $name"]

这里写图片描述

5、数据卷应用

如果-v后面不跟系统目录 容器会帮我们自动分配,挂载数据卷
把静态数据放进镜像 ,镜像挂载到容器使用
如果挂载数据到系统目录,那么数据来源于本地,现在是数据来源于镜像,但是是只读的

查看默认发布文件
[root@foundation10 tmp]# cd /tmp/docker/web/
[root@foundation10 web]# cat index.html 
<h1>www.westos.org</h1>
<h1>www.westos.org</h1>
<h1>www.westos.org</h1>
<h1>www.westos.org</h1>
<h1>www.westos.org</h1>
复制默认发布文件到新建的目录
[root@foundation10 web]# cd ..
[root@foundation10 docker]# cp web/index.html  test/
制作html.tar包
[root@foundation10 docker]# cd test/
[root@foundation10 test]# mkdir nginx
[root@foundation10 test]# mkdir nginx/html
[root@foundation10 test]# cp index.html nginx/html
[root@foundation10 test]# tar cf html.tar nginx/ 
[root@foundation10 test]# ls
Dockerfile  html.tar  nginx  index.html
解压tar包
[root@foundation10 test]# tar tf html.tar 
nginx/
nginx/html/
nginx/html/index.html
编写Dockerfile
[root@foundation10 test]# vim Dockerfile 
FROM rhel7
COPY index.html /usr/share/nginx/html
VOLUME ["/usr/share/nginx/html"]
将前一个实验的rhel7:v4删除
[root@foundation10 test]# docker rmi rhel7:v4
创建镜像
[root@foundation10 test]# docker build -t  rhel7:v4 .
运行数据卷容器
[root@foundation10 test]# docker create --name vol rhel7:v4 bash
[root@foundation10 test]# docker run -d --name vm1 --volumes-from vol nginx
查看vm1的IP
[root@foundation10 test]# docker inspect vm1
                    "IPAddress": "172.17.0.2",
测试
[root@foundation10 test]# curl 172.17.0.2                

这里写图片描述
测试结果与nginx发布内容相同

[root@foundation10 test]# cd /tmp/docker/test/nginx/html/
[root@foundation10 html]# cat index.html 

这里写图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值